PostgreSQL 9.1

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 1957

Documentation PostgreSQL 9.1.

14

The PostgreSQL Global Development Group

Documentation PostgreSQL 9.1.14


The PostgreSQL Global Development Group
Copyright 1996-2014 The PostgreSQL Global Development Group
Legal Notice
PostgreSQL is Copyright (c) 1996-2014 by the PostgreSQL Global Development Group and is distributed under the terms of the license of the University of California below.
Postgres95 is Copyright (c) 1994-5 by the Regents of the University of California.
Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN AS-IS
BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
OR MODIFICATIONS.

Prface ......................................................................................................................................................... xx
1. Dfinition de PostgreSQL ................................................................................................................... xx
2. Bref historique de PostgreSQL ............................................................................................................. xx
3. Conventions ...................................................................................................................................... xxii
4. Pour plus d'informations ....................................................................................................................... xxii
5. Lignes de conduite pour les rapports de bogues ........................................................................................ xxii
I. Tutoriel ...................................................................................................................................................... 1
1. Dmarrage ............................................................................................................................................ 2
1.1. Installation ................................................................................................................................... 2
1.2. Concepts architecturaux de base ....................................................................................................... 2
1.3. Cration d'une base de donnes ........................................................................................................ 2
1.4. Accder une base ........................................................................................................................ 4
2. Le langage SQL .................................................................................................................................... 5
2.1. Introduction ................................................................................................................................. 5
2.2. Concepts ..................................................................................................................................... 5
2.3. Crer une nouvelle table ................................................................................................................. 5
2.4. Remplir une table avec des lignes ..................................................................................................... 6
2.5. Interroger une table ........................................................................................................................ 6
2.6. Jointures entre les tables ................................................................................................................. 8
2.7. Fonctions d'agrgat ........................................................................................................................ 9
2.8. Mises jour ................................................................................................................................ 10
2.9. Suppressions ............................................................................................................................... 11
3. Fonctionnalits avances ........................................................................................................................ 12
3.1. Introduction ................................................................................................................................ 12
3.2. Vues .......................................................................................................................................... 12
3.3. Cls trangres ............................................................................................................................ 12
3.4. Transactions ................................................................................................................................ 13
3.5. Fonctions de fentrage .................................................................................................................. 14
3.6. Hritage ........................................................................................................................................
3.7. Conclusion .................................................................................................................................. 18
II. Langage SQL ............................................................................................................................................ 19
4. Syntaxe SQL ....................................................................................................................................... 20
4.1. Structure lexicale ......................................................................................................................... 20
4.2. Expressions de valeurs .................................................................................................................. 27
4.3. Fonctions appelantes ..................................................................................................................... 36
5. Dfinition des donnes ........................................................................................................................... 38
5.1. Notions fondamentales sur les tables ................................................................................................ 38
5.2. Valeurs par dfaut ........................................................................................................................ 39
5.3. Contraintes ................................................................................................................................. 39
5.4. Colonnes systme ......................................................................................................................... 45
5.5. Modification des tables .................................................................................................................. 46
5.6. Droits ......................................................................................................................................... 48
5.7. Schmas ..................................................................................................................................... 48
5.8. L'hritage ......................................................................................................................................
5.9. Partitionnement ............................................................................................................................ 54
5.10. Donnes distantes ....................................................................................................................... 60
5.11. Autres objets de la base de donnes ................................................................................................ 60
5.12. Gestion des dpendances .............................................................................................................. 60
6. Manipulation de donnes ........................................................................................................................ 62
6.1. Insrer des donnes ....................................................................................................................... 62
6.2. Actualiser les donnes ................................................................................................................... 63
6.3. Supprimer des donnes .................................................................................................................. 63
7. Requtes ............................................................................................................................................. 65
7.1. Aperu ....................................................................................................................................... 65
7.2. Expressions de table ..................................................................................................................... 65
7.3. Listes de slection ........................................................................................................................ 73
7.4. Combiner des requtes .................................................................................................................. 74
7.5. Tri des lignes ............................................................................................................................... 74
7.6. LIMIT et OFFSET ....................................................................................................................... 75
7.7. Listes VALUES ............................................................................................................................ 76
7.8. Requtes WITH (Common Table Expressions) ................................................................................... 76
8. Types de donnes ................................................................................................................................. 81
iii

Documentation PostgreSQL 9.1.14

8.1. Types numriques ........................................................................................................................ 82


8.2. Types montaires ......................................................................................................................... 85
8.3. Types caractre ............................................................................................................................ 86
8.4. Types de donnes binaires .............................................................................................................. 87
8.5. Types date/heure .......................................................................................................................... 89
8.6. Type boolen ............................................................................................................................... 97
8.7. Types numration ....................................................................................................................... 98
8.8. Types gomtriques ...................................................................................................................... 99
8.9. Types adresses rseau ................................................................................................................. 101
8.10. Type chane de bits ................................................................................................................... 102
8.11. Types de recherche plein texte .................................................................................................... 103
8.12. Type UUID ............................................................................................................................. 105
8.13. Type XML .............................................................................................................................. 106
8.14. Tableaux ................................................................................................................................. 107
8.15. Types composites ..................................................................................................................... 114
8.16. Types identifiant d'objet ............................................................................................................. 117
8.17. Pseudo-Types .......................................................................................................................... 118
9. Fonctions et oprateurs ........................................................................................................................ 119
9.1. Oprateurs logiques .................................................................................................................... 119
9.2. Oprateurs de comparaison .......................................................................................................... 119
9.3. Fonctions et oprateurs mathmatiques ........................................................................................... 121
9.4. Fonctions et oprateurs de chanes ................................................................................................. 123
9.5. Fonctions et oprateurs de chanes binaires ...................................................................................... 132
9.6. Fonctions et oprateurs sur les chanes de bits .................................................................................. 134
9.7. Correspondance de motif ............................................................................................................. 134
9.8. Fonctions de formatage des types de donnes .................................................................................. 146
9.9. Fonctions et oprateurs sur date/heure ............................................................................................ 151
9.10. Fonctions de support enum ......................................................................................................... 160
9.11. Fonctions et oprateurs gomtriques ........................................................................................... 161
9.12. Fonctions et oprateurs sur les adresses rseau ............................................................................... 164
9.13. Fonctions et oprateurs de la recherche plein texte .......................................................................... 166
9.14. Fonctions XML ........................................................................................................................ 169
9.15. Fonctions de manipulation de squences ....................................................................................... 178
9.16. Expressions conditionnelles ........................................................................................................ 179
9.17. Fonctions et oprateurs de tableaux .............................................................................................. 181
9.18. Fonctions d'agrgat ................................................................................................................... 183
9.19. Fonctions Window .................................................................................................................... 187
9.20. Expressions de sous-requtes ...................................................................................................... 188
9.21. Comparaisons de lignes et de tableaux .......................................................................................... 191
9.22. Fonctions retournant des ensembles ............................................................................................. 193
9.23. Fonctions d'informations systme ................................................................................................ 195
9.24. Fonctions d'administration systme .............................................................................................. 202
9.25. Fonctions trigger ...................................................................................................................... 212
10. Conversion de types .......................................................................................................................... 214
10.1. Aperu ................................................................................................................................... 214
10.2. Oprateurs ............................................................................................................................... 215
10.3. Fonctions ................................................................................................................................ 217
10.4. Stockage de valeurs ................................................................................................................... 219
10.5. Constructions UNION, CASE et constructions relatives .................................................................... 220
11. Index .............................................................................................................................................. 222
11.1. Introduction ............................................................................................................................. 222
11.2. Types d'index ........................................................................................................................... 222
11.3. Index multicolonnes .................................................................................................................. 224
11.4. Index et ORDER BY .................................................................................................................. 224
11.5. Combiner des index multiples ..................................................................................................... 225
11.6. Index d'unicit ......................................................................................................................... 226
11.7. Index d'expressions ................................................................................................................... 226
11.8. Index partiels ........................................................................................................................... 227
11.9. Classes et familles d'oprateurs ................................................................................................... 228
11.10. Index et collationnements ......................................................................................................... 229
11.11. Examiner l'utilisation des index ................................................................................................. 230
12. Recherche plein texte ......................................................................................................................... 231
12.1. Introduction ............................................................................................................................. 231
iv

Documentation PostgreSQL 9.1.14

12.2. Tables et index ......................................................................................................................... 233


12.3. Contrler la recherche plein texte ................................................................................................. 235
12.4. Fonctionnalits supplmentaires .................................................................................................. 240
12.5. Analyseurs .............................................................................................................................. 244
12.6. Dictionnaires ........................................................................................................................... 246
12.7. Exemple de configuration ........................................................................................................... 252
12.8. Tester et dboguer la recherche plein texte ..................................................................................... 253
12.9. Types d'index GiST et GIN ........................................................................................................ 257
12.10. Support de psql ....................................................................................................................... 258
12.11. Limites ................................................................................................................................. 260
12.12. Migration partir d'une recherche plein texte antrieure 8.3 .......................................................... 260
13. Contrle d'accs simultan .................................................................................................................. 262
13.1. Introduction ............................................................................................................................. 262
13.2. Isolation des transactions ........................................................................................................... 262
13.3. Verrouillage explicite ................................................................................................................ 266
13.4. Vrification de cohrence des donnes au niveau de l'application ....................................................... 270
14. Conseils sur les performances .............................................................................................................. 272
14.1. Utiliser EXPLAIN ................................................................................................................... 272
14.2. Statistiques utilises par le planificateur ........................................................................................ 276
14.3. Contrler le planificateur avec des clauses JOIN explicites .............................................................. 277
14.4. Remplir une base de donnes ...................................................................................................... 278
14.5. Configuration avec une perte accepte .......................................................................................... 281
III. Administration du serveur ......................................................................................................................... 282
15. Procdure d'installation de PostgreSQL du code source ......................................................................... 283
15.1. Version courte ......................................................................................................................... 283
15.2. Prrequis ................................................................................................................................. 283
15.3. Obtenir les sources .................................................................................................................... 284
15.4. Procdure d'installation .............................................................................................................. 285
15.5. Initialisation post-installation ...................................................................................................... 292
15.6. Dmarrer ................................................................................................................................ 293
15.7. Et maintenant ? ........................................................................................................................ 294
15.8. Plateformes supportes .............................................................................................................. 294
15.9. Notes spcifiques des plateformes ............................................................................................. 295
16. Installation partir du code source sur Windows .................................................................................. 303
16.1. Construire avec Visual C++ ou le Platform SDK ...................................................................... 303
16.2. Construire libpq avec Visual C++ ou Borland C++ ................................................................... 306
17. Configuration du serveur et mise en place .............................................................................................. 308
17.1. Compte utilisateur PostgreSQL ................................................................................................ 308
17.2. Crer un groupe de base de donnes ............................................................................................. 308
17.3. Lancer le serveur de bases de donnes .......................................................................................... 309
17.4. Grer les ressources du noyau ..................................................................................................... 311
17.5. Arrter le serveur ...................................................................................................................... 318
17.6. Mise jour d'une instance PostgreSQL ...................................................................................... 318
17.7. Empcher l'usurpation de serveur ................................................................................................. 321
17.8. Options de chiffrement .............................................................................................................. 321
17.9. Connexions tcp/ip scurises avec ssl ........................................................................................... 322
17.10. Connexions tcp/ip scurises avec des tunnels ssh tunnels ............................................................... 323
18. Configuration du serveur .................................................................................................................... 325
18.1. Paramtres de configuration ........................................................................................................ 325
18.2. Emplacement des fichiers ........................................................................................................... 326
18.3. Connexions et authentification .................................................................................................... 327
18.4. Consommation des ressources ..................................................................................................... 330
18.5. Write Ahead Log ...................................................................................................................... 333
18.6. Rplication .............................................................................................................................. 337
18.7. Planification des requtes ........................................................................................................... 339
18.8. Remonter et tracer les erreurs ...................................................................................................... 343
18.9. Statistiques d'excution .............................................................................................................. 350
18.10. Nettoyage (vacuum) automatique .............................................................................................. 351
18.11. Valeurs par dfaut des connexions client ..................................................................................... 352
18.12. Gestion des verrous ................................................................................................................. 357
18.13. Compatibilit de version et de plateforme .................................................................................... 357
18.14. Gestion des erreurs .................................................................................................................. 359
18.15. Options prconfigures ............................................................................................................ 360
v

Documentation PostgreSQL 9.1.14

18.16. Options personnalises ............................................................................................................. 361


18.17. Options pour les dveloppeurs ................................................................................................... 361
18.18. Options courtes ...................................................................................................................... 363
19. Authentification du client ................................................................................................................... 364
19.1. Le fichier pg_hba.conf ......................................................................................................... 364
19.2. Correspondances d'utilisateurs .................................................................................................... 369
19.3. Mthodes d'authentification ........................................................................................................ 370
19.4. Problmes d'authentification ....................................................................................................... 376
20. Rles de la base de donnes ................................................................................................................ 377
20.1. Rles de la base de donnes ........................................................................................................ 377
20.2. Attributs des rles ..................................................................................................................... 377
20.3. Appartenance d'un rle .............................................................................................................. 378
20.4. Scurit des fonctions et dclencheurs (triggers) ............................................................................. 380
21. Administration des bases de donnes .................................................................................................... 381
21.1. Aperu ................................................................................................................................... 381
21.2. Cration d'une base de donnes ................................................................................................... 381
21.3. Bases de donnes modles .......................................................................................................... 382
21.4. Configuration d'une base de donnes ............................................................................................ 383
21.5. Dtruire une base de donnes ...................................................................................................... 383
21.6. Tablespaces ............................................................................................................................. 383
22. Localisation ..................................................................................................................................... 385
22.1. Support des locales ................................................................................................................... 385
22.2. Support des collations ................................................................................................................ 387
22.3. Support des jeux de caractres ..................................................................................................... 389
23. Planifier les tches de maintenance ....................................................................................................... 394
23.1. Nettoyages rguliers .................................................................................................................. 394
23.2. R-indexation rgulire .............................................................................................................. 399
23.3. Maintenance du fichier de traces .................................................................................................. 399
24. Sauvegardes et restaurations ................................................................................................................ 401
24.1. Sauvegarde SQL ...................................................................................................................... 401
24.2. Sauvegarde de niveau systme de fichiers ...................................................................................... 403
24.3. Archivage continu et rcupration d'un instantan (PITR) ................................................................. 404
25. Haute disponibilit, rpartition de charge et rplication ............................................................................. 412
25.1. Comparaison de diffrentes solutions ........................................................................................... 412
25.2. Serveurs de Standby par transfert de journaux ................................................................................ 415
25.3. Bascule (Failover) .................................................................................................................... 419
25.4. Mthode alternative pour le log shipping ....................................................................................... 420
25.5. Hot Standby ............................................................................................................................ 422
26. Configuration de la rcupration .......................................................................................................... 428
26.1. Paramtres de rcupration de l'archive ......................................................................................... 428
26.2. Paramtres de cible de rcupration .............................................................................................. 428
26.3. Paramtres de serveur de Standby ................................................................................................ 429
27. Surveiller l'activit de la base de donnes ............................................................................................... 431
27.1. Outils Unix standard ................................................................................................................. 431
27.2. Le rcuprateur de statistiques ..................................................................................................... 431
27.3. Visualiser les verrous ................................................................................................................ 440
27.4. Traces dynamiques ................................................................................................................... 440
28. Surveiller l'utilisation des disques ......................................................................................................... 449
28.1. Dterminer l'utilisation des disques .............................................................................................. 449
28.2. Panne pour disque satur ............................................................................................................ 450
29. Fiabilit et journaux de transaction ....................................................................................................... 451
29.1. Fiabilit .................................................................................................................................. 451
29.2. Write-Ahead Logging (WAL) ..................................................................................................... 452
29.3. Validation asynchrone (Asynchronous Commit) ............................................................................. 452
29.4. Configuration des journaux de transaction ..................................................................................... 453
29.5. Vue interne des journaux de transaction ........................................................................................ 455
30. Tests de rgression ............................................................................................................................ 457
30.1. Lancer les tests ......................................................................................................................... 457
30.2. valuation des tests ................................................................................................................... 459
30.3. Fichiers de comparaison de variants ............................................................................................. 461
30.4. Examen de la couverture du test .................................................................................................. 462
IV. Interfaces client ...................................................................................................................................... 463
31. libpq - Bibliothque C ........................................................................................................................ 464
vi

Documentation PostgreSQL 9.1.14

31.1. Fonctions de contrle de connexion la base de donnes .................................................................. 464


31.2. Fonctions de statut de connexion ................................................................................................. 470
31.3. Fonctions de commandes d'excution ........................................................................................... 473
31.4. Traitement des commandes asynchrones ....................................................................................... 484
31.5. Annuler des requtes en cours d'excution ..................................................................................... 487
31.6. Interface chemin rapide ........................................................................................................... 487
31.7. Notification asynchrone ............................................................................................................. 488
31.8. Fonctions associes avec la commande COPY ............................................................................... 489
31.9. Fonctions de contrle ................................................................................................................ 492
31.10. Fonctions diverses ................................................................................................................... 493
31.11. Traitement des messages .......................................................................................................... 495
31.12. Systme d'vnements ............................................................................................................. 496
31.13. Variables d'environnement ........................................................................................................ 501
31.14. Fichier de mots de passe ........................................................................................................... 502
31.15. Fichier des connexions de service ............................................................................................... 503
31.16. Recherches LDAP des paramtres de connexion ........................................................................... 503
31.17. Support de SSL ...................................................................................................................... 504
31.18. Comportement des programmes threads ..................................................................................... 507
31.19. Construire des applications avec libpq ......................................................................................... 508
31.20. Exemples de programmes ......................................................................................................... 508
32. Objets larges .................................................................................................................................... 516
32.1. Introduction ............................................................................................................................. 516
32.2. Fonctionnalits d'implmentation ................................................................................................. 516
32.3. Interfaces client ........................................................................................................................ 516
32.4. Fonctions du ct serveur ........................................................................................................... 518
32.5. Programme d'exemple ............................................................................................................... 519
33. ECPG SQL embarqu en C ................................................................................................................. 524
33.1. Le Concept .............................................................................................................................. 524
33.2. Grer les Connexions la Base de Donnes ................................................................................... 524
33.3. Excuter des Commandes SQL ................................................................................................... 526
33.4. Utiliser des Variables Htes ........................................................................................................ 528
33.5. SQL Dynamique ...................................................................................................................... 540
33.6. Librairie pgtypes ...................................................................................................................... 541
33.7. Utiliser les Zones de Descripteur ................................................................................................. 552
33.8. Gestion des Erreurs ................................................................................................................... 562
33.9. Directives de Prprocesseur ........................................................................................................ 568
33.10. Traiter des Programmes en SQL Embarqu .................................................................................. 569
33.11. Fonctions de la Librairie ........................................................................................................... 570
33.12. Large Objects ......................................................................................................................... 570
33.13. Applications C++ .................................................................................................................... 572
33.14. Commandes SQL Embarques .................................................................................................. 575
33.15. Mode de Compatibilit Informix ............................................................................................. 593
33.16. Fonctionnement Interne ............................................................................................................ 604
34. Schma d'information ........................................................................................................................ 607
34.1. Le schma ............................................................................................................................... 607
34.2. Types de donnes ..................................................................................................................... 607
34.3. information_schema_catalog_name ............................................................................... 608
34.4. administrable_role_authorizations ........................................................................... 608
34.5. applicable_roles ............................................................................................................. 608
34.6. attributes ......................................................................................................................... 608
34.7. character_sets ................................................................................................................. 610
34.8. check_constraint_routine_usage ................................................................................. 611
34.9. check_constraints ........................................................................................................... 612
34.10. collations ........................................................................................................................ 612
34.11. collation_character_set_applicability .................................................................. 612
34.12. column_domain_usage ...................................................................................................... 613
34.13. column_privileges .......................................................................................................... 613
34.14. column_udt_usage ............................................................................................................ 614
34.15. columns .............................................................................................................................. 614
34.16. constraint_column_usage .............................................................................................. 617
34.17. constraint_table_usage ................................................................................................ 617
34.18. data_type_privileges .................................................................................................... 617
34.19. domain_constraints ........................................................................................................ 618
vii

Documentation PostgreSQL 9.1.14

34.20. domain_udt_usage ............................................................................................................ 618


34.21. domains .............................................................................................................................. 619
34.22. element_types .................................................................................................................. 620
34.23. enabled_roles .................................................................................................................. 622
34.24. foreign_data_wrapper_options .................................................................................... 622
34.25. foreign_data_wrappers .................................................................................................. 622
34.26. foreign_server_options ................................................................................................ 623
34.27. foreign_servers .............................................................................................................. 623
34.28. foreign_table_options .................................................................................................. 623
34.29. foreign_tables ................................................................................................................ 624
34.30. key_column_usage ............................................................................................................ 624
34.31. parameters ........................................................................................................................ 625
34.32. referential_constraints .............................................................................................. 626
34.33. role_column_grants ........................................................................................................ 627
34.34. role_routine_grants ...................................................................................................... 627
34.35. role_table_grants .......................................................................................................... 628
34.36. role_usage_grants .......................................................................................................... 628
34.37. routine_privileges ........................................................................................................ 628
34.38. routines ............................................................................................................................ 629
34.39. schemata ............................................................................................................................ 632
34.40. sequences .......................................................................................................................... 633
34.41. sql_features .................................................................................................................... 634
34.42. sql_implementation_info .............................................................................................. 634
34.43. sql_languages .................................................................................................................. 634
34.44. sql_packages .................................................................................................................... 635
34.45. sql_parts .......................................................................................................................... 635
34.46. sql_sizing ........................................................................................................................ 636
34.47. sql_sizing_profiles ...................................................................................................... 636
34.48. table_constraints .......................................................................................................... 636
34.49. table_privileges ............................................................................................................ 637
34.50. tables ................................................................................................................................ 637
34.51. triggered_update_columns ............................................................................................ 638
34.52. triggers ............................................................................................................................ 638
34.53. usage_privileges ............................................................................................................ 640
34.54. user_mapping_options .................................................................................................... 640
34.55. user_mappings .................................................................................................................. 641
34.56. view_column_usage .......................................................................................................... 641
34.57. view_routine_usage ........................................................................................................ 641
34.58. view_table_usage ............................................................................................................ 642
34.59. views .................................................................................................................................. 642
V. Programmation serveur ............................................................................................................................. 644
35. tendre SQL .................................................................................................................................... 645
35.1. L'extensibilit .......................................................................................................................... 645
35.2. Le systme des types de PostgreSQL ......................................................................................... 645
35.3. Fonctions utilisateur .................................................................................................................. 646
35.4. Fonctions en langage de requtes (SQL) ........................................................................................ 647
35.5. Surcharge des fonctions ............................................................................................................. 657
35.6. Catgories de volatilit des fonctions ............................................................................................ 657
35.7. Fonctions en langage de procdures ............................................................................................. 658
35.8. Fonctions internes ..................................................................................................................... 658
35.9. Fonctions en langage C .............................................................................................................. 659
35.10. Agrgats utilisateur ................................................................................................................. 677
35.11. Types utilisateur ..................................................................................................................... 679
35.12. Oprateurs dfinis par l'utilisateur .............................................................................................. 681
35.13. Informations sur l'optimisation d'un oprateur .............................................................................. 682
35.14. Interfacer des extensions d'index ................................................................................................ 685
35.15. Empaqueter des objets dans une extension ................................................................................... 694
35.16. Outils de construction d'extension .............................................................................................. 699
36. Dclencheurs (triggers) ...................................................................................................................... 701
36.1. Aperu du comportement des dclencheurs .................................................................................... 701
36.2. Visibilit des modifications des donnes ....................................................................................... 702
36.3. crire des fonctions dclencheurs en C ......................................................................................... 703
36.4. Un exemple complet de trigger .................................................................................................... 705
viii

Documentation PostgreSQL 9.1.14

37. Systme de rgles .............................................................................................................................. 708


37.1. Arbre de requtes ..................................................................................................................... 708
37.2. Vues et systme de rgles ........................................................................................................... 709
37.3. Rgles sur insert, update et delete .............................................................................................. 715
37.4. Rgles et droits ........................................................................................................................ 723
37.5. Rgles et statut de commande ..................................................................................................... 724
37.6. Rgles contre dclencheurs ......................................................................................................... 724
38. Langages de procdures ..................................................................................................................... 727
38.1. Installation des langages de procdures ......................................................................................... 727
39. PL/pgSQL - Langage de procdures SQL .............................................................................................. 729
39.1. Aperu ................................................................................................................................... 729
39.2. Structure de PL/pgSQL .............................................................................................................. 730
39.3. Dclarations ............................................................................................................................ 731
39.4. Expressions ............................................................................................................................. 735
39.5. Instructions de base ................................................................................................................... 736
39.6. Structures de contrle ................................................................................................................ 741
39.7. Curseurs ................................................................................................................................. 750
39.8. Erreurs et messages ................................................................................................................... 755
39.9. Procdures trigger ..................................................................................................................... 756
39.10. Les dessous de PL/pgSQL ........................................................................................................ 761
39.11. Astuces pour dvelopper en PL/pgSQL ....................................................................................... 764
39.12. Portage d'Oracle PL/SQL ...................................................................................................... 766
40. PL/Tcl - Langage de procdures Tcl ..................................................................................................... 774
40.1. Aperu ................................................................................................................................... 774
40.2. Fonctions et arguments PL/Tcl .................................................................................................... 774
40.3. Valeurs des donnes avec PL/Tcl ................................................................................................. 775
40.4. Donnes globales avec PL/Tcl ..................................................................................................... 775
40.5. Accs la base de donnes depuis PL/Tcl ..................................................................................... 776
40.6. Procdures pour dclencheurs en PL/Tcl ....................................................................................... 777
40.7. Les modules et la commande unknown ....................................................................................... 779
40.8. Noms de procdure Tcl .............................................................................................................. 779
41. PL/Perl - Langage de procdures Perl .................................................................................................... 780
41.1. Fonctions et arguments PL/Perl ................................................................................................... 780
41.2. Valeurs en PL/Perl .................................................................................................................... 783
41.3. Fonction incluses ...................................................................................................................... 783
41.4. Valeurs globales dans PL/Perl ..................................................................................................... 787
41.5. Niveaux de confiance de PL/Perl ................................................................................................. 787
41.6. Dclencheurs PL/Perl ................................................................................................................ 788
41.7. PL/Perl sous le capot ................................................................................................................. 789
42. PL/Python - Langage de procdures Python ........................................................................................... 791
42.1. Python 2 et Python 3 ................................................................................................................. 791
42.2. Fonctions PL/Python ................................................................................................................. 792
42.3. Valeur des donnes avec PL/Python ............................................................................................. 793
42.4. Sharing Data ............................................................................................................................ 797
42.5. Blocs de code anonymes ............................................................................................................ 797
42.6. Fonctions de dclencheurs .......................................................................................................... 797
42.7. Accs la base de donnes ......................................................................................................... 798
42.8. Sous-transactions explicites ........................................................................................................ 799
42.9. Fonctions outils ........................................................................................................................ 800
42.10. Variables d'environnement ........................................................................................................ 801
43. Interface de programmation serveur ...................................................................................................... 802
43.1. Fonctions d'interface ................................................................................................................. 802
43.2. Fonctions de support d'interface .................................................................................................. 830
43.3. Gestion de la mmoire ............................................................................................................... 838
43.4. Visibilit des modifications de donnes ......................................................................................... 847
43.5. Exemples ................................................................................................................................ 847
VI. Rfrence .............................................................................................................................................. 850
I. Commandes SQL ................................................................................................................................ 851
ABORT ......................................................................................................................................... 852
ALTER AGGREGATE ..................................................................................................................... 853
ALTER COLLATION ...................................................................................................................... 854
ALTER CONVERSION .................................................................................................................... 855
ALTER DATABASE ....................................................................................................................... 856
ix

Documentation PostgreSQL 9.1.14

ALTER DEFAULT PRIVILEGES ...................................................................................................... 858


ALTER DOMAIN ........................................................................................................................... 860
ALTER EXTENSION ...................................................................................................................... 862
ALTER FOREIGN DATA WRAPPER ................................................................................................ 865
ALTER FOREIGN TABLE ............................................................................................................... 867
ALTER FUNCTION ........................................................................................................................ 869
ALTER GROUP .............................................................................................................................. 871
ALTER INDEX ............................................................................................................................... 872
ALTER LANGUAGE ....................................................................................................................... 874
ALTER LARGE OBJECT ................................................................................................................. 875
ALTER OPERATOR ........................................................................................................................ 876
ALTER OPERATOR CLASS ............................................................................................................ 877
ALTER OPERATOR FAMILY .......................................................................................................... 878
ALTER ROLE ................................................................................................................................ 881
ALTER SCHEMA ........................................................................................................................... 884
ALTER SEQUENCE ........................................................................................................................ 885
ALTER SERVER ............................................................................................................................ 887
ALTER TABLE .............................................................................................................................. 888
ALTER TABLESPACE .................................................................................................................... 896
ALTER TEXT SEARCH CONFIGURATION ...................................................................................... 897
ALTER TEXT SEARCH DICTIONARY ............................................................................................. 899
ALTER TEXT SEARCH PARSER ..................................................................................................... 901
ALTER TEXT SEARCH TEMPLATE ................................................................................................ 902
ALTER TRIGGER ........................................................................................................................... 903
ALTER TYPE ................................................................................................................................. 904
ALTER USER ................................................................................................................................. 907
ALTER USER MAPPING ................................................................................................................. 908
ALTER VIEW ................................................................................................................................ 909
ANALYZE ..................................................................................................................................... 910
BEGIN .......................................................................................................................................... 912
CHECKPOINT ................................................................................................................................ 914
CLOSE .......................................................................................................................................... 915
CLUSTER ...................................................................................................................................... 916
COMMENT .................................................................................................................................... 918
COMMIT ....................................................................................................................................... 921
COMMIT PREPARED ..................................................................................................................... 922
COPY ............................................................................................................................................ 923
CREATE AGGREGATE ................................................................................................................... 930
CREATE CAST .............................................................................................................................. 933
CREATE COLLATION .................................................................................................................... 937
CREATE CONVERSION ................................................................................................................. 939
CREATE DATABASE ..................................................................................................................... 941
CREATE DOMAIN ......................................................................................................................... 943
CREATE EXTENSION .................................................................................................................... 945
CREATE FOREIGN DATA WRAPPER .............................................................................................. 947
CREATE FOREIGN TABLE ............................................................................................................. 949
CREATE FUNCTION ...................................................................................................................... 951
CREATE GROUP ............................................................................................................................ 957
CREATE INDEX ............................................................................................................................. 958
CREATE LANGUAGE .................................................................................................................... 963
CREATE OPERATOR ..................................................................................................................... 966
CREATE OPERATOR CLASS .......................................................................................................... 968
CREATE OPERATOR FAMILY ........................................................................................................ 971
CREATE ROLE .............................................................................................................................. 972
CREATE RULE .............................................................................................................................. 975
CREATE SCHEMA ......................................................................................................................... 977
CREATE SEQUENCE ..................................................................................................................... 979
CREATE SERVER .......................................................................................................................... 982
CREATE TABLE ............................................................................................................................ 984
CREATE TABLE AS ....................................................................................................................... 995
CREATE TABLESPACE .................................................................................................................. 997
CREATE TEXT SEARCH CONFIGURATION .................................................................................... 998
CREATE TEXT SEARCH DICTIONARY ........................................................................................... 999
x

Documentation PostgreSQL 9.1.14

CREATE TEXT SEARCH PARSER .................................................................................................


CREATE TEXT SEARCH TEMPLATE ............................................................................................
CREATE TRIGGER ......................................................................................................................
CREATE TYPE .............................................................................................................................
CREATE USER ............................................................................................................................
CREATE USER MAPPING .............................................................................................................
CREATE VIEW ............................................................................................................................
DEALLOCATE .............................................................................................................................
DECLARE ...................................................................................................................................
DELETE ......................................................................................................................................
DISCARD ....................................................................................................................................
DO ..............................................................................................................................................
DROP AGGREGATE .....................................................................................................................
DROP CAST ................................................................................................................................
DROP COLLATION ......................................................................................................................
DROP CONVERSION ...................................................................................................................
DROP DATABASE .......................................................................................................................
DROP DOMAIN ...........................................................................................................................
DROP EXTENSION ......................................................................................................................
DROP FOREIGN DATA WRAPPER ................................................................................................
DROP FOREIGN TABLE ...............................................................................................................
DROP FUNCTION ........................................................................................................................
DROP GROUP ..............................................................................................................................
DROP INDEX ...............................................................................................................................
DROP LANGUAGE ......................................................................................................................
DROP OPERATOR .......................................................................................................................
DROP OPERATOR CLASS ............................................................................................................
DROP OPERATOR FAMILY ..........................................................................................................
DROP OWNED .............................................................................................................................
DROP ROLE ................................................................................................................................
DROP RULE ................................................................................................................................
DROP SCHEMA ...........................................................................................................................
DROP SEQUENCE ........................................................................................................................
DROP SERVER ............................................................................................................................
DROP TABLE ..............................................................................................................................
DROP TABLESPACE ....................................................................................................................
DROP TEXT SEARCH CONFIGURATION ......................................................................................
DROP TEXT SEARCH DICTIONARY .............................................................................................
DROP TEXT SEARCH PARSER .....................................................................................................
DROP TEXT SEARCH TEMPLATE ................................................................................................
DROP TRIGGER ...........................................................................................................................
DROP TYPE .................................................................................................................................
DROP USER ................................................................................................................................
DROP USER MAPPING .................................................................................................................
DROP VIEW ................................................................................................................................
END ............................................................................................................................................
EXECUTE ...................................................................................................................................
EXPLAIN ....................................................................................................................................
FETCH ........................................................................................................................................
GRANT .......................................................................................................................................
INSERT .......................................................................................................................................
LISTEN .......................................................................................................................................
LOAD .........................................................................................................................................
LOCK ..........................................................................................................................................
MOVE .........................................................................................................................................
NOTIFY ......................................................................................................................................
PREPARE ....................................................................................................................................
PREPARE TRANSACTION ............................................................................................................
REASSIGN OWNED .....................................................................................................................
REINDEX ....................................................................................................................................
RELEASE SAVEPOINT .................................................................................................................
RESET ........................................................................................................................................
REVOKE .....................................................................................................................................
xi

1000
1001
1002
1006
1012
1013
1014
1016
1017
1020
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1063
1066
1071
1074
1075
1076
1078
1080
1082
1084
1086
1087
1089
1090
1091

Documentation PostgreSQL 9.1.14

ROLLBACK .................................................................................................................................
ROLLBACK PREPARED ...............................................................................................................
ROLLBACK TO SAVEPOINT ........................................................................................................
SAVEPOINT ................................................................................................................................
SECURITY LABEL .......................................................................................................................
SELECT ......................................................................................................................................
SELECT INTO ..............................................................................................................................
SET .............................................................................................................................................
SET CONSTRAINTS .....................................................................................................................
SET ROLE ...................................................................................................................................
SET SESSION AUTHORIZATION ..................................................................................................
SET TRANSACTION ....................................................................................................................
SHOW .........................................................................................................................................
START TRANSACTION ................................................................................................................
TRUNCATE .................................................................................................................................
UNLISTEN ..................................................................................................................................
UPDATE ......................................................................................................................................
VACUUM ....................................................................................................................................
VALUES ......................................................................................................................................
II. Applications client de PostgreSQL ......................................................................................................
clusterdb ......................................................................................................................................
createdb .......................................................................................................................................
createlang .....................................................................................................................................
createuser .....................................................................................................................................
dropdb .........................................................................................................................................
droplang .......................................................................................................................................
dropuser .......................................................................................................................................
ecpg ............................................................................................................................................
pg_basebackup ..............................................................................................................................
pg_config .....................................................................................................................................
pg_dump ......................................................................................................................................
pg_dumpall ...................................................................................................................................
pg_restore .....................................................................................................................................
psql .............................................................................................................................................
reindexdb .....................................................................................................................................
vacuumdb .....................................................................................................................................
III. Applications relatives au serveur PostgreSQL .......................................................................................
initdb ...........................................................................................................................................
pg_controldata ...............................................................................................................................
pg_ctl ..........................................................................................................................................
pg_resetxlog .................................................................................................................................
postgres ........................................................................................................................................
postmaster ....................................................................................................................................
VII. Internes ..............................................................................................................................................
44. Prsentation des mcanismes internes de PostgreSQL ............................................................................
44.1. Chemin d'une requte ..............................................................................................................
44.2. tablissement des connexions ...................................................................................................
44.3. tape d'analyse ......................................................................................................................
44.4. Systme de rgles de PostgreSQL ...........................................................................................
44.5. Planificateur/Optimiseur ..........................................................................................................
44.6. Excuteur ..............................................................................................................................
45. Catalogues systme .........................................................................................................................
45.1. Aperu .................................................................................................................................
45.2. pg_aggregate .........................................................................................................................
45.3. pg_am ..................................................................................................................................
45.4. pg_amop ...............................................................................................................................
45.5. pg_amproc ............................................................................................................................
45.6. pg_attrdef .............................................................................................................................
45.7. pg_attribute ...........................................................................................................................
45.8. pg_authid ..............................................................................................................................
45.9. pg_auth_members ...................................................................................................................
45.10. pg_cast ...............................................................................................................................
45.11. pg_class ..............................................................................................................................
xii

1094
1095
1096
1098
1099
1101
1115
1117
1120
1121
1123
1124
1126
1128
1129
1131
1132
1135
1138
1140
1141
1143
1145
1147
1150
1152
1154
1156
1158
1161
1163
1170
1174
1179
1200
1202
1204
1205
1208
1209
1213
1215
1220
1221
1222
1222
1222
1223
1223
1224
1225
1226
1226
1227
1228
1229
1229
1230
1230
1232
1233
1233
1234

Documentation PostgreSQL 9.1.14

45.12. pg_constraint ....................................................................................................................... 1235


45.13. pg_collation ......................................................................................................................... 1237
45.14. pg_conversion ...................................................................................................................... 1237
45.15. pg_database ......................................................................................................................... 1238
45.16. pg_db_role_setting ................................................................................................................ 1239
45.17. pg_default_acl ...................................................................................................................... 1239
45.18. pg_depend ........................................................................................................................... 1239
45.19. pg_description ...................................................................................................................... 1240
45.20. pg_enum ............................................................................................................................. 1241
45.21. pg_extension ........................................................................................................................ 1241
45.22. pg_foreign_data_wrapper ....................................................................................................... 1242
45.23. pg_foreign_server ................................................................................................................. 1242
45.24. pg_foreign_table ................................................................................................................... 1243
45.25. pg_index ............................................................................................................................. 1243
45.26. pg_inherits ..................................................................................................................................
45.27. pg_language ........................................................................................................................ 1245
45.28. pg_largeobject ...................................................................................................................... 1245
45.29. pg_largeobject_metadata ........................................................................................................ 1246
45.30. pg_namespace ...................................................................................................................... 1246
45.31. pg_opclass ........................................................................................................................... 1246
45.32. pg_operator ......................................................................................................................... 1247
45.33. pg_opfamily ........................................................................................................................ 1247
45.34. pg_pltemplate ...................................................................................................................... 1248
45.35. pg_proc ............................................................................................................................... 1248
45.36. pg_rewrite ........................................................................................................................... 1250
45.37. pg_seclabel .......................................................................................................................... 1251
45.38. pg_shdepend ........................................................................................................................ 1251
45.39. pg_shdescription ................................................................................................................... 1252
45.40. pg_statistic .......................................................................................................................... 1252
45.41. pg_tablespace ....................................................................................................................... 1254
45.42. pg_trigger ............................................................................................................................ 1254
45.43. pg_ts_config ........................................................................................................................ 1255
45.44. pg_ts_config_map ................................................................................................................. 1255
45.45. pg_ts_dict ............................................................................................................................ 1256
45.46. pg_ts_parser ........................................................................................................................ 1256
45.47. pg_ts_template ..................................................................................................................... 1256
45.48. pg_type ............................................................................................................................... 1257
45.49. pg_user_mapping .................................................................................................................. 1260
45.50. Vues systme ....................................................................................................................... 1261
45.51. pg_available_extensions ......................................................................................................... 1262
45.52. pg_available_extension_versions ............................................................................................. 1262
45.53. pg_cursors ........................................................................................................................... 1262
45.54. pg_group ............................................................................................................................. 1263
45.55. pg_indexes .......................................................................................................................... 1263
45.56. pg_locks ............................................................................................................................. 1264
45.57. pg_prepared_statements ......................................................................................................... 1265
45.58. pg_prepared_xacts ................................................................................................................ 1266
45.59. pg_roles .............................................................................................................................. 1267
45.60. pg_rules .............................................................................................................................. 1267
45.61. pg_seclabels ........................................................................................................................ 1268
45.62. pg_settings .......................................................................................................................... 1268
45.63. pg_shadow .......................................................................................................................... 1270
45.64. pg_stats ............................................................................................................................... 1270
45.65. pg_tables ............................................................................................................................. 1271
45.66. pg_timezone_abbrevs ............................................................................................................ 1271
45.67. pg_timezone_names .............................................................................................................. 1272
45.68. pg_user ............................................................................................................................... 1272
45.69. pg_user_mappings ................................................................................................................ 1272
45.70. pg_views ............................................................................................................................. 1273
46. Protocole client/serveur .................................................................................................................... 1274
46.1. Aperu ................................................................................................................................. 1274
46.2. Flux de messages .................................................................................................................... 1275
46.3. Types de donnes des message .................................................................................................. 1283
xiii

Documentation PostgreSQL 9.1.14

46.4. Protocole de rplication en continu .............................................................................................


46.5. Formats de message ................................................................................................................
46.6. Champs des messages d'erreur et d'avertissement ..........................................................................
46.7. Rsum des modifications depuis le protocole 2.0 .........................................................................
47. Conventions de codage pour PostgreSQL ............................................................................................
47.1. Formatage .............................................................................................................................
47.2. Reporter les erreurs dans le serveur ............................................................................................
47.3. Guide de style des messages d'erreurs .........................................................................................
48. Support natif des langues ..................................................................................................................
48.1. Pour le traducteur ...................................................................................................................
48.2. Pour le dveloppeur ................................................................................................................
49. crire un gestionnaire de langage procdural ........................................................................................
50. crire un wrapper de donnes distantes ...............................................................................................
50.1. Fonctions d'un wrapper de donnes distantes ................................................................................
50.2. Routines callback des wrappers de donnes distantes .....................................................................
51. Optimiseur gntique de requtes (Genetic Query Optimizer) ..................................................................
51.1. Grer les requtes, un problme d'optimisation complexe ...............................................................
51.2. Algorithmes gntiques ...........................................................................................................
51.3. Optimisation gntique des requtes (GEQO) dans PostgreSQL ......................................................
51.4. Lectures supplmentaires .........................................................................................................
52. Dfinition de l'interface des mthodes d'accs aux index .........................................................................
52.1. Entres du catalogue pour les index ............................................................................................
52.2. Fonctions de la mthode d'accs aux index ..................................................................................
52.3. Parcours d'index .....................................................................................................................
52.4. Considrations sur le verrouillage d'index ....................................................................................
52.5. Vrification de l'unicit de l'index ..............................................................................................
52.6. Fonctions d'estimation des cots d'index .....................................................................................
53. Index GiST ....................................................................................................................................
53.1. Introduction ...........................................................................................................................
53.2. Extensibilit ..........................................................................................................................
53.3. Implantation ..........................................................................................................................
53.4. Exemples ..............................................................................................................................
54. Index GIN .....................................................................................................................................
54.1. Introduction ...........................................................................................................................
54.2. Extensibilit ..........................................................................................................................
54.3. Implantation ..........................................................................................................................
54.4. Conseils et astuces GIN ...........................................................................................................
54.5. Limitations ............................................................................................................................
54.6. Exemples ..............................................................................................................................
55. Stockage physique de la base de donnes .............................................................................................
55.1. Emplacement des fichiers de la base de donnes ...........................................................................
55.2. TOAST ................................................................................................................................
55.3. Carte des espaces libres ...........................................................................................................
55.4. Carte de visibilit ...................................................................................................................
55.5. The Initialization Fork .............................................................................................................
55.6. Emplacement des pages de la base de donnes .............................................................................
56. Interface du moteur, BKI ..................................................................................................................
56.1. Format des fichiers BKI ...........................................................................................................
56.2. Commandes BKI ....................................................................................................................
56.3. Structure du fichier BKI de bootstrap ....................................................................................
56.4. Exemple ...............................................................................................................................
57. Comment le planificateur utilise les statistiques ....................................................................................
57.1. Exemples d'estimation des lignes ...............................................................................................
VIII. Annexes ............................................................................................................................................
A. Codes d'erreurs de PostgreSQL ........................................................................................................
B. Support de date/heure ........................................................................................................................
B.1. Interprtation des Date/Heure saisies ...........................................................................................
B.2. Mots cls Date/Heure ...............................................................................................................
B.3. Fichiers de configuration date/heure ............................................................................................
B.4. Histoire des units ...................................................................................................................
C. Mots-cl SQL ..................................................................................................................................
D. Conformit SQL ..............................................................................................................................
D.1. Fonctionnalits supportes ........................................................................................................
xiv

1284
1286
1295
1296
1298
1298
1298
1300
1304
1304
1306
1309
1312
1312
1312
1314
1314
1314
1315
1316
1317
1317
1318
1321
1322
1323
1324
1326
1326
1326
1326
1332
1333
1333
1333
1335
1335
1336
1336
1337
1337
1338
1340
1340
1340
1340
1343
1343
1343
1344
1344
1345
1345
1350
1351
1358
1358
1359
1360
1360
1362
1382
1383

Documentation PostgreSQL 9.1.14

D.2. Fonctionnalits non supportes ...................................................................................................


E. Notes de version ...............................................................................................................................
E.1. Release 9.1.14 .........................................................................................................................
E.2. Release 9.1.13 .........................................................................................................................
E.3. Release 9.1.12 .........................................................................................................................
E.4. Release 9.1.11 .........................................................................................................................
E.5. Release 9.1.10 .........................................................................................................................
E.6. Release 9.1.9 ...........................................................................................................................
E.7. Release 9.1.8 ...........................................................................................................................
E.8. Release 9.1.7 ...........................................................................................................................
E.9. Release 9.1.6 ...........................................................................................................................
E.10. Release 9.1.5 .........................................................................................................................
E.11. Release 9.1.4 .........................................................................................................................
E.12. Release 9.1.3 .........................................................................................................................
E.13. Release 9.1.2 .........................................................................................................................
E.14. Release 9.1.1 .........................................................................................................................
E.15. Release 9.1 ...........................................................................................................................
E.16. Release 9.0.18 .......................................................................................................................
E.17. Release 9.0.17 .......................................................................................................................
E.18. Release 9.0.16 .......................................................................................................................
E.19. Release 9.0.15 .......................................................................................................................
E.20. Release 9.0.14 .......................................................................................................................
E.21. Release 9.0.13 .......................................................................................................................
E.22. Release 9.0.12 .......................................................................................................................
E.23. Release 9.0.11 .......................................................................................................................
E.24. Release 9.0.10 .......................................................................................................................
E.25. Release 9.0.9 .........................................................................................................................
E.26. Release 9.0.8 .........................................................................................................................
E.27. Release 9.0.7 .........................................................................................................................
E.28. Release 9.0.6 .........................................................................................................................
E.29. Release 9.0.5 .........................................................................................................................
E.30. Release 9.0.4 .........................................................................................................................
E.31. Release 9.0.3 .........................................................................................................................
E.32. Release 9.0.2 .........................................................................................................................
E.33. Release 9.0.1 .........................................................................................................................
E.34. Release 9.0 ...........................................................................................................................
E.35. Release 8.4.22 .......................................................................................................................
E.36. Release 8.4.21 .......................................................................................................................
E.37. Release 8.4.20 .......................................................................................................................
E.38. Release 8.4.19 .......................................................................................................................
E.39. Release 8.4.18 .......................................................................................................................
E.40. Release 8.4.17 .......................................................................................................................
E.41. Release 8.4.16 .......................................................................................................................
E.42. Release 8.4.15 .......................................................................................................................
E.43. Release 8.4.14 .......................................................................................................................
E.44. Release 8.4.13 .......................................................................................................................
E.45. Release 8.4.12 .......................................................................................................................
E.46. Release 8.4.11 .......................................................................................................................
E.47. Release 8.4.10 .......................................................................................................................
E.48. Release 8.4.9 .........................................................................................................................
E.49. Release 8.4.8 .........................................................................................................................
E.50. Release 8.4.7 .........................................................................................................................
E.51. Release 8.4.6 .........................................................................................................................
E.52. Release 8.4.5 .........................................................................................................................
E.53. Release 8.4.4 .........................................................................................................................
E.54. Release 8.4.3 .........................................................................................................................
E.55. Release 8.4.2 .........................................................................................................................
E.56. Release 8.4.1 .........................................................................................................................
E.57. Release 8.4 ...........................................................................................................................
E.58. Release 8.3.23 .......................................................................................................................
E.59. Release 8.3.22 .......................................................................................................................
E.60. Release 8.3.21 .......................................................................................................................
E.61. Release 8.3.20 .......................................................................................................................
xv

1391
1400
1400
1402
1403
1406
1407
1408
1410
1412
1414
1415
1417
1420
1423
1426
1426
1440
1441
1442
1445
1446
1447
1449
1450
1452
1453
1455
1456
1459
1461
1464
1466
1466
1469
1470
1485
1487
1488
1490
1491
1492
1493
1494
1496
1496
1498
1499
1501
1503
1505
1506
1507
1509
1511
1513
1515
1518
1519
1534
1535
1537
1537

Documentation PostgreSQL 9.1.14

E.62. Release 8.3.19 .......................................................................................................................


E.63. Release 8.3.18 .......................................................................................................................
E.64. Release 8.3.17 .......................................................................................................................
E.65. Release 8.3.16 .......................................................................................................................
E.66. Release 8.3.15 .......................................................................................................................
E.67. Release 8.3.14 .......................................................................................................................
E.68. Release 8.3.13 .......................................................................................................................
E.69. Release 8.3.12 .......................................................................................................................
E.70. Release 8.3.11 .......................................................................................................................
E.71. Release 8.3.10 .......................................................................................................................
E.72. Release 8.3.9 .........................................................................................................................
E.73. Release 8.3.8 .........................................................................................................................
E.74. Release 8.3.7 .........................................................................................................................
E.75. Release 8.3.6 .........................................................................................................................
E.76. Release 8.3.5 .........................................................................................................................
E.77. Release 8.3.4 .........................................................................................................................
E.78. Release 8.3.3 .........................................................................................................................
E.79. Release 8.3.2 .........................................................................................................................
E.80. Release 8.3.1 .........................................................................................................................
E.81. Release 8.3 ...........................................................................................................................
E.82. Release 8.2.23 .......................................................................................................................
E.83. Release 8.2.22 .......................................................................................................................
E.84. Release 8.2.21 .......................................................................................................................
E.85. Release 8.2.20 .......................................................................................................................
E.86. Release 8.2.19 .......................................................................................................................
E.87. Release 8.2.18 .......................................................................................................................
E.88. Release 8.2.17 .......................................................................................................................
E.89. Release 8.2.16 .......................................................................................................................
E.90. Release 8.2.15 .......................................................................................................................
E.91. Release 8.2.14 .......................................................................................................................
E.92. Release 8.2.13 .......................................................................................................................
E.93. Release 8.2.12 .......................................................................................................................
E.94. Release 8.2.11 .......................................................................................................................
E.95. Release 8.2.10 .......................................................................................................................
E.96. Release 8.2.9 .........................................................................................................................
E.97. Release 8.2.8 .........................................................................................................................
E.98. Release 8.2.7 .........................................................................................................................
E.99. Release 8.2.6 .........................................................................................................................
E.100. Release 8.2.5 .......................................................................................................................
E.101. Release 8.2.4 .......................................................................................................................
E.102. Release 8.2.3 .......................................................................................................................
E.103. Release 8.2.2 .......................................................................................................................
E.104. Release 8.2.1 .......................................................................................................................
E.105. Release 8.2 ..........................................................................................................................
E.106. Release 8.1.23 ......................................................................................................................
E.107. Release 8.1.22 ......................................................................................................................
E.108. Release 8.1.21 ......................................................................................................................
E.109. Release 8.1.20 ......................................................................................................................
E.110. Release 8.1.19 ......................................................................................................................
E.111. Release 8.1.18 ......................................................................................................................
E.112. Release 8.1.17 ......................................................................................................................
E.113. Release 8.1.16 ......................................................................................................................
E.114. Release 8.1.15 ......................................................................................................................
E.115. Release 8.1.14 ......................................................................................................................
E.116. Release 8.1.13 ......................................................................................................................
E.117. Release 8.1.12 ......................................................................................................................
E.118. Release 8.1.11 ......................................................................................................................
E.119. Release 8.1.10 ......................................................................................................................
E.120. Release 8.1.9 .......................................................................................................................
E.121. Release 8.1.8 .......................................................................................................................
E.122. Release 8.1.7 .......................................................................................................................
E.123. Release 8.1.6 .......................................................................................................................
E.124. Release 8.1.5 .......................................................................................................................
xvi

1539
1540
1541
1543
1545
1545
1546
1548
1549
1551
1552
1554
1555
1557
1558
1559
1561
1561
1563
1565
1577
1578
1580
1581
1581
1583
1584
1585
1587
1588
1589
1590
1591
1592
1593
1593
1594
1596
1597
1598
1599
1599
1600
1601
1612
1613
1614
1615
1616
1617
1618
1619
1619
1620
1621
1622
1623
1624
1625
1625
1626
1626
1627

Documentation PostgreSQL 9.1.14

E.125. Release 8.1.4 .......................................................................................................................


E.126. Release 8.1.3 .......................................................................................................................
E.127. Release 8.1.2 .......................................................................................................................
E.128. Release 8.1.1 .......................................................................................................................
E.129. Release 8.1 ..........................................................................................................................
E.130. Release 8.0.26 ......................................................................................................................
E.131. Release 8.0.25 ......................................................................................................................
E.132. Release 8.0.24 ......................................................................................................................
E.133. Release 8.0.23 ......................................................................................................................
E.134. Release 8.0.22 ......................................................................................................................
E.135. Release 8.0.21 ......................................................................................................................
E.136. Release 8.0.20 ......................................................................................................................
E.137. Release 8.0.19 ......................................................................................................................
E.138. Release 8.0.18 ......................................................................................................................
E.139. Release 8.0.17 ......................................................................................................................
E.140. Release 8.0.16 ......................................................................................................................
E.141. Release 8.0.15 ......................................................................................................................
E.142. Release 8.0.14 ......................................................................................................................
E.143. Release 8.0.13 ......................................................................................................................
E.144. Release 8.0.12 ......................................................................................................................
E.145. Release 8.0.11 ......................................................................................................................
E.146. Release 8.0.10 ......................................................................................................................
E.147. Release 8.0.9 .......................................................................................................................
E.148. Release 8.0.8 .......................................................................................................................
E.149. Release 8.0.7 .......................................................................................................................
E.150. Release 8.0.6 .......................................................................................................................
E.151. Release 8.0.5 .......................................................................................................................
E.152. Release 8.0.4 .......................................................................................................................
E.153. Release 8.0.3 .......................................................................................................................
E.154. Release 8.0.2 .......................................................................................................................
E.155. Release 8.0.1 .......................................................................................................................
E.156. Release 8.0 ..........................................................................................................................
E.157. Release 7.4.30 ......................................................................................................................
E.158. Release 7.4.29 ......................................................................................................................
E.159. Release 7.4.28 ......................................................................................................................
E.160. Release 7.4.27 ......................................................................................................................
E.161. Release 7.4.26 ......................................................................................................................
E.162. Release 7.4.25 ......................................................................................................................
E.163. Release 7.4.24 ......................................................................................................................
E.164. Release 7.4.23 ......................................................................................................................
E.165. Release 7.4.22 ......................................................................................................................
E.166. Release 7.4.21 ......................................................................................................................
E.167. Release 7.4.20 ......................................................................................................................
E.168. Release 7.4.19 ......................................................................................................................
E.169. Release 7.4.18 ......................................................................................................................
E.170. Release 7.4.17 ......................................................................................................................
E.171. Release 7.4.16 ......................................................................................................................
E.172. Release 7.4.15 ......................................................................................................................
E.173. Release 7.4.14 ......................................................................................................................
E.174. Release 7.4.13 ......................................................................................................................
E.175. Release 7.4.12 ......................................................................................................................
E.176. Release 7.4.11 ......................................................................................................................
E.177. Release 7.4.10 ......................................................................................................................
E.178. Release 7.4.9 .......................................................................................................................
E.179. Release 7.4.8 .......................................................................................................................
E.180. Release 7.4.7 .......................................................................................................................
E.181. Release 7.4.6 .......................................................................................................................
E.182. Release 7.4.5 .......................................................................................................................
E.183. Release 7.4.4 .......................................................................................................................
E.184. Release 7.4.3 .......................................................................................................................
E.185. Release 7.4.2 .......................................................................................................................
E.186. Release 7.4.1 .......................................................................................................................
E.187. Release 7.4 ..........................................................................................................................
xvii

1628
1629
1630
1631
1632
1643
1644
1645
1646
1647
1647
1648
1648
1649
1650
1650
1651
1653
1653
1654
1654
1654
1655
1656
1657
1658
1658
1659
1660
1661
1663
1663
1675
1675
1676
1677
1678
1678
1679
1679
1680
1680
1681
1682
1683
1683
1684
1684
1684
1685
1686
1686
1687
1688
1688
1690
1691
1692
1692
1692
1693
1695
1696

Documentation PostgreSQL 9.1.14

E.188. Release 7.3.21 ......................................................................................................................


E.189. Release 7.3.20 ......................................................................................................................
E.190. Release 7.3.19 ......................................................................................................................
E.191. Release 7.3.18 ......................................................................................................................
E.192. Release 7.3.17 ......................................................................................................................
E.193. Release 7.3.16 ......................................................................................................................
E.194. Release 7.3.15 ......................................................................................................................
E.195. Release 7.3.14 ......................................................................................................................
E.196. Release 7.3.13 ......................................................................................................................
E.197. Release 7.3.12 ......................................................................................................................
E.198. Release 7.3.11 ......................................................................................................................
E.199. Release 7.3.10 ......................................................................................................................
E.200. Release 7.3.9 .......................................................................................................................
E.201. Release 7.3.8 .......................................................................................................................
E.202. Release 7.3.7 .......................................................................................................................
E.203. Release 7.3.6 .......................................................................................................................
E.204. Release 7.3.5 .......................................................................................................................
E.205. Release 7.3.4 .......................................................................................................................
E.206. Release 7.3.3 .......................................................................................................................
E.207. Release 7.3.2 .......................................................................................................................
E.208. Release 7.3.1 .......................................................................................................................
E.209. Release 7.3 ..........................................................................................................................
E.210. Release 7.2.8 .......................................................................................................................
E.211. Release 7.2.7 .......................................................................................................................
E.212. Release 7.2.6 .......................................................................................................................
E.213. Release 7.2.5 .......................................................................................................................
E.214. Release 7.2.4 .......................................................................................................................
E.215. Release 7.2.3 .......................................................................................................................
E.216. Release 7.2.2 .......................................................................................................................
E.217. Release 7.2.1 .......................................................................................................................
E.218. Release 7.2 ..........................................................................................................................
E.219. Release 7.1.3 .......................................................................................................................
E.220. Release 7.1.2 .......................................................................................................................
E.221. Release 7.1.1 .......................................................................................................................
E.222. Release 7.1 ..........................................................................................................................
E.223. Release 7.0.3 .......................................................................................................................
E.224. Release 7.0.2 .......................................................................................................................
E.225. Release 7.0.1 .......................................................................................................................
E.226. Release 7.0 ..........................................................................................................................
E.227. Release 6.5.3 .......................................................................................................................
E.228. Release 6.5.2 .......................................................................................................................
E.229. Release 6.5.1 .......................................................................................................................
E.230. Release 6.5 ..........................................................................................................................
E.231. Release 6.4.2 .......................................................................................................................
E.232. Release 6.4.1 .......................................................................................................................
E.233. Release 6.4 ..........................................................................................................................
E.234. Release 6.3.2 .......................................................................................................................
E.235. Release 6.3.1 .......................................................................................................................
E.236. Release 6.3 ..........................................................................................................................
E.237. Release 6.2.1 .......................................................................................................................
E.238. Release 6.2 ..........................................................................................................................
E.239. Release 6.1.1 .......................................................................................................................
E.240. Release 6.1 ..........................................................................................................................
E.241. Release 6.0 ..........................................................................................................................
E.242. Release 1.09 ........................................................................................................................
E.243. Release 1.02 ........................................................................................................................
E.244. Release 1.01 ........................................................................................................................
E.245. Release 1.0 ..........................................................................................................................
E.246. Postgres95 Release 0.03 .....................................................................................................
E.247. Postgres95 Release 0.02 .....................................................................................................
E.248. Postgres95 Release 0.01 .....................................................................................................
E.249. Timing Results .....................................................................................................................
F. Modules supplmentaires fournis .........................................................................................................
xviii

1708
1708
1709
1709
1709
1710
1710
1711
1712
1712
1713
1713
1714
1715
1715
1716
1716
1717
1718
1720
1721
1721
1731
1731
1732
1732
1733
1733
1734
1734
1735
1743
1744
1744
1744
1748
1749
1749
1749
1755
1755
1756
1756
1760
1760
1761
1765
1765
1766
1769
1770
1772
1773
1775
1776
1777
1778
1780
1781
1782
1783
1783
1785

Documentation PostgreSQL 9.1.14

F.1. adminpack ..............................................................................................................................


F.2. auth_delay ..............................................................................................................................
F.3. auto_explain ...........................................................................................................................
F.4. btree_gin ................................................................................................................................
F.5. btree_gist ................................................................................................................................
F.6. chkpass ..................................................................................................................................
F.7. citext .....................................................................................................................................
F.8. cube ......................................................................................................................................
F.9. dblink ....................................................................................................................................
F.10. dict_int .................................................................................................................................
F.11. dict_xsyn ..............................................................................................................................
F.12. dummy_seclabel ....................................................................................................................
F.13. earthdistance .........................................................................................................................
F.14. file_fdw ................................................................................................................................
F.15. fuzzystrmatch ........................................................................................................................
F.16. hstore ...................................................................................................................................
F.17. intagg ...................................................................................................................................
F.18. intarray .................................................................................................................................
F.19. isn .......................................................................................................................................
F.20. lo ........................................................................................................................................
F.21. ltree .....................................................................................................................................
F.22. oid2name ..............................................................................................................................
F.23. pageinspect ...........................................................................................................................
F.24. passwordcheck .......................................................................................................................
F.25. pg_archivecleanup ..................................................................................................................
F.26. pgbench ................................................................................................................................
F.27. pg_buffercache ......................................................................................................................
F.28. pgcrypto ...............................................................................................................................
F.29. pg_freespacemap ....................................................................................................................
F.30. pgrowlocks ...........................................................................................................................
F.31. pg_standby ............................................................................................................................
F.32. pg_stat_statements ..................................................................................................................
F.33. pgstattuple ............................................................................................................................
F.34. pg_test_fsync ........................................................................................................................
F.35. pg_trgm ................................................................................................................................
F.36. pg_upgrade ...........................................................................................................................
F.37. seg .......................................................................................................................................
F.38. sepgsql .................................................................................................................................
F.39. spi .......................................................................................................................................
F.40. sslinfo ..................................................................................................................................
F.41. tablefunc ...............................................................................................................................
F.42. test_parser .............................................................................................................................
F.43. tsearch2 ................................................................................................................................
F.44. unaccent ...............................................................................................................................
F.45. uuid-ossp ..............................................................................................................................
F.46. vacuumlo ..............................................................................................................................
F.47. xml2 ....................................................................................................................................
G. Projets externes ...............................................................................................................................
G.1. Interfaces client .......................................................................................................................
G.2. Outils d'administration ..............................................................................................................
G.3. Langages procduraux ..............................................................................................................
G.4. Extensions .............................................................................................................................
H. Dpt du code source ........................................................................................................................
H.1. Rcuprer les sources via Git ..................................................................................................
I. Documentation .................................................................................................................................
I.1. DocBook .................................................................................................................................
I.2. Ensemble d'outils ......................................................................................................................
I.3. Construire la documentation .......................................................................................................
I.4. criture de la documentation .......................................................................................................
I.5. Guide des styles ........................................................................................................................
J. Acronymes ......................................................................................................................................
K. Traduction franaise .........................................................................................................................
Bibliographie ............................................................................................................................................
xix

1785
1786
1786
1788
1788
1789
1790
1792
1795
1821
1821
1822
1823
1824
1825
1827
1832
1833
1836
1839
1840
1845
1848
1850
1850
1852
1857
1858
1868
1869
1870
1873
1876
1877
1878
1880
1884
1887
1892
1893
1895
1903
1904
1905
1906
1908
1909
1913
1913
1913
1913
1914
1915
1915
1916
1916
1916
1919
1922
1923
1925
1929
1931

Prface
Cet ouvrage reprsente l'adaptation franaise de la documentation officielle de PostgreSQL. Celle-ci a t rdige par les dveloppeurs de PostgreSQL et quelques volontaires en parallle du dveloppement du logiciel. Elle dcrit toutes les fonctionnalits
officiellement supportes par la dernire version de PostgreSQL.
Afin de faciliter l'accs aux informations qu'il contient, cet ouvrage est organis en plusieurs parties. Chaque partie est destine
une classe prcise d'utilisateurs ou des utilisateurs de niveaux d'expertise diffrents :

la Partie I, Tutoriel est une introduction informelle destine aux nouveaux utilisateurs ;

la Partie II, Langage SQL prsente l'environnement du langage de requtes SQL, notamment les types de donnes, les
fonctions et les optimisations utilisateurs. Tout utilisateur de PostgreSQL devrait la lire ;

la Partie III, Administration du serveur , destine aux administrateurs PostgreSQL, dcrit l'installation et l'administration
du serveur ;

la Partie IV, Interfaces client dcrit les interfaces de programmation ;

la Partie V, Programmation serveur , destine aux utilisateurs expriments, prsente les lments d'extension du serveur,
notamment les types de donnes et les fonctions utilisateurs ;

la Partie VI, Rfrence contient la documentation de rfrence de SQL et des programmes client et serveur. Cette partie est
utilise comme rfrence par les autres parties ;

la Partie VII, Internes contient diverses informations utiles aux dveloppeurs de PostgreSQL.

1. Dfinition de PostgreSQL
PostgreSQL est un systme de gestion de bases de donnes relationnelles objet (ORDBMS) fond sur POSTGRES, Version
4.2. Ce dernier a t dvelopp l'universit de Californie au dpartement des sciences informatiques de Berkeley. POSTGRES
est l'origine de nombreux concepts qui ne seront rendus disponibles au sein de systmes de gestion de bases de donnes commerciaux que bien plus tard.
PostgreSQL est un descendant libre du code original de Berkeley. Il supporte une grande partie du standard SQL tout en offrant
de nombreuses fonctionnalits modernes :

requtes complexes ;
cls trangres ;
triggers ;
vues ;
intgrit transactionnelle ;
contrle des versions concurrentes (MVCC, acronyme de MultiVersion Concurrency Control ).

De plus, PostgreSQL peut tre tendu par l'utilisateur de multiples faons, en ajoutant, par exemple :

de nouveaux types de donnes ;


de nouvelles fonctions ;
de nouveaux oprateurs ;
de nouvelles fonctions d'agrgat ;
de nouvelles mthodes d'indexage ;
de nouveaux langages de procdure.

Et grce sa licence librale, PostgreSQL peut tre utilis, modifi et distribu librement, quel que soit le but vis, qu'il soit priv, commercial ou acadmique.

2. Bref historique de PostgreSQL


Le systme de bases de donnes relationnel objet PostgreSQL est issu de POSTGRES, programme crit l'universit de Californie Berkeley. Aprs plus d'une vingtaine d'annes de dveloppement, PostgreSQL annonce tre devenu la base de donnes
libre de rfrence.

2.1. Le projet POSTGRES Berkeley


Le projet POSTGRES, men par le professeur Michael Stonebraker, tait sponsoris par le DARPA (acronyme de Defense Adxx

Prface

vanced Research Projects Agency), l'ARO (acronyme de Army Research Office), la NSF (acronyme de National Science Foundation) et ESL, Inc. Le dveloppement de POSTGRES a dbut en 1986. Les concepts initiaux du systme ont t prsents dans
Stonebraker and Rowe, 1986 et la dfinition du modle de donnes initial apparut dans Rowe and Stonebraker, 1987. Le systme
de rgles ft dcrit dans Stonebraker, Hanson, Hong, 1987, l'architecture du gestionnaire de stockage dans Stonebraker, 1987.
Depuis, plusieurs versions majeures de POSTGRES ont vu le jour. La premire dmo devint oprationnelle en 1987 et fut
prsente en 1988 lors de la confrence ACM-SIGMOD. La version 1, dcrite dans Stonebraker, Rowe, Hirohama, 1990, fut livre quelques utilisateurs externes en juin 1989. Suite la critique du premier mcanisme de rgles (Stonebraker et al, 1989), celui-ci fut rcrit (Stonebraker et al, ACM, 1990) pour la version 2, prsente en juin 1990. La version 3 apparut en 1991. Elle apporta le support de plusieurs gestionnaires de stockage, un excuteur de requtes amlior et une rcriture du gestionnaire de
rgles. La plupart des versions qui suivirent, jusqu' Postgres95 (voir plus loin), portrent sur la portabilit et la fiabilit.
POSTGRES ft utilis dans plusieurs applications, en recherche et en production. On peut citer, par exemple : un systme
d'analyse de donnes financires, un programme de suivi des performances d'un moteur raction, une base de donnes de suivi
d'astrodes, une base de donnes mdicale et plusieurs systmes d'informations gographiques. POSTGRES a aussi t utilis
comme support de formation dans plusieurs universits. Illustra Information Technologies (devenu Informix, maintenant dtenu
par IBM) a repris le code et l'a commercialis. Fin 1992, POSTGRES est devenu le gestionnaire de donnes principal du projet
de calcul scientifique Sequoia 2000.
La taille de la communaut d'utilisateurs doubla quasiment au cours de l'anne 1993. De manire vidente, la maintenance du prototype et le support prenaient un temps considrable, temps qui aurait d tre employ la recherche en bases de donnes. Dans
un souci de rduction du travail de support, le projet POSTGRES de Berkeley se termina officiellement avec la version 4.2.

2.2. Postgres95
En 1994, Andrew Yu et Jolly Chen ajoutrent un interprteur de langage SQL POSTGRES. Sous le nouveau nom de
Postgres95, le projet fut publi sur le Web comme descendant libre (OpenSource) du code source initial de POSTGRES, version Berkeley.
Le code de Postgres95 tait crit en pur C ANSI et rduit de 25%. De nombreux changements internes amliorrent les performances et la maintenabilit. Les versions 1.0.x de Postgres95 passrent le Wisconsin Benchmark avec des performances
meilleures de 30 50% par rapport POSTGRES, version 4.2. part les correctifs de bogues, les principales amliorations
furent les suivantes :

le langage PostQUEL est remplac par SQL (implant sur le serveur) ; les requtes imbriques n'ont pas t supportes avant
PostgreSQL (voir plus loin) mais elles pouvaient tre imites dans Postgres95 l'aide de fonctions SQL utilisateur ; les
agrgats furent reprogramms, la clause GROUP BY ajoute ;

un nouveau programme, psql, qui utilise GNU Readline, permet l'excution interactive de requtes SQL ; c'est la fin du programme monitor ;

une nouvelle bibliothque cliente, libpgtcl, supporte les programmes crits en Tcl ; un shell exemple, pgtclsh, fournit de
nouvelles commandes Tcl pour interfacer des programmes Tcl avec Postgres95 ;

l'interface de gestion des Large Objects est rcrite ; jusque-l, le seul mcanisme de stockage de ces objets passait par le
systme de fichiers Inversion ( Inversion file system ) ; ce systme est abandonn ;

le systme de rgles d'instance est supprim ; les rgles sont toujours disponibles en tant que rgles de rcriture ;

un bref tutoriel prsentant les possibilits du SQL ainsi que celles spcifiques Postgres95 est distribu avec les sources ;

la version GNU de make est utilise pour la construction la place de la version BSD ; Postgres95 peut galement tre compil avec un GCC sans correctif (l'alignement des doubles est corrig).

2.3. PostgreSQL
En 1996, le nom Postgres95 commence mal vieillir. Le nom choisi, PostgreSQL, souligne le lien entre POSTGRES et
les versions suivantes qui intgrent le SQL. En parallle, la version est numrote 6.0 pour reprendre la numrotation du projet
POSTGRES de Berkeley.
Beaucoup de personnes font rfrence PostgreSQL par Postgres (il est rare que le nom soit crit en capitales) par tradition
ou parce que c'est plus simple prononcer. Cet usage est accept comme alias ou pseudo.
Lors du dveloppement de Postgres95, l'effort tait ax sur l'identification et la comprhension des problmes dans le code.
Avec PostgreSQL, l'accent est mis sur les nouvelles fonctionnalits, sans pour autant abandonner les autres domaines.
L'historique de PostgreSQL partir de ce moment est disponible dans l'Annexe E, Notes de version.

xxi

Prface

3. Conventions
Cet ouvrage utilise les conventions typographiques suivantes pour marquer certaines portions du texte : les nouveaux termes,
phrases en langue trangre et autres passages importants sont tous affichs en italique. Tout ce qui reprsente une entre ou une
sortie l'cran, et en particulier le code, les commandes et les sorties d'cran, est affich l'aide d'une police espacement fixe
(exemple). l'intrieur de tels passages, l'italique (exemple) indique des contenants ; une valeur particulire doit tre insre
la place de ce contenant. Parfois, des bouts de code de programme sont affichs en gras (exemple). Cela permet de souligner les
ajouts et modifications par rapport l'exemple qui prcde.
Les conventions suivantes sont utilises dans le synopsis d'une commande : les crochets ([ et ]) indiquent des parties optionnelles. (Dans le synopsis d'une commande Tcl, des points d'interrogation (?) sont utiliss, comme c'est habituellement le cas en
Tcl.) Les accolades ({ et }) et les barres verticales (|) indiquent un choix entre plusieurs options. Les points de suspension (...)
signifient que l'lment prcdent peut tre rpt.
Lorsque cela amliore la clart, les commandes SQL sont prcdes d'une invite =>, tandis que les commandes shell le sont par $.
Dans le cadre gnral, les invites ne sont pas indiques.
Un administrateur est gnralement une personne en charge de l'installation et de la bonne marche du serveur. Un utilisateur est
une personne qui utilise ou veut utiliser une partie quelconque du systme PostgreSQL. Ces termes ne doivent pas tre pris trop
la lettre ; cet ouvrage n'a pas d'avis fig sur les procdures d'administration systme.

4. Pour plus d'informations


En dehors de la documentation, il existe d'autres ressources concernant PostgreSQL :
Wiki
Le wiki de PostgreSQL contient la FAQ (liste des questions frquemment poses), la liste TODO et des informations dtailles sur de nombreux autres thmes.
Site web
Le site web de PostgreSQL contient des dtails sur la dernire version, et bien d'autres informations pour rendre un travail
ou un investissement personnel avec PostgreSQL plus productif.
Listes de discussion
Les listes de discussion constituent un bon endroit pour trouver des rponses ses questions, pour partager ses expriences
avec celles d'autres utilisateurs et pour contacter les dveloppeurs. La consultation du site web de PostgreSQL fournit tous
les dtails.
Soi-mme !
PostgreSQL est un projet OpenSource. En tant que tel, le support dpend de la communaut des utilisateurs. Lorsque l'on
dbute avec PostgreSQL, on est tributaire de l'aide des autres, soit au travers de la documentation soit par les listes de discussion. Il est important de faire partager son tour ses connaissances par la lecture des listes de discussion et les rponses
aux questions. Lorsque quelque chose est dcouvert qui ne figurait pas dans la documentation, pourquoi ne pas en faire profiter les autres ? De mme lors d'ajout de fonctionnalits au code.

5. Lignes de conduite pour les rapports de bogues


Lorsque vous trouvez un bogue dans PostgreSQL, nous voulons en entendre parler. Vos rapports de bogues jouent un rle important pour rendre PostgreSQL plus fiable car mme avec la plus grande attention, nous ne pouvons pas garantir que chaque
partie de PostgreSQL fonctionnera sur toutes les plates-formes et dans toutes les circonstances.
Les suggestions suivantes ont pour but de vous former la saisie d'un rapport de bogue qui pourra ensuite tre gre de faon efficace. Il n'est pas requis de les suivre mais ce serait l'avantage de tous.
Nous ne pouvons pas promettre de corriger tous les bogues immdiatement. Si le bogue est vident, critique ou affecte un grand
nombre d'utilisateurs, il y a de grandes chances pour que quelqu'un s'en charge. Il se peut que nous vous demandions d'utiliser une
version plus rcente pour vrifier si le bogue est toujours prsent. Ou nous pourrions dcider que le bogue ne peut tre corrig
avant qu'une rcriture massive, que nous avions planifie, ne soit faite. Ou peut-tre est-ce trop difficile et que des choses plus
importantes nous attendent. Si vous avez besoin d'aide immdiatement, envisagez l'obtention d'un contrat de support commercial.

5.1. Identifier les bogues


Avant de rapporter un bogue, merci de lire et re-lire la documentation pour vrifier que vous pouvez rellement faire ce que vous
essayez de faire. Si ce n'est pas clair, rapportez-le aussi ; c'est un bogue dans la documentation. S'il s'avre que le programme fait
diffremment de ce qu'indique la documentation, c'est un bogue. Ceci peut inclure les circonstances suivantes, sans s'y limiter :
xxii

Prface

Un programme se terminant avec un signal fatal ou un message d'erreur du systme d'exploitation qui indiquerait un problme
avec le programme. (Un contre-exemple pourrait tre le message disk full , disque plein, car vous devez le rgler vousmme.)

Un programme produit une mauvaise sortie pour une entre donne.

Un programme refuse d'accepter une entre valide (c'est--dire telle que dfinie dans la documentation).

Un programme accepte une entre invalide sans information ou message d'erreur. Mais gardez en tte que votre ide d'entre
invalide pourrait tre notre ide d'une extension ou d'une compatibilit avec les pratiques traditionnelles.

PostgreSQL choue la compilation, la construction ou l'installation suivant les instructions des plateformes supportes.

Ici, programme fait rfrence un excutable, pas au moteur du serveur.


Une lenteur ou une absorption des ressources n'est pas ncessairement un bogue. Lisez la documentation ou demandez sur une des
listes de discussion pour de l'aide concernant l'optimisation de vos applications. Ne pas se conformer au standard SQL n'est pas
ncessairement un bogue sauf si une telle conformit est indique explicitement.
Avant de continuer, vrifiez sur la liste des choses faire ainsi que dans la FAQ pour voir si votre bogue n'est pas dj connu. Si
vous n'arrivez pas dcoder les informations sur la liste des choses faire, crivez un rapport. Le minimum que nous puissions
faire est de rendre cette liste plus claire.

5.2. Que rapporter ?


Le point le plus important se rappeler avec les rapports de bogues est de donner tous les faits et seulement les faits. Ne spculez
pas sur ce que vous pensez qui ne va pas, sur ce qu' il semble faire ou sur quelle partie le programme a une erreur. Si vous
n'tes pas familier avec l'implmentation, vous vous tromperez probablement et vous ne nous aiderez pas. Et mme si vous avez
raison, des explications compltes sont un bon supplment mais elles ne doivent pas se substituer aux faits. Si nous pensons corriger le bogue, nous devons toujours le reproduire nous-mme. Rapporter les faits stricts est relativement simple (vous pouvez probablement copier/coller partir de l'cran) mais, trop souvent, des dtails importants sont oublis parce que quelqu'un a pens
qu'ils n'avaient pas d'importance ou que le rapport serait compris.
Les lments suivants devraient tre fournis avec chaque rapport de bogue :

La squence exacte des tapes ncessaires pour reproduire le problme partir du lancement du programme. Ceci devrait se
suffire ; il n'est pas suffisant d'envoyer une simple instruction SELECT sans les commandes CREATE TABLE et INSERT
qui ont prcd, si la sortie devrait dpendre des donnes contenues dans les tables. Nous n'avons pas le temps de comprendre
le schma de votre base de donnes. Si nous sommes supposs crer nos propres donnes, nous allons probablement ne pas
voir le problme.
Le meilleur format pour un test suite un problme relatif SQL est un fichier qui peut tre lanc via l'interface psql et qui
montrera le problme. (Assurez-vous de ne rien avoir dans votre fichier de lancement ~/.psqlrc.) Un moyen facile pour
crer ce fichier est d'utiliser pg_dump pour rcuprer les dclarations des tables ainsi que les donnes ncessaires pour mettre
en place la scne. Il ne reste plus qu' ajouter la requte posant problme. Vous tes encourag minimiser la taille de votre
exemple mais ce n'est pas une obligation. Si le bogue est reproductible, nous le trouverons de toute faon.
Si votre application utilise une autre interface client, telle que PHP, alors essayez d'isoler le problme aux requtes errones.
Nous n'allons certainement pas mettre en place un serveur web pour reproduire votre problme. Dans tous les cas, rappelezvous d'apporter les fichiers d'entre exacts ; n'essayez pas de deviner que le problme se pose pour les gros fichiers ou pour
les bases de donnes de moyenne taille , etc. car cette information est trop inexacte, subjective pour tre utile.

La sortie que vous obtenez. Merci de ne pas dire que cela ne fonctionne pas ou s'est arrt brutalement . S'il existe un
message d'erreur, montrez-le mme si vous ne le comprenez pas. Si le programme se termine avec une erreur du systme
d'exploitation, dites-le. Mme si le rsultat de votre test est un arrt brutal du programme ou un autre souci vident, il pourrait
ne pas survenir sur notre plateforme. Le plus simple est de copier directement la sortie du terminal, si possible.

Note
Si vous rapportez un message d'erreur, merci d'obtenir la forme la plus verbeuse de ce message. Avec psql, excutez \set VERBOSITY verbose avant tout. Si vous rcuprez le message des traces du serveur, initialisez la variable d'excution log_error_verbosity avec verbose pour que tous les dtails soient tracs.

Note
Dans le cas d'erreurs fatales, le message d'erreur rapport par le client pourrait ne pas contenir toutes les inforxxiii

Prface

mations disponibles. Jetez aussi un il aux traces du serveur de la base de donnes. Si vous ne conservez pas
les traces de votre serveur, c'est le bon moment pour commencer le faire.

Il est trs important de prciser ce que vous attendez en sortie. Si vous crivez uniquement Cette commande m'a donn cette
rponse. ou Ce n'est pas ce que j'attendais. , nous pourrions le lancer nous-mme, analyser la sortie et penser que tout est
correct car cela correspond exactement ce que nous attendions. Nous ne devrions pas avoir passer du temps pour dcoder la
smantique exacte de vos commandes. Tout spcialement, ne vous contentez pas de dire que Ce n'est pas ce que SQL spcifie/Oracle fait. Rechercher le comportement correct partir de SQL n'est pas amusant et nous ne connaissons pas le comportement de tous les autres serveurs de base de donnes relationnels. (Si votre problme est un arrt brutal du serveur, vous pouvez videmment omettre cet lment.)

Toutes les options en ligne de commande ainsi que les autres options de lancement incluant les variables d'environnement ou
les fichiers de configuration que vous avez modifi. Encore une fois, soyez exact. Si vous utilisez une distribution prpackage qui lance le serveur au dmarrage, vous devriez essayer de retrouver ce que cette distribution fait.

Tout ce que vous avez fait de diffrent partir des instructions d'installation.

La version de PostgreSQL. Vous pouvez lancer la commande SELECT version(); pour trouver la version du serveur
sur lequel vous tes connect. La plupart des excutables disposent aussi d'une option --version ; postgres -version et psql --version devraient au moins fonctionner. Si la fonction ou les options n'existent pas, alors votre
version est bien trop ancienne et vous devez mettre jour. Si vous avez lanc une version prpare sous forme de paquets, tel
que les RPM, dites-le en incluant la sous-version que le paquet pourrait avoir. Si vous tes sur une version Git, mentionnez-le
en indiquant le hachage du commit.
Si votre version est antrieure la 9.1.14, nous allons certainement vous demander de mettre jour. Beaucoup de corrections
de bogues et d'amliorations sont apportes dans chaque nouvelle version, donc il est bien possible qu'un bogue rencontr dans
une ancienne version de PostgreSQL soit dj corrig. Nous ne fournissons qu'un support limit pour les sites utilisant
d'anciennes versions de PostgreSQL ; si vous avez besoin de plus de support que ce que nous fournissons, considrez
l'acquisition d'un contrat de support commercial.

Informations sur la plate-forme. Ceci inclut le nom du noyau et sa version, bibliothque C, processeur, mmoires et ainsi de
suite. Dans la plupart des cas, il est suffisant de prciser le vendeur et la version mais ne supposez pas que tout le monde sait
ce que Debian contient ou que tout le monde utilise des i386. Si vous avez des problmes l'installation, des informations
sur l'ensemble des outils de votre machine (compilateurs, make, etc.) sont aussi ncessaires.

N'ayez pas peur si votre rapport de bogue devient assez long. C'est un fait. Il est prfrable de rapporter tous les faits la premire
fois plutt que nous ayons vous tirer les vers du nez. D'un autre ct, si vos fichiers d'entre sont trop gros, il est prfrable de
demander si quelqu'un souhaite s'y plonger. Voici un article qui relve quelques autres conseils sur les rapports de bogues.
Ne passez pas tout votre temps vous demander quelles modifications apporter pour que le problme s'en aille. Ceci ne nous aidera probablement pas le rsoudre. S'il arrive que le bogue ne peut pas tre corrig immdiatement, vous aurez toujours
l'opportunit de chercher ceci et de partager vos trouvailles. De mme, encore une fois, ne perdez pas votre temps deviner pourquoi le bogue existe. Nous le trouverons assez rapidement.
Lors de la rdaction d'un rapport de bogue, merci de choisir une terminologie qui ne laisse pas place aux confusions. Le paquet logiciel en totalit est appel PostgreSQL , quelquefois Postgres en court. Si vous parlez spcifiquement du serveur, mentionnez-le mais ne dites pas seulement PostgreSQL a plant . Un arrt brutal d'un seul processus serveur est assez diffrent de
l'arrt brutal du postgres pre ; merci de ne pas dire que le serveur a plant lorsque vous voulez dire qu'un seul processus
s'est arrt, ni vice versa. De plus, les programmes clients tels que l'interface interactive psql sont compltement spars du
moteur. Essayez d'tre prcis sur la provenance du problme : client ou serveur.

5.3. O rapporter des bogues ?


En gnral, envoyez vos rapports de bogue la liste de discussion des rapports de bogue
(<pgsql-bogues@postgresql.org>). Nous vous demandons d'utiliser un sujet descriptif pour votre courrier lectronique,
par exemple une partie du message d'erreur.
Une autre mthode consiste remplir le formulaire web disponible sur le site web du projet. Saisir un rapport de bogue de cette
faon fait que celui-ci est envoy la liste de discussion <pgsql-bogues@postgresql.org>.
Si votre rapport de bogue a des implications sur la scurit et que vous prfreriez qu'il ne soit pas immdiatement visible dans les
archives publiques, ne l'envoyez pas sur pgsql-bugs. Les problmes de scurit peuvent tre rapports de faon priv sur
<security@postgresql.org>.
N'envoyez pas de rapports de bogue aux listes de discussion des utilisateurs, comme <pgsql-sql@postgresql.org> ou
<pgsql-general@postgresql.org>. Ces listes de discussion servent rpondre aux questions des utilisateurs et les abonxxiv

Prface

ns ne souhaitent pas recevoir de rapports de bogues. Plus important, ils ont peu de chance de les corriger.
De mme, n'envoyez pas vos rapports de bogue la liste de discussion des dveloppeurs
<pgsql-hackers@postgresql.org>. Cette liste sert aux discussions concernant le dveloppement de PostgreSQL et il
serait bon de conserver les rapports de bogue sparment. Nous pourrions choisir de discuter de votre rapport de bogue sur pgsql-hackers si le problme ncessite que plus de personnes s'en occupent.
Si vous avez un problme avec la documentation, le meilleur endroit pour le rapporter est la liste de discussion pour la documentation <pgsql-docs@postgresql.org>. Soyez prcis sur la partie de la documentation qui vous dplat.
Si votre bogue concerne un problme de portabilit sur une plate-forme non supporte, envoyez un courrier lectronique
<pgsql-hackers@postgresql.org>, pour que nous puissions travailler sur le portage de PostgreSQL sur votre plateforme.

Note
D, malheureusement, au grand nombre de pourriels (spam), toutes les adresses de courrier lectronique ci-dessus
appartiennent des listes de discussion fermes. Autrement dit, vous devez tre abonn pour tre autoris y envoyer un courrier. Nanmoins, vous n'avez pas besoin de vous abonner pour utiliser le formulaire web de rapports
de bogue. Si vous souhaitez envoyer des courriers mais ne pas recevoir le trafic de la liste, vous pouvez vous abonner et configurer l'option nomail. Pour plus d'informations, envoyez un courrier
<majordomo@postgresql.org> avec le seul mot help dans le corps du message.

xxv

Partie I. Tutoriel
Bienvenue dans le tutoriel de PostgreSQL. Les chapitres suivants prsentent une courte introduction PostgreSQL, aux
concepts des bases de donnes relationnelles et au langage SQL ceux qui dbutent dans l'un de ces domaines. Seules sont ncessaires des connaissances gnrales sur l'utilisation des ordinateurs. Aucune exprience particulire d'Unix ou de programmation
n'est requise. Ce tutoriel a surtout pour but de faire acqurir une exprience pratique des aspects importants du systme PostgreSQL. Il n'est ni exhaustif ni complet, mais introductif.
la suite de ce tutoriel, la lecture de la Partie II, Langage SQL permettra d'acqurir une connaissance plus complte du langage SQL, celle de la Partie IV, Interfaces client des informations sur le dveloppement d'applications. La configuration et la
gestion sont dtailles dans la Partie III, Administration du serveur .

Chapitre 1. Dmarrage
1.1. Installation
Avant de pouvoir utiliser PostgreSQL, vous devez l'installer. Il est possible que PostgreSQL soit dj install dans votre environnement, soit parce qu'il est inclus dans votre distribution, soit parce que votre administrateur systme s'en est charg. Dans
ce cas, vous devriez obtenir les informations ncessaires pour accder PostgreSQL dans la documentation de votre distribution ou de la part de votre administrateur.
Si vous n'tes pas sr que PostgreSQL soit dj disponible ou que vous puissiez l'utiliser pour vos tests, vous avez la possibilit de l'installer vous-mme. Le faire n'est pas difficile et peut tre un bon exercice. PostgreSQL peut tre install par
n'importe quel utilisateur sans droit particulier. Aucun accs administrateur (root) n'est requis.
Si vous installez PostgreSQL vous-mme, rfrez-vous au Chapitre 15, Procdure d'installation de PostgreSQL du code
source, pour les instructions sur l'installation, puis revenez ce guide quand l'installation est termine. Nous vous conseillons de
suivre attentivement la section sur la configuration des variables d'environnement appropries.
Si votre administrateur n'a pas fait une installation par dfaut, vous pouvez avoir effectuer un paramtrage supplmentaire. Par
exemple, si le serveur de bases de donnes est une machine distante, vous aurez besoin de configurer la variable
d'environnement PGHOST avec le nom du serveur de bases de donnes. Il sera aussi peut-tre ncessaire de configurer la variable d'environnement PGPORT. La dmarche est la suivante : si vous essayez de dmarrer un programme et qu'il se plaint de
ne pas pouvoir se connecter la base de donnes, vous devez consulter votre administrateur ou, si c'est vous, la documentation
pour tre sr que votre environnement est correctement paramtr. Si vous n'avez pas compris le paragraphe prcdent, lisez
donc la prochaine section.

1.2. Concepts architecturaux de base


Avant de continuer, vous devez connatre les bases de l'architecture systme de PostgreSQL. Comprendre comment les parties
de PostgreSQL interagissent entre elles rendra ce chapitre un peu plus clair.
Dans le jargon des bases de donnes, PostgreSQL utilise un modle client/serveur. Une session PostgreSQL est le rsultat
de la coopration des processus (programmes) suivants :

Un processus serveur, qui gre les fichiers de la base de donnes, accepte les connexions la base de la part des applications
clientes et effectue sur la base les actions des clients. Le programme serveur est appel postgres.

L'application cliente (l'application de l'utilisateur), qui veut effectuer des oprations sur la base de donnes. Les applications
clientes peuvent tre de nature trs diffrentes : un client peut tre un outil texte, une application graphique, un serveur web
qui accde la base de donnes pour afficher des pages web ou un outil spcialis dans la maintenance de bases de donnes.
Certaines applications clientes sont fournies avec PostgreSQL ; la plupart sont dveloppes par les utilisateurs.

Comme souvent avec les applications client/serveur, le client et le serveur peuvent tre sur des htes diffrents. Dans ce cas, ils
communiquent travers une connexion rseau TCP/IP. Vous devez garder cela l'esprit car les fichiers qui sont accessibles sur
la machine cliente peuvent ne pas l'tre (ou l'tre seulement en utilisant des noms de fichiers diffrents) sur la machine excutant
le serveur de bases de donnes.
Le serveur PostgreSQL peut traiter de multiples connexions simultanes depuis les clients. Dans ce but, il dmarre un nouveau processus pour chaque connexion. ce moment, le client et le nouveau processus serveur communiquent sans intervention
de la part du processus postgres original. Ainsi, le processus serveur matre s'excute toujours, attendant de nouvelles
connexions clientes, tandis que le client et les processus serveurs associs vont et viennent (bien sr, tout ceci est invisible pour
l'utilisateur ; nous le mentionnons ici seulement par exhaustivit).

1.3. Cration d'une base de donnes


Le premier test pour voir si vous pouvez accder au serveur de bases de donnes consiste essayer de crer une base. Un serveur PostgreSQL peut grer plusieurs bases de donnes. Gnralement, une base de donnes distincte est utilise pour chaque
projet ou pour chaque utilisateur.
Il est possible que votre administrateur ait dj cr une base pour vous. Il devrait vous avoir dit son nom. Dans ce cas, vous
pouvez omettre cette tape et aller directement la prochaine section.
Pour crer une nouvelle base, nomme ma_base dans cet exemple, utilisez la commande suivante :
$ createdb ma_base
2

Dmarrage

Si cette commande ne fournit aucune rponse, cette tape est russie et vous pouvez sauter le reste de cette section.
Si vous voyez un message similaire :
createdb: command not found
alors PostgreSQL n'a pas t install correctement. Soit il n'a pas t install du tout, soit le chemin systme n'a pas t configur pour l'inclure. Essayez d'appeler la commande avec le chemin absolu :
$ /usr/local/pgsql/bin/createdb ma_base
Le chemin sur votre serveur peut tre diffrent. Contactez votre administrateur ou vrifiez dans les instructions d'installation pour
corriger la commande.
Voici une autre rponse possible :
createdb: could not connect to database postgres: could not connect to server: No such
file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
Cela signifie que le serveur n'tait pas dmarr, ou qu'il n'tait pas dmarr l o createdb l'attendait. Une fois encore, vrifiez les
instructions d'installation ou consultez votre administrateur.
Voici encore une autre rponse possible :
createdb: could not connect to database postgres: FATAL:

role "joe" does not exist

mais avec votre propre nom de connexion mentionn la place de joe. Ceci survient si l'administrateur n'a pas cr de compte utilisateur PostgreSQL pour vous (les comptes utilisateurs PostgreSQL sont distincts de ceux du systme d'exploitation). Si
vous tes l'administrateur, la lecture du Chapitre 20, Rles de la base de donnes vous expliquera comment crer de tels comptes.
Vous aurez besoin de prendre l'identit de l'utilisateur du systme d'exploitation sous lequel PostgreSQL a t install
(gnralement postgres) pour crer le compte du premier utilisateur. Cela pourrait aussi signifier que vous avez un nom
d'utilisateur PostgreSQL qui est diffrent de celui de votre compte utilisateur du systme d'exploitation. Dans ce cas, vous avez
besoin d'utiliser l'option -U ou de configurer la variable d'environnement PGUSER pour spcifier votre nom d'utilisateur PostgreSQL.
Si vous n'avez pas les droits requis pour crer une base, vous verrez le message suivant :
createdb: database creation failed: ERROR:

permission denied to create database

Tous les utilisateurs n'ont pas l'autorisation de crer de nouvelles bases de donnes. Si PostgreSQL refuse de crer des bases
pour vous, alors il faut que l'administrateur vous accorde ce droit. Consultez votre administrateur si cela arrive. Si vous avez install vous-mme PostgreSQL, alors vous devez ouvrir une session sous le compte utilisateur que vous avez utilis pour dmarrer le serveur. 1
Vous pouvez aussi crer des bases de donnes avec d'autres noms. PostgreSQL vous permet de crer un nombre quelconque de
bases sur un site donn. Le nom des bases doit avoir comme premier caractre un caractre alphabtique et est limit 63 octets
de longueur. Un choix pratique est de crer une base avec le mme nom que votre nom d'utilisateur courant. Beaucoup d'outils utilisent ce nom comme nom par dfaut pour la base : cela permet de gagner du temps en saisie. Pour crer cette base, tapez simplement :
$ createdb
Si vous ne voulez plus utiliser votre base, vous pouvez la supprimer. Par exemple, si vous tes le propritaire (crateur) de la base
ma_base, vous pouvez la dtruire en utilisant la commande suivante :
$ dropdb ma_base
(Pour cette commande, le nom de la base n'est pas par dfaut le nom du compte utilisateur. Vous devez toujours en spcifier un.)
Cette action supprime physiquement tous les fichiers associs avec la base de donnes et elle ne peut pas tre annule, donc cela
doit se faire avec beaucoup de prvoyance.
createdb(1) et dropdb(1) apportent beaucoup plus d'informations sur createdb et dropdb.

Quelques explications : les noms d'utilisateurs de PostgreSQL sont diffrents des comptes utilisateurs du systme d'exploitation. Quand vous vous connectez une base de donnes, vous pouvez choisir le nom d'utilisateur PostgreSQL que vous utilisez. Si vous ne spcifiez rien, cela sera par dfaut le mme nom que votre compte systme courant. En fait, il existe toujours un compte utilisateur PostgreSQL qui a le mme nom que l'utilisateur du systme d'exploitation qui a dmarr le serveur, et cet utilisateur a toujours le droit de crer des bases. Au lieu de vous connecter au systme en tant que
cet utilisateur, vous pouvez spcifier partout l'option -U pour slectionner un nom d'utilisateur PostgreSQL sous lequel vous connecter.

Dmarrage

1.4. Accder une base


Une fois que vous avez cr la base, vous pouvez y accder :

Dmarrez le programme en ligne de commande de PostgreSQL, appel psql, qui vous permet de saisir, d'diter et d'excuter
de manire interactive des commandes SQL.
Utilisez un outil existant avec une interface graphique comme pgAdmin ou une suite bureautique avec un support ODBC ou
JDBC pour crer et manipuler une base. Ces possibilits ne sont pas couvertes dans ce tutoriel.
crivez une application personnalise en utilisant un des nombreux langages disponibles. Ces possibilits sont davantage examines dans la Partie IV, Interfaces client .

Vous aurez probablement besoin de lancer psql pour essayer les exemples de ce tutoriel. Pour cela, saisissez la commande suivante :
$ psql ma_base
Si vous n'indiquez pas le nom de la base, alors psql utilisera par dfaut le nom de votre compte utilisateur. Vous avez dj dcouvert ce principe dans la section prcdente en utilisant createdb.
Dans psql, vous serez accueilli avec le message suivant :
psql (9.1.14)
Type "help" for help.
ma_base=>
La dernire ligne peut aussi tre :
ma_base=#
Cela veut dire que vous tes le super-utilisateur de la base de donnes, ce qui est souvent le cas si vous avez install
PostgreSQL vous-mme. tre super-utilisateur ou administrateur signifie que vous n'tes pas sujet aux contrles d'accs.
Concernant ce tutoriel, cela n'a pas d'importance.
Si vous rencontrez des problmes en excutant psql, alors retournez la section prcdente. Les diagnostiques de psql et de createdb sont semblables. Si le dernier fonctionnait, alors le premier devrait fonctionner galement.
La dernire ligne affiche par psql est l'invite. Cela indique que psql est l'coute et que vous pouvez saisir des requtes SQL
dans l'espace de travail maintenu par psql. Essayez ces commandes :
ma_base=> SELECT version();
version
----------------------------------------------------------------------PostgreSQL 9.1.14 on i586-pc-linux-gnu, compiled by GCC 2.96, 32-bit
(1 row)
ma_base=> SELECT current_date;
date
-----------2002-08-31
(1 row)
ma_base=> SELECT 2 + 2;
?column?
---------4
(1 row)
Le programme psql dispose d'un certain nombre de commandes internes qui ne sont pas des commandes SQL. Elles commencent
avec le caractre antislash (une barre oblique inverse, \ ). Par exemple, vous pouvez obtenir de l'aide sur la syntaxe de nombreuses commandes SQL de PostgreSQL en excutant :
ma_base=> \h
Pour sortir de psql, saisissez :
ma_base=> \q
et psql se terminera et vous ramnera votre shell. Pour plus de commandes internes, saisissez \? l'invite de psql. Les possibilits compltes de psql sont documentes dans psql(1). Dans ce tutoriel, nous ne verrons pas ces caractristiques explicitement mais
vous pouvez les utiliser vous-mme quand cela vous est utile.

Chapitre 2. Le langage SQL


2.1. Introduction
Ce chapitre fournit un panorama sur la faon d'utiliser SQL pour excuter des oprations simples. Ce tutoriel est seulement prvu pour vous donner une introduction et n'est, en aucun cas, un tutoriel complet sur SQL. De nombreux livres ont t crits sur
SQL, incluant melt93 et date97. Certaines caractristiques du langage de PostgreSQL sont des extensions de la norme.
Dans les exemples qui suivent, nous supposons que vous avez cr une base de donnes appele ma_base, comme cela a t
dcrit dans le chapitre prcdent et que vous avez t capable de lancer psql.
Les exemples dans ce manuel peuvent aussi tre trouvs dans le rpertoire src/tutorial/ de la distribution source de PostgreSQL. (Les distributions binaires de PostgreSQL pourraient ne pas proposer ces fichiers.) Pour utiliser ces fichiers, commencez par changer de rpertoire et lancez make :
$ cd ..../src/tutorial
$ make
Ceci cre les scripts et compile les fichiers C contenant des fonctions et types dfinis par l'utilisateur. Puis, pour lancer le tutoriel, faites ce qui suit :
$ cd ..../tutorial
$ psql -s ma_base
...
ma_base=> \i basics.sql
La commande \i de psql lit les commandes depuis le fichier spcifi. L'option -s vous place dans un mode pas pas qui fait
une pause avant d'envoyer chaque instruction au serveur. Les commandes utilises dans cette section sont dans le fichier basics.sql.

2.2. Concepts
PostgreSQL est un systme de gestion de bases de donnes relationnelles (SGBDR). Cela signifie que c'est un systme pour
grer des donnes stockes dans des relations. Relation est essentiellement un terme mathmatique pour table. La notion de stockage de donnes dans des tables est si commune aujourd'hui que cela peut sembler en soi vident mais il y a de nombreuses
autres manires d'organiser des bases de donnes. Les fichiers et rpertoires dans les systmes d'exploitation de type Unix
forment un exemple de base de donnes hirarchique. Un dveloppement plus moderne est une base de donnes oriente objets.
Chaque table est un ensemble de lignes. Chaque ligne d'une table donne a le mme ensemble de colonnes et chaque colonne est
d'un type de donnes particulier. Tandis que les colonnes ont un ordre fix dans chaque ligne, il est important de se rappeler que
SQL ne garantit, d'aucune faon, l'ordre des lignes l'intrieur de la table (bien qu'elles puissent tre explicitement tries pour
l'affichage).
Les tables sont groupes dans des bases de donnes et un ensemble de bases gres par une instance unique du serveur PostgreSQL constitue une instance de bases (cluster en anglais).

2.3. Crer une nouvelle table


Vous pouvez crer une nouvelle table en spcifiant le nom de la table, suivi du nom de toutes les colonnes et de leur type :
CREATE TABLE temps (
ville
varchar(80),
t_basse
int,
t_haute
int,
prcp
real,
date
date
);

-- temprature basse
-- temprature haute
-- prcipitation

Vous pouvez saisir cela dans psql avec les sauts de lignes. psql reconnatra que la commande n'est pas termine jusqu' arriver
un point-virgule.
Les espaces blancs (c'est--dire les espaces, les tabulations et les retours la ligne) peuvent tre librement utiliss dans les commandes SQL. Cela signifie que vous pouvez saisir la commande ci-dessus aligne diffremment ou mme sur une seule ligne.
Deux tirets ( -- ) introduisent des commentaires. Ce qui les suit est ignor jusqu' la fin de la ligne. SQL est insensible la
casse pour les mots-cls et les identifiants except quand les identifiants sont entre double guillemets pour prserver leur casse
(non fait ci-dessus).
5

Le langage SQL

varchar(80) spcifie un type de donnes pouvant contenir une chane de caractres arbitraires de 80 caractres au maximum. int est
le type entier normal. real est un type pour les nombres dcimaux en simple prcision. date devrait s'expliquer de lui-mme (oui, la
colonne de type date est aussi nomme date ; cela peut tre commode ou porter confusion, vous de choisir).
PostgreSQL prend en charge les types SQL standards int, smallint, real, double precision, char(N), varchar(N), date, time, timestamp et interval ainsi que d'autres types d'utilit gnrale et un riche ensemble de types gomtriques. PostgreSQL peut tre personnalis avec un nombre arbitraire de types de donnes dfinis par l'utilisateur. En consquence, les noms des types ne sont pas
des mots-cl dans la syntaxe sauf lorsqu'il est requis de supporter des cas particuliers dans la norme SQL.
Le second exemple stockera des villes et leur emplacement gographique associ :
CREATE TABLE villes (
nom
varchar(80),
emplacement
point
);
Le type point est un exemple d'un type de donnes spcifique PostgreSQL.
Pour finir, vous devez savoir que si vous n'avez plus besoin d'une table ou que vous voulez la recrer diffremment, vous pouvez
la supprimer en utilisant la commande suivante :
DROP TABLE nom_table;

2.4. Remplir une table avec des lignes


L'instruction INSERT est utilise pour remplir une table avec des lignes :
INSERT INTO temps VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');
Notez que tous les types utilisent des formats d'entres plutt vident. Les constantes qui ne sont pas des valeurs numriques
simples doivent tre habituellement entoures par des guillemets simples (') comme dans l'exemple. Le type date est en ralit
tout fait flexible dans ce qu'il accepte mais, pour ce tutoriel, nous collerons au format non ambigu montr ici.
Le type point demande une paire de coordonnes en entre comme cela est montr ici :
INSERT INTO villes VALUES ('San Francisco', '(-194.0, 53.0)');
La syntaxe utilise jusqu' maintenant ncessite de se rappeler l'ordre des colonnes. Une syntaxe alternative vous autorise lister
les colonnes explicitement :
INSERT INTO temps (ville, t_basse, t_haute, prcp, date)
VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29');
Vous pouvez lister les colonnes dans un ordre diffrent si vous le souhaitez ou mme omettre certaines colonnes ; par exemple, si
la prcipitation est inconnue :
INSERT INTO temps (date, ville, t_haute, t_basse)
VALUES ('1994-11-29', 'Hayward', 54, 37);
De nombreux dveloppeurs considrent que le listage explicite des colonnes est un meilleur style que de compter sur l'ordre implicite.
Merci d'excuter toutes les commandes vues ci-dessus de faon avoir des donnes sur lesquelles travailler dans les prochaines
sections.
Vous auriez pu aussi utiliser COPY pour charger de grandes quantits de donnes depuis des fichiers texte. C'est habituellement
plus rapide car la commande COPY est optimise pour cet emploi mais elle est moins flexible que INSERT. Par exemple :
COPY temps FROM '/home/utilisateur/temps.txt';
o le nom du fichier source doit tre disponible sur la machine qui excute le processus serveur car le processus serveur lit le fichier directement. Vous avez plus d'informations sur la commande COPY dans COPY(7).

2.5. Interroger une table


Pour retrouver les donnes d'une table, elle est interroge. Une instruction SQL SELECT est utilise pour faire cela. L'instruction
est divise en liste de slection (la partie qui liste les colonnes retourner), une liste de tables (la partie qui liste les tables partir
desquelles les donnes seront retrouves) et une qualification optionnelle (la partie qui spcifie les restrictions). Par exemple, pour
retrouver toutes les lignes de la table temps, saisissez :
SELECT * FROM temps;
6

Le langage SQL
Ici, * est un raccourci pour toutes les colonnes . 1 Donc, le mme rsultat pourrait tre obtenu avec :
SELECT ville, t_basse, t_haute, prcp, date FROM temps;
Le rsultat devrait tre ceci :
ville
| t_basse | t_haute | prcp |
date
---------------+---------+---------+------+-----------San Francisco |
46 |
50
| 0.25 | 1994-11-27
San Francisco |
43 |
57
|
0 | 1994-11-29
Hayward
|
37 |
54
|
| 1994-11-29
(3 rows)
Vous pouvez crire des expressions, pas seulement des rfrences de simples colonnes, dans la liste de slection. Par exemple,
vous pouvez faire :
SELECT ville, (t_haute+t_basse)/2 AS temp_moy, date FROM temps;
Cela devrait donner :
ville
| temp_moy |
date
---------------+----------+-----------San Francisco |
48 | 1994-11-27
San Francisco |
50 | 1994-11-29
Hayward
|
45 | 1994-11-29
(3 rows)
Notez comment la clause AS est utilise pour renommer la sortie d'une colonne (cette clause AS est optionnelle).
Une requte peut tre qualifie en ajoutant une clause WHERE qui spcifie les lignes souhaites. La clause WHERE contient une
expression boolenne et seules les lignes pour lesquelles l'expression boolenne est vraie sont renvoyes. Les oprateurs boolens
habituels (AND, OR et NOT) sont autoriss dans la qualification. Par exemple, ce qui suit recherche le temps San Francisco les
jours pluvieux :
SELECT * FROM temps
WHERE ville = 'San Francisco' AND prcp > 0.0;
Rsultat :
ville
| t_basse | t_haute | prcp |
date
---------------+---------+---------+------+-----------San Francisco |
46 |
50 | 0.25 | 1994-11-27
(1 row)
Vous pouvez demander ce que les rsultats d'une requte soient renvoys dans un ordre tri :
SELECT * FROM temps
ORDER BY ville;
ville
| t_basse | t_haute | prcp |
date
--------------+---------+---------+------+-----------Hayward
|
37 |
54 |
| 1994-11-29
San Francisco |
43 |
57 |
0 | 1994-11-29
San Francisco |
46 |
50 | 0.25 | 1994-11-27
Dans cet exemple, l'ordre de tri n'est pas spcifi compltement, donc vous pouvez obtenir les lignes San Francisco dans n'importe
quel ordre. Mais, vous auriez toujours obtenu les rsultats affichs ci-dessus si vous aviez fait :
SELECT * FROM temps
ORDER BY ville, t_basse;
Vous pouvez demander que les lignes dupliques soient supprimes du rsultat d'une requte :
SELECT DISTINCT ville
FROM temps;
ville
--------------Hayward
San Francisco
(2 rows)
1

Alors que SELECT * est utile pour des requtes rapides, c'est gnralement considr comme un mauvais style dans un code en production car l'ajout d'une colonne dans la table changerait les rsultats.

Le langage SQL

De nouveau, l'ordre des lignes rsultats pourrait varier. Vous pouvez vous assurer des rsultats cohrents en utilisant DISTINCT
et ORDER BY ensemble : 2
SELECT DISTINCT ville
FROM temps
ORDER BY ville;

2.6. Jointures entre les tables


Jusqu'ici, nos requtes avaient seulement consult une table la fois. Les requtes peuvent accder plusieurs tables en mme
temps ou accder la mme table de faon ce que plusieurs lignes de la table soient traites en mme temps. Une requte qui
consulte plusieurs lignes de la mme ou de diffrentes tables en mme temps est appele requte de jointure. Comme exemple,
supposez que vous souhaitez comparer la colonne ville de chaque ligne de la table temps avec la colonne nom de toutes les
lignes de la table villes et que vous choisissez les paires de lignes o ces valeurs correspondent.

Note
Ceci est uniquement un modle conceptuel. La jointure est habituellement excute d'une manire plus efficace que
la comparaison de chaque paire de lignes mais c'est invisible pour l'utilisateur.
Ceci sera accompli avec la requte suivante :
SELECT *
FROM temps, villes
WHERE ville = nom;
ville
| t_basse | t_haute | prcp |
date
|
nom
| emplacement
---------------+---------+---------+------+------------+---------------+------------San Francisco |
46 |
50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
San Francisco |
43 |
57 |
0 | 1994-11-29 | San Francisco | (-194,53)
(2 rows)
Deux remarques propos du rsultat :

Il n'y a pas de lignes pour la ville de Hayward dans le rsultat. C'est parce qu'il n'y a aucune entre correspondante dans la
table villes pour Hayward, donc la jointure ignore les lignes n'ayant pas de correspondance avec la table temps. Nous verrons
rapidement comment cela peut tre rsolu.

Il y a deux colonnes contenant le nom des villes. C'est correct car les listes des colonnes des tables temps et villes sont concatnes. En pratique, ceci est indsirable, vous voudrez probablement lister les colonnes explicitement plutt que d'utiliser * :
SELECT ville, t_basse, t_haute, prcp, date, emplacement
FROM temps, villes
WHERE ville = nom;

Exercice : Essayez de dterminer la smantique de cette requte quand la clause WHERE est omise.
Puisque toutes les colonnes ont un nom diffrent, l'analyseur a automatiquement trouv quelle table elles appartiennent. Si des
noms de colonnes sont communs entre les deux tables, vous aurez besoin de qualifier les noms des colonnes pour prciser celles
dont vous parlez. Par exemple :
SELECT temps.ville, temps.t_basse, temps.t_haute,
temps.prcp, temps.date, villes.emplacement
FROM temps, villes
WHERE villes.nom = temps.ville;
La qualification des noms de colonnes dans une requte de jointure est frquemment considre comme une bonne pratique. Cela
vite l'chec de la requte si un nom de colonne dupliqu est ajout plus tard dans une des tables.
Les requtes de jointure vues jusqu'ici peuvent aussi tre crites sous une autre forme :
SELECT *
FROM temps INNER JOIN villes ON (temps.ville = villes.nom);

Dans certains systmes de bases de donnes, ceci incluant les anciennes versions de PostgreSQL, l'implmentation de DISTINCT ordonne automatiquement les lignes. Du coup, ORDER BY n'est pas
ncessaire. Mais, ceci n'est pas requis par le standard SQL et PostgreSQL ne vous garantit pas actuellement que DISTINCT ordonne les lignes.

Le langage SQL

Cette syntaxe n'est pas aussi couramment utilise que les prcdentes mais nous la montrons ici pour vous aider comprendre les
sujets suivants.
Maintenant, nous allons essayer de comprendre comment nous pouvons avoir les entres de Hayward. Nous voulons que la requte parcourt la table temps et que, pour chaque ligne, elle trouve la (ou les) ligne(s) de villes correspondante(s). Si aucune ligne
correspondante n'est trouve, nous voulons que les valeurs des colonnes de la table villes soient remplaces par des valeurs
vides . Ce genre de requtes est appel jointure externe (outer join). (Les jointures que nous avons vus jusqu'ici sont des jointures
internes -- inner joins). La commande ressemble cela :
SELECT *
FROM temps LEFT OUTER JOIN villes ON (temps.ville = villes.nom);
ville
| t_basse | t_haute | prcp |
date
|
nom
| emplacement
---------------+---------+---------+------+------------+---------------+------------Hayward
|
37 |
54 |
| 1994-11-29 |
|
San Francisco |
46 |
50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
San Francisco |
43 |
57 |
0 | 1994-11-29 | San Francisco | (-194,53)
(3 rows)
Cette requte est appele une jointure externe gauche (left outer join) parce que la table mentionne la gauche de l'oprateur de
jointure aura au moins une fois ses lignes dans le rsultat tandis que la table sur la droite aura seulement les lignes qui correspondent des lignes de la table de gauche. Lors de l'affichage d'une ligne de la table de gauche pour laquelle il n'y a pas de correspondance dans la table de droite, des valeurs vides (appeles NULL) sont utilises pour les colonnes de la table de droite.
Exercice : Il existe aussi des jointures externes droite et des jointures externes compltes. Essayez de trouver ce qu'elles font.
Nous pouvons galement joindre une table avec elle-mme. Ceci est appel une jointure rflexive. Comme exemple, supposons
que nous voulons trouver toutes les entres de temps qui sont dans un intervalle de temprature d'autres entres de temps. Nous
avons donc besoin de comparer les colonnes t_basse et t_haute de chaque ligne de temps aux colonnes t_basse et
t_haute de toutes les autres lignes de temps. Nous pouvons faire cela avec la requte suivante :
SELECT T1.ville, T1.t_basse AS bas, T1.t_haute AS haut,
T2.ville, T2.t_basse AS bas, T2.t_haute AS haus
FROM temps T1, temps T2
WHERE T1.t_basse < T2.t_basse
AND T1.t_haute > T2.t_haute;
ville
| bas | haut |
ville
| bas | haut
----------------+-----+------+---------------+-----+-----San Francisco | 43 |
57 | San Francisco | 46 |
50
Hayward
| 37 |
54 | San Francisco | 46 |
50
(2 rows)
Dans cet exemple, nous avons renomm la table temps en T1 et en T2 pour tre capable de distinguer respectivement le ct
gauche et droit de la jointure. Vous pouvez aussi utiliser ce genre d'alias dans d'autres requtes pour conomiser de la frappe,
c'est--dire :
SELECT *
FROM temps t, villes v
WHERE t.ville = v.nom;
Vous rencontrerez ce genre d'abrviation assez frquemment.

2.7. Fonctions d'agrgat


Comme la plupart des autres produits de bases de donnes relationnelles, PostgreSQL supporte les fonctions d'agrgat. Une
fonction d'agrgat calcule un seul rsultat partir de plusieurs lignes en entre. Par exemple, il y a des agrgats pour calculer le
nombre (count), la somme (sum), la moyenne (avg), le maximum (max) et le minimum (min) d'un ensemble de lignes.
Comme exemple, nous pouvons trouver la temprature la plus haute parmi les tempratures basses avec :
SELECT max(t_basse) FROM temps;
max
----46
(1 row)
Si nous voulons connatre dans quelle ville (ou villes) ces lectures se sont produites, nous pouvons essayer :
SELECT ville FROM temps WHERE t_basse = max(t_basse);
9

Le langage SQL

FAUX
mais cela ne marchera pas puisque l'agrgat max ne peut pas tre utilis dans une clause WHERE (cette restriction existe parce que
la clause WHERE dtermine les lignes qui seront traites par l'agrgat ; donc les lignes doivent tre values avant que les fonctions
d'agrgat ne calculent leur rsultat). Cependant, comme cela est souvent le cas, la requte peut tre rpte pour arriver au rsultat
attendu, ici en utilisant une sous-requte :
SELECT ville FROM temps
WHERE t_basse = (SELECT max(t_basse) FROM temps);
ville
--------------San Francisco
(1 row)
Ceci est correct car la sous-requte est un calcul indpendant qui traite son propre agrgat sparment partir de ce qui se passe
dans la requte externe.
Les agrgats sont galement trs utiles s'ils sont combins avec les clauses GROUP BY. Par exemple, nous pouvons obtenir la
temprature la plus haute parmi les tempratures basses observes dans chaque ville avec :
SELECT ville, max(t_basse)
FROM temps
GROUP BY ville;
ville
| max
---------------+----Hayward
| 37
San Francisco | 46
(2 rows)
ce qui nous donne une ligne par ville dans le rsultat. Chaque rsultat d'agrgat est calcul avec les lignes de la table correspondant la ville. Nous pouvons filtrer ces lignes groupes en utilisant HAVING :
SELECT ville, max(t_basse)
FROM temps
GROUP BY ville
HAVING max(t_basse) < 40;
ville | max
---------+----Hayward | 37
(1 row)
ce qui nous donne le mme rsultat uniquement pour les villes qui ont toutes leurs valeurs de t_basse en-dessous de 40. Pour finir, si nous nous proccupons seulement des villes dont le nom commence par S , nous pouvons faire :
SELECT ville, max(t_basse)
FROM temps
WHERE ville LIKE 'S%'
GROUP BY ville
HAVING max(t_basse) < 40;
L'oprateur LIKE fait la correspondance avec un motif ; cela est expliqu dans la Section 9.7, Correspondance de motif .
Il est important de comprendre l'interaction entre les agrgats et les clauses SQL WHERE et HAVING. La diffrence fondamentale
entre WHERE et HAVING est que WHERE slectionne les lignes en entre avant que les groupes et les agrgats ne soient traits
(donc, cette clause contrle les lignes qui se retrouvent dans le calcul de l'agrgat) tandis que HAVING slectionne les lignes groupes aprs que les groupes et les agrgats aient t traits. Donc, la clause WHERE ne doit pas contenir de fonctions d'agrgat ; cela
n'a aucun sens d'essayer d'utiliser un agrgat pour dterminer les lignes en entre des agrgats. D'un autre ct, la clause HAVING
contient toujours des fonctions d'agrgat (pour tre prcis, vous tes autoriss crire une clause HAVING qui n'utilise pas
d'agrgats mais c'est rarement utilis. La mme condition pourra tre utilise plus efficacement par un WHERE).
Dans l'exemple prcdent, nous pouvons appliquer la restriction sur le nom de la ville dans la clause WHERE puisque cela ne ncessite aucun agrgat. C'est plus efficace que d'ajouter la restriction dans HAVING parce que nous vitons le groupement et les calculs d'agrgat pour toutes les lignes qui ont chou lors du contrle fait par WHERE.

2.8. Mises jour


10

Le langage SQL

Vous pouvez mettre jour une ligne existante en utilisant la commande UPDATE. Supposez que vous dcouvrez que les tempratures sont toutes excdentes de deux degrs aprs le 28 novembre. Vous pouvez corriger les donnes de la faon suivante :
UPDATE temps
SET t_haute = t_haute - 2,
WHERE date > '1994-11-28';

t_basse = t_basse - 2

Regardez le nouvel tat des donnes :


SELECT * FROM temps;
ville
| t_basse | t_haute | prcp |
date
----------------+---------+---------+------+-----------San Francisco |
46 |
50 | 0.25 | 1994-11-27
San Francisco |
41 |
55 |
0 | 1994-11-29
Hayward
|
35 |
52 |
| 1994-11-29
(3 rows)

2.9. Suppressions
Les lignes peuvent tre supprimes de la table avec la commande DELETE. Supposez que vous n'tes plus intress par le temps
de Hayward. Vous pouvez faire ce qui suit pour supprimer ses lignes de la table :
DELETE FROM temps WHERE ville = 'Hayward';
Toutes les entres de temps pour Hayward sont supprimes.
SELECT * FROM temps;
ville
| t_basse | t_haute | prcp |
date
---------------+---------+---------+------+-----------San Francisco |
46 |
50 | 0.25 | 1994-11-27
San Francisco |
41 |
55 |
0 | 1994-11-29
(2 rows)
Faire trs attention aux instructions de la forme
DELETE FROM nom_table;
Sans une qualification, DELETE supprimera toutes les lignes de la table donne, la laissant vide. Le systme le fera sans demander de confirmation !

11

Chapitre 3. Fonctionnalits avances


3.1. Introduction
Le chapitre prcdent couvre les bases de l'utilisation de SQL pour le stockage et l'accs aux donnes avec PostgreSQL. Il est
temps d'aborder quelques fonctionnalits avances du SQL qui simplifient la gestion et empchent la perte ou la corruption des
donnes. Quelques extensions de PostgreSQL sont galement abordes.
Ce chapitre fait occasionnellement rfrence aux exemples disponibles dans le Chapitre 2, Le langage SQL pour les modifier ou
les amliorer. Il est donc prfrable d'avoir lu ce chapitre. Quelques exemples de ce chapitre sont galement disponibles dans
advanced.sql situ dans le rpertoire du tutoriel. De plus, ce fichier contient quelques donnes charger pour utiliser
l'exemple. Cela n'est pas repris ici (on peut se rfrer la Section 2.1, Introduction pour savoir comment utiliser ce fichier).

3.2. Vues
Se rfrer aux requtes de la Section 2.6, Jointures entre les tables . Si la liste des enregistrements du temps et des villes est
d'un intrt particulier pour l'application considre mais qu'il devient contraignant de saisir la requte chaque utilisation, il est
possible de crer une vue avec la requte. De ce fait, la requte est nomme et il peut y tre fait rfrence de la mme faon qu'il
est fait rfrence une table :
CREATE VIEW ma_vue AS
SELECT ville, t_basse, t_haute, prcp, date, emplacement
FROM temps, villes
WHERE ville = nom;
SELECT * FROM ma_vue;
L'utilisation des vues est un aspect cl d'une bonne conception des bases de donnes SQL. Les vues permettent d'encapsuler les
dtails de la structure des tables. Celle-ci peut alors changer avec l'volution de l'application, tandis que l'interface reste
constante.
Les vues peuvent tre utilises dans quasiment toutes les situations o une vraie table est utilisable. De plus, il n'est pas inhabituel de construire des vues reposant sur d'autres vues.

3.3. Cls trangres


Soient les tables temps et villes dfinies dans le Chapitre 2, Le langage SQL. Il s'agit maintenant de s'assurer que personne
n'insre de ligne dans la table temps qui ne corresponde une entre dans la table villes. On appelle cela maintenir l'intgrit rfrentielle des donnes. Dans les systmes de bases de donnes simplistes, lorsqu'au moins c'est possible, cela est parfois
obtenu par la vrification pralable de l'existence d'un enregistrement correspondant dans la table villes, puis par l'insertion,
ou l'interdiction, du nouvel enregistrement dans temps. Puisque cette approche, peu pratique, prsente un certain nombre
d'inconvnients, PostgreSQL peut se charger du maintien de l'intgrit rfrentielle.
La nouvelle dclaration des tables ressemble alors ceci :
CREATE TABLE villes (
ville
varchar(80) primary key,
emplacement point
);
CREATE TABLE temps (
ville
varchar(80) references villes,
t_haute int,
t_basse int,
prcp
real,
date
date
);
Lors d'une tentative d'insertion d'enregistrement non valide :
INSERT INTO temps VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28');
ERROR: insert or update on table "temps" violates foreign key constraint
"temps_ville_fkey"
DETAIL : Key (ville)=(a) is not present in table "villes".

12

Fonctionnalits avances

Le comportement des cls trangres peut tre adapt trs finement une application particulire. Ce tutoriel ne va pas plus loin
que cet exemple simple. De plus amples informations sont accessibles dans le Chapitre 5, Dfinition des donnes. Une utilisation
efficace des cls trangres amliore la qualit des applications accdant aux bases de donnes. Il est donc fortement conseill
d'apprendre les utiliser.

3.4. Transactions
Les transactions sont un concept fondamental de tous les systmes de bases de donnes. Une transaction assemble plusieurs
tapes en une seule opration tout-ou-rien. Les tats intermdiaires entre les tapes ne sont pas visibles par les transactions concurrentes. De plus, si un chec survient qui empche le succs de la transaction, alors aucune des tapes n'affecte la base de donnes.
Si l'on considre, par exemple, la base de donnes d'une banque qui contient le solde de diffrents comptes clients et le solde total
des dpts par branches et que l'on veuille enregistrer un virement de 100 euros du compte d'Alice vers celui de Bob, les commandes SQL peuvent ressembler cela (aprs simplification) :
UPDATE comptes SET balance = balance - 100.00
WHERE nom = 'Alice';
UPDATE branches SET balance = balance - 100.00
WHERE nom = (SELECT nom_branche FROM comptes WHERE nom = 'Alice');
UPDATE comptes SET balance = balance + 100.00
WHERE nom = 'Bob';
UPDATE branches SET balance = balance + 100.00
WHERE nom = (SELECT nom_branche FROM comptes WHERE nom = 'Bob');
Ce ne sont pas les dtails des commandes qui importent ici ; le point important est la ncessit de plusieurs mises jour spares
pour accomplir cette opration assez simple. Les employs de la banque veulent tre assurs que, soit toutes les commandes sont
effectues, soit aucune ne l'est. Il n'est pas envisageable que, suite une erreur du systme, Bob reoive 100 euros qui n'ont pas t
dbits du compte d'Alice. De la mme faon, Alice ne restera pas longtemps une cliente fidle si elle est dbite du montant sans
que celui-ci ne soit crdit sur le compte de Bob. Il est important de garantir que si quelque chose se passe mal, aucune des tapes
dj excutes n'est prise en compte. Le regroupement des mises jour au sein d'une transaction apporte cette garantie. Une transaction est dite atomique : du point de vue des autres transactions, elle passe compltement ou pas du tout.
Il est galement ncessaire de garantir qu'une fois la transaction termine et valide par la base de donnes, les transactions sont
enregistres dfinitivement et ne peuvent tre perdues, mme si une panne survient peu aprs. Ainsi, si un retrait d'argent est effectu par Bob, il ne faut absolument pas que le dbit de son compte disparaisse suite une panne survenant juste aprs son dpart de
la banque. Une base de donnes transactionnelle garantit que toutes les mises jour faites lors d'une transaction sont stockes de
manire persistante (c'est--dire sur disque) avant que la transaction ne soit dclare valide.
Une autre proprit importante des bases de donnes transactionnelles est en relation troite avec la notion de mises jour atomiques : quand plusieurs transactions sont lances en parallle, aucune d'entre elles ne doit tre capable de voir les modifications
incompltes effectues par les autres. Ainsi, si une transaction calcule le total de toutes les branches, inclure le dbit de la branche
d'Alice sans le crdit de la branche de Bob, ou vice-versa, est une vritable erreur. Les transactions doivent donc tre tout-ou-rien,
non seulement pour leur effet persistant sur la base de donnes, mais aussi pour leur visibilit au moment de leur excution. Les
mises jour faites jusque-l par une transaction ouverte sont invisibles aux autres transactions jusqu' la fin de celle-ci. ce moment, toutes les mises jours deviennent simultanment visibles.
Sous PostgreSQL, une transaction est dclare en entourant les commandes SQL de la transaction par les commandes BEGIN
et COMMIT. La transaction bancaire ressemble alors ceci :
BEGIN;
UPDATE comptes SET balance = balance - 100.00
WHERE nom = 'Alice';
-- etc etc
COMMIT;
Si, au cours de la transaction, il est dcid de ne pas valider (peut-tre la banque s'aperoit-elle que la balance d'Alice passe en ngatif), la commande ROLLBACK peut tre utilise la place de COMMIT. Toutes les mises jour ralises jusque-l sont alors
annules.
En fait, PostgreSQL traite chaque instruction SQL comme si elle tait excute dans une transaction. En l'absence de commande
BEGIN explicite, chaque instruction individuelle se trouve implicitement entoure d'un BEGIN et (en cas de succs) d'un COMMIT. Un groupe d'instructions entoures par BEGIN et COMMIT est parfois appel bloc transactionnel.

Note
Quelques bibliothques clientes lancent les commandes BEGIN et COMMIT automatiquement. L'utilisateur bn13

Fonctionnalits avances

ficie alors des effets des blocs transactionnels sans les demander. Vrifiez la documentation de l'interface que vous
utilisez.
Il est possible d'augmenter la granularit du contrle des instructions au sein d'une transaction en utilisant des points de retournement (savepoint). Ceux-ci permettent d'annuler des parties de la transaction tout en validant le reste. Aprs avoir dfini un point de
retournement l'aide de SAVEPOINT, les instructions excutes depuis ce point peuvent, au besoin, tre annules avec ROLLBACK TO. Toutes les modifications de la base de donnes effectues par la transaction entre le moment o le point de retournement a t dfini et celui o l'annulation est demande sont annules mais les modifications antrieures ce point sont conserves.
Le retour un point de retournement ne l'annule pas. Il reste dfini et peut donc tre utilis plusieurs fois. l'inverse, lorsqu'il
n'est plus ncessaire de revenir un point de retournement particulier, il peut tre relch, ce qui permet de librer des ressources
systmes. Il faut savoir toutefois que relcher un point de retournement ou y revenir relche tous les points de retournement qui
ont t dfinis aprs.
Tout ceci survient l'intrieur du bloc de transaction, et n'est donc pas visible par les autres sessions en cours sur la base de donnes. Si le bloc est valid, et ce moment-l seulement, toutes les actions valides deviennent immdiatement visibles par les
autres sessions, tandis que les actions annules ne le seront jamais.
Reconsidrant la base de donnes de la banque, on peut supposer vouloir dbiter le compte d'Alice de $100.00, somme crditer
sur le compte de Bob, mais considrer plus tard que c'est le compte de Wally qu'il convient de crditer. l'aide des points de retournement, cela peut se drouler ainsi :
BEGIN;
UPDATE comptes SET balance = balance
WHERE nom = 'Alice';
SAVEPOINT mon_pointdesauvegarde;
UPDATE comptes SET balance = balance
WHERE nom = 'Bob';
-- oups ... oublions a et crditons
ROLLBACK TO mon_pointdesauvegarde;
UPDATE comptes SET balance = balance
WHERE nom = 'Wally';
COMMIT;

- 100.00
+ 100.00
le compte de Wally
+ 100.00

Cet exemple est bien sr trs simplifi mais de nombreux contrles sont ralisables au sein d'un bloc de transaction grce
l'utilisation des points de retournement. Qui plus est, ROLLBACK TO est le seul moyen de regagner le contrle d'un bloc de
transaction plac dans un tat d'annulation par le systme du fait d'une erreur. C'est plus rapide que de tout annuler pour tout recommencer.

3.5. Fonctions de fentrage


Une fonction de fentrage effectue un calcul sur un jeu d'enregistrements lis d'une certaine faon l'enregistrement courant. On
peut les rapprocher des calculs ralisables par une fonction d'agrgat mais, contrairement une fonction d'agrgat, l'utilisation
d'une fonction de fentrage (de fentrage) n'entrane pas le regroupement des enregistrements traits en un seul. Chaque enregistrement garde son identit propre. En coulisse, la fonction de fentrage est capable d'accder d'autres enregistrements que
l'enregistrement courant du rsultat de la requte.
Voici un exemple permettant de comparer le salaire d'un employ avec le salaire moyen de sa division :
SELECT nomdep, noemp, salaire, avg(salaire) OVER (PARTITION BY nomdep) FROM salaireemp;
nomdep
| noemp | salaire |
avg
-----------+-------+---------+----------------------develop
|
11 |
5200 | 5020.0000000000000000
develop
|
7 |
4200 | 5020.0000000000000000
develop
|
9 |
4500 | 5020.0000000000000000
develop
|
8 |
6000 | 5020.0000000000000000
develop
|
10 |
5200 | 5020.0000000000000000
personnel |
5 |
3500 | 3700.0000000000000000
personnel |
2 |
3900 | 3700.0000000000000000
ventes
|
3 |
4800 | 4866.6666666666666667
ventes
|
1 |
5000 | 4866.6666666666666667
ventes
|
4 |
4800 | 4866.6666666666666667
(10 rows)
Les trois premires colonnes viennent directement de la table salaireemp, et il y a une ligne de sortie pour chaque ligne de la table.
14

Fonctionnalits avances

La quatrime colonne reprsente une moyenne calcule sur tous les enregistrements de la table qui ont la mme valeur de nomdep que la ligne courante. (Il s'agit effectivement de la mme fonction que la fonction d'agrgat classique avg, mais la clause
OVER entrane son excution en tant que fonction de fentrage et son calcul sur le jeu appropri d'enregistrements.)
Un appel une fonction de fentrage contient toujours une clause OVER qui suit immdiatement le nom et les arguments de la
fonction. C'est ce qui permet de la distinguer syntaxiquement d'une fonction simple ou d'une fonction d'agrgat. La clause OVER
dtermine prcisment comment les lignes de la requte sont clates pour tre traites par la fonction de fentrage. La liste PARTITION BY contenue dans la clause OVER spcifie la rpartition des enregistrements en groupes, ou partitions, qui partagent les
mmes valeurs pour la (les) expression(s) contenue(s) dans la clause PARTITION BY. Pour chaque enregistrement, la fonction
de fentrage est calcule sur les enregistrements qui se retrouvent dans la mme partition que l'enregistrement courant.
Vous pouvez aussi contrler l'ordre dans lequel les lignes sont traites par les fonctions de fentrage en utilisant la clause ORDER
BY l'intrieur de la clause OVER (la partition traite par le ORDER BY n'a de plus pas besoin de correspondre l'ordre dans lequel les lignes seront affiches). Voici un exemple :
SELECT nomdep, noemp, salaire, rank() OVER (PARTITION BY nomdep ORDER BY salaire DESC)
FROM salaireemp;
nomdep
| noemp | salaire| rank
-----------+-------+--------+-----develop
|
8 |
6000 |
1
develop
|
10 |
5200 |
2
develop
|
11 |
5200 |
2
develop
|
9 |
4500 |
4
develop
|
7 |
4200 |
5
personnel |
2 |
3900 |
1
personnel |
5 |
3500 |
2
ventes
|
1 |
5000 |
1
ventes
|
4 |
4800 |
2
ventes
|
3 |
4800 |
2
(10 rows)
On remarque que la fonction rank produit un rang numrique dans la partition de l'enregistrement pour chaque valeur diffrente
de l'ORDER BY, dans l'ordre dfini par la clause ORDER BY. rank n'a pas besoin de paramtre explicite, puisque son comportement est entirement dtermin par la clause OVER.
Les lignes prises en compte par une fonction de fentrage sont celles de la table virtuelle produite par la clause FROM de la requte
filtre par ses clauses WHERE, GROUP BY et HAVING, s'il y en a. Par exemple, une ligne rejete parce qu'elle ne satisfait pas la
condition WHERE n'est vue par aucune fonction de fentrage. Une requte peut contenir plusieurs de ces fonctions de fentrage qui
dcoupent les donnes de faons diffrentes, par le biais de clauses OVER diffrentes, mais elles travaillent toutes sur le mme jeu
d'enregistrements, dfini par cette table virtuelle.
ORDER BY peut tre omis lorsque l'ordre des enregistrements est sans importance. Il est aussi possible d'omettre PARTITION
BY, auquel cas il n'y a qu'une seule partition, contenant tous les enregistrements.
Il y a un autre concept important associ aux fonctions de fentrage : pour chaque enregistrement, il existe un jeu
d'enregistrements dans sa partition appel son window frame (cadre de fentre). Beaucoup de fonctions de fentrage, mais pas
toutes, travaillent uniquement sur les enregistrements du window frame, plutt que sur l'ensemble de la partition. Par dfaut, si on
a prcis une clause ORDER BY, la window frame contient tous les enregistrements du dbut de la partition jusqu'
l'enregistrement courant, ainsi que tous les enregistrements suivants qui sont gaux l'enregistrement courant au sens de la clause
ORDER BY. Quand ORDER BY est omis, la window frame par dfaut contient tous les enregistrements de la partition. 1 Voici un
exemple utilisant sum :
SELECT salaire, sum(salaire) OVER () FROM salaireemp;
salaire| sum
--------+------5200 | 47100
5000 | 47100
3500 | 47100
4800 | 47100
3900 | 47100
4200 | 47100
4500 | 47100
1

Il existe des options pour dfinir la window frame autrement, mais ce tutoriel ne les prsente pas. Voir la Section 4.2.8, Appels de fonction de fentrage pour les dtails.

15

Fonctionnalits avances

4800 | 47100
6000 | 47100
5200 | 47100
(10 rows)
Dans l'exemple ci-dessus, puisqu'il n'y a pas d'ORDER BY dans la clause OVER, la window frame est gale la partition ; en
d'autres termes, chaque somme est calcule sur toute la table, ce qui fait qu'on a le mme rsultat pour chaque ligne du rsultat.
Mais si on ajoute une clause ORDER BY, on a un rsultat trs diffrent :
SELECT salaire, sum(salaire) OVER (ORDER BY salaire) FROM salaireemp;
salaire| sum
--------+------3500 | 3500
3900 | 7400
4200 | 11600
4500 | 16100
4800 | 25700
4800 | 25700
5000 | 30700
5200 | 41100
5200 | 41100
6000 | 47100
(10 rows)
Ici, sum est calcul partir du premier salaire (c'est--dire le plus bas) jusqu'au salaire courant, en incluant tous les doublons du
salaire courant (remarquez les valeurs pour les salaires identiques).
Les fonctions window ne sont autorises que dans la liste SELECT et la clause ORDER BY de la requte. Elles sont interdites
ailleurs, comme par exemple dans les clauses GROUP BY,HAVING et WHERE. La raison en est qu'elles sont excutes aprs le
traitement de ces clauses. Par ailleurs, les fonctions de fentrage s'excutent aprs les fonctions d'agrgat classiques. Cela signifie
qu'il est permis d'inclure une fonction d'agrgat dans les arguments d'une fonction de fentrage, mais pas l'inverse.
S'il y a besoin de filtrer ou de grouper les enregistrements aprs le calcul des fonctions de fentrage, une sous-requte peut tre utilise. Par exemple :
SELECT nomdep, noemp, salaire, date_embauche
FROM
(SELECT nomdep, noemp, salaire, date_embauche,
rank() OVER (PARTITION BY nomdep ORDER BY salaire DESC, noemp) AS pos
FROM salaireemp
) AS ss
WHERE pos < 3;
La requte ci-dessus n'affiche que les enregistrements de la requte interne ayant un rang infrieur 3.
Quand une requte met en jeu plusieurs fonctions de fentrage, il est possible d'crire chacune avec une clause OVER diffrente,
mais cela entrane des duplications de code et augmente les risques d'erreurs si on souhaite le mme comportement pour plusieurs
fonctions de fentrage. la place, chaque comportement de fentrage peut tre associ un nom dans une clause WINDOW et ensuite tre rfrenc dans OVER. Par exemple :
SELECT sum(salaire) OVER w, avg(salaire) OVER w
FROM salaireemp
WINDOW w AS (PARTITION BY nomdep ORDER BY salaire DESC);
Plus de dtails sur les fonctions de fentrage sont disponibles dans la Section 4.2.8, Appels de fonction de fentrage , la Section 9.19, Fonctions Window , la Section 7.2.4, Traitement de fonctions Window et la page de rfrence SELECT(7).

3.6. Hritage
L'hritage est un concept issu des bases de donnes orientes objet. Il ouvre de nouvelles possibilits intressantes en conception
de bases de donnes.
Soient deux tables : une table villes et une table capitales. Les capitales tant galement des villes, il est intressant d'avoir
la possibilit d'afficher implicitement les capitales lorsque les villes sont listes. Un utilisateur particulirement brillant peut crire
16

Fonctionnalits avances

ceci
CREATE TABLE
nom
population
altitude
etat
);

capitales (
text,
real,
int,
-- (en pied)
char(2)

CREATE TABLE
nom
population
altitude
);

non_capitales (
text,
real,
int
-- (en pied)

CREATE VIEW villes AS


SELECT nom, population, altitude FROM capitales
UNION
SELECT nom, population, altitude FROM non_capitales;
Cela fonctionne bien pour les requtes, mais la mise jour d'une mme donne sur plusieurs lignes devient vite un horrible cassette.
Une meilleure solution peut tre :
CREATE TABLE
nom
population
altitude
);

villes (
text,
real,
int
-- (en pied)

CREATE TABLE capitales (


etat
char(2)
) INHERITS (villes);
Dans ce cas, une ligne de capitales hrite de toutes les colonnes (nom, population et altitude) de son parent,
villes. Le type de la colonne nom est text, un type natif de PostgreSQL pour les chanes de caractres longueur variable.
Les capitales d'tat ont une colonne supplmentaire, etat, qui affiche l'tat dont elles sont la capitale. Sous PostgreSQL, une
table peut hriter de zro plusieurs autres tables.
La requte qui suit fournit un exemple d'extraction des noms de toutes les villes, en incluant les capitales des tats, situes une
altitude de plus de 500 pieds :
SELECT nom, altitude
FROM villes
WHERE altitude > 500;
ce qui renvoie :
nom
| altitude
-----------+---------Las Vegas |
2174
Mariposa |
1953
Madison
|
845
(3 rows)
l'inverse, la requte qui suit rcupre toutes les villes qui ne sont pas des capitales et qui sont situes une altitude d'au moins
500 pieds :
SELECT nom, altitude
FROM ONLY villes
WHERE altitude > 500;
nom
| altitude
-----------+---------Las Vegas |
2174
Mariposa |
1953
(2 rows)
Ici, ONLY avant villes indique que la requte ne doit tre excute que sur la table villes, et non pas sur les tables en dessous de villes dans la hirarchie des hritages. La plupart des commandes dj voques -- SELECT, UPDATE et DELETE 17

Fonctionnalits avances

- supportent cette notation (ONLY).

Note
Bien que l'hritage soit frquemment utile, il n'a pas t intgr avec les contraintes d'unicit et les cls trangres,
ce qui limite son utilit. Voir la Section 5.8, L'hritage pour plus de dtails.

3.7. Conclusion
PostgreSQL dispose d'autres fonctionnalits non dcrites dans ce tutoriel d'introduction orient vers les nouveaux utilisateurs de
SQL. Ces fonctionnalits sont discutes plus en dtails dans le reste de ce livre.
Si une introduction plus approfondie est ncessaire, le lecteur peut visiter le site web de PostgreSQL qui fournit des liens vers
d'autres ressources.

18

Partie II. Langage SQL


Cette partie prsente l'utilisation du langage SQL au sein de PostgreSQL. La syntaxe gnrale de SQL y est explique, ainsi que
la cration des structures de stockage des donnes, le peuplement de la base et son interrogation. La partie centrale liste les types
de donnes et les fonctions disponibles ainsi que leur utilisation dans les requtes SQL. Le reste traite de l'optimisation de la base
de donnes en vue d'obtenir des performances idales.
L'information dans cette partie est prsente pour qu'un utilisateur novice puisse la suivre du dbut la fin et obtenir ainsi une
comprhension complte des sujets sans avoir effectuer de frquents sauts entre les chapitres. Les chapitres sont indpendants.
Un utilisateur plus expriment pourra, donc, ne consulter que les chapitres l'intressant. L'information est prsente dans un style
narratif par unit thmatique. Les lecteurs qui cherchent une description complte d'une commande particulire peuvent se rfrer
la Partie VI, Rfrence .
Pour profiter pleinement de cette partie, il est ncessaire de savoir se connecter une base PostgreSQL et d'y excuter des commandes SQL. Les lecteurs qui ne sont pas familiers avec ces prrequis sont encourags lire pralablement la Partie I,
Tutoriel .
Les commandes SQL sont gnralement saisies partir du terminal interactif de PostgreSQL, psql. D'autres programmes possdant des fonctionnalits similaires peuvent galement tre utiliss.

Chapitre 4. Syntaxe SQL


Ce chapitre dcrit la syntaxe de SQL. Il donne les fondements pour comprendre les chapitres suivants qui iront plus en dtail sur
la faon dont les commandes SQL sont appliques pour dfinir et modifier des donnes.
Nous avertissons aussi nos utilisateurs, dj familiers avec le SQL, qu'ils doivent lire ce chapitre trs attentivement car il existe
plusieurs rgles et concepts implments diffremment suivant les bases de donnes SQL ou spcifiques PostgreSQL.

4.1. Structure lexicale


Une entre SQL consiste en une squence de commandes. Une commande est compose d'une squence de jetons, termins par
un point-virgule ( ; ). La fin du flux en entre termine aussi une commande. Les jetons valides dpendent de la syntaxe particulire de la commande.
Un jeton peut tre un mot cl, un identificateur, un identificateur entre guillemets, une constante ou un symbole de caractre
spcial. Les jetons sont normalement spars par des espaces blancs (espace, tabulation, nouvelle ligne) mais n'ont pas besoin de
l'tre s'il n'y a pas d'ambigut (ce qui est seulement le cas si un caractre spcial est adjacent des jetons d'autres types).
Par exemple, ce qui suit est (syntaxiquement) valide pour une entre SQL :
SELECT * FROM MA_TABLE;
UPDATE MA_TABLE SET A = 5;
INSERT INTO MA_TABLE VALUES (3, 'salut ici');
C'est une squence de trois commandes, une par ligne (bien que cela ne soit pas requis ; plusieurs commandes peuvent se trouver sur une mme ligne et une commande peut se rpartir sur plusieurs lignes).
De plus, des commentaires peuvent se trouver dans l'entre SQL. Ce ne sont pas des jetons, ils sont rellement quivalents un
espace blanc.
La syntaxe SQL n'est pas trs cohrente en ce qui concerne les jetons identificateurs des commandes et lesquels sont des oprandes ou des paramtres. Les premiers jetons sont gnralement le nom de la commande. Dans l'exemple ci-dessus, nous parlons d'une commande SELECT , d'une commande UPDATE et d'une commande INSERT . Mais en fait, la commande
UPDATE requiert toujours un jeton SET apparaissant une certaine position, et cette variante particulire de INSERT requiert
aussi un VALUES pour tre complte. Les rgles prcises de syntaxe pour chaque commande sont dcrites dans la Partie VI,
Rfrence .

4.1.1. identificateurs et mots cls


Les jetons tels que SELECT, UPDATE ou VALUES dans l'exemple ci-dessus sont des exemples de mots cls, c'est--dire des
mots qui ont une signification dans le langage SQL. Les jetons MA_TABLE et A sont des exemples d'identificateurs. Ils identifient des noms de tables, colonnes ou d'autres objets de la base de donnes suivant la commande qui a t utilise. Du coup, ils
sont quelques fois simplement nomms des noms . Les mots cls et les identificateurs ont la mme structure lexicale, signifiant que quelqu'un ne peut pas savoir si un jeton est un identificateur ou un mot cl sans connatre le langage. Une liste complte des mots cl est disponible dans l'Annexe C, Mots-cl SQL.
Les identificateurs et les mots cls SQL doivent commencer avec une lettre (a-z, mais aussi des lettres de marques diacritiques
diffrentes et des lettres non latines) ou un tiret bas (_). Les caractres suivants dans un identificateur ou dans un mot cl
peuvent tre des lettres, des tirets-bas, des chiffres (0-9) ou des signes dollar ($). Notez que les signes dollar ne sont pas autoriss en tant qu'identificateur d'aprs le standard SQL, donc leur utilisation pourrait rendre les applications moins portables. Le
standard SQL ne dfinira pas un mot cl contenant des chiffres ou commenant ou finissant par un tiret bas, donc les identificateurs de cette forme sont sr de ne pas entrer en conflit avec les futures extensions du standard.
Le systme utilise au plus NAMEDATALEN-1 octets d'un identificateur ; les noms longs peuvent tre crits dans des commandes mais ils seront tronqus. Par dfaut, NAMEDATALEN vaut 64. Du coup, la taille maximum de l'identificateur est de 63
octets. Si cette limite est problmatique, elle peut tre leve en modifiant NAMEDATALEN dans src/include/pg_config_manual.h.
Les mots cls et les identificateurs sans guillemets doubles sont insensibles la casse. Du coup :
UPDATE MA_TABLE SET A = 5;
peut aussi s'crire de cette faon :
uPDaTE ma_TabLE SeT a = 5;
Une convention couramment utilise revient crire les mots cls en majuscule et les noms en minuscule, c'est--dire :
UPDATE ma_table SET a = 5;
20

Syntaxe SQL

Voici un deuxime type d'identificateur : l'identificateur dlimit ou l'identificateur entre guillemets. Il est form en englobant une
squence arbitraire de caractres entre des guillemets doubles ("). Un identificateur dlimit est toujours un identificateur, jamais
un mot cl. Donc, "select" pourrait tre utilis pour faire rfrence une colonne ou une table nomme select , alors
qu'un select sans guillemets sera pris pour un mot cl et du coup, pourrait provoquer une erreur d'analyse lorsqu'il est utilis
alors qu'un nom de table ou de colonne est attendu. L'exemple peut tre crit avec des identificateurs entre guillemets comme ceci :
UPDATE "ma_table" SET "a" = 5;
Les identificateurs entre guillemets peuvent contenir tout caractre autre que celui de code 0. (Pour inclure un guillemet double,
crivez deux guillemets doubles.) Ceci permet la construction de noms de tables et de colonnes qui ne seraient pas possible autrement, comme des noms contenant des espaces ou des arobases. La limitation de la longueur s'applique toujours.
Une variante des identificateurs entre guillemets permet d'inclure des caractres Unicode chapps en les identificateur par leur
point de code. Cette variante commence par U& (U en majuscule ou minuscule suivi par un et commercial ) immdiatement
suivi par un guillemet double d'ouverture, sans espace entre eux. Par exemple U&"foo". (Notez que c'est source d'ambigut avec
l'oprateur &. Utilisez les espaces autour de l'oprateur pour viter ce problme.) l'intrieur des guillemets, les caractres Unicode peuvent tre indiqus dans une forme chappe en crivant un antislash suivi par le code hexadcimal sur quatre chiffres ou,
autre possibilit, un antislash suivi du signe plus suivi d'un code hexadcimal sur six chiffres. Par exemple, l'identificateur "data" peut tre crit ainsi :
U&"d\0061t\+000061"
L'exemple suivant, moins trivial, crit le mot russe slon (lphant) en lettres cyrilliques :
U&"\0441\043B\043E\043D"
Si un caractre d'chappement autre que l'antislash est dsir, il peut tre indiqu en utilisant la clause UESCAPE aprs la chane.
Par exemple :
U&"d!0061t!+000061" UESCAPE '!'
La chane d'chappement peut tre tout caractre simple autre qu'un chiffre hexadcimal, le signe plus, un guillemet simple ou
double, ou un espace blanc. Notez que le caractre d'chappement est crit entre guillemets simples, pas entre guillemets doubles.
Pour inclure le caractre d'chappement dans l'identificateur sans interprtation, crivez-le deux fois.
La syntaxe d'chappement Unicode fonctionne seulement quand l'encodage serveur est UTF8. Quand d'autres encodages clients
sont utiliss, seuls les codes dans l'chelle ASCII (jusqu' \007F) peuvent tre utiliss. La forme sur quatre chiffres et la forme
sur six chiffres peuvent tre utilises pour indiquer des paires UTF-16 composant ainsi des caractres comprenant des points de
code plus grands que U+FFFF (et ce, bien que la disponibilit de la forme sur six chiffres ne le ncessite pas techniquement). (Les
paires de substitution ne sont pas stockes directement mais combines dans un point de code seul qui est ensuite encod en UTF8.)
Mettre un identificateur entre guillemets le rend sensible la casse alors que les noms sans guillemets sont toujours convertis en
minuscules. Par exemple, les identificateurs FOO, foo et "foo" sont considrs identiques par PostgreSQL mais "Foo" et
"FOO" sont diffrents des trois autres et entre eux. La mise en minuscule des noms sans guillemets avec PostgreSQL n'est pas
compatible avec le standard SQL qui indique que les noms sans guillemets devraient tre mis en majuscule. Du coup, foo devrait
tre quivalent "FOO" et non pas "foo" en respect avec le standard. Si vous voulez crire des applications portables, nous
vous conseillons de toujours mettre entre guillemets un nom particulier ou de ne jamais le mettre.

4.1.2. Constantes
Il existe trois types implicites de constantes dans PostgreSQL : les chanes, les chanes de bits et les nombres. Les constantes
peuvent aussi tre spcifies avec des types explicites, ce qui peut activer des reprsentations plus prcises et gres plus efficacement par le systme. Les constantes implicites sont dcrites ci-dessous ; ces constantes sont discutes dans les sous-sections suivantes.

4.1.2.1. Constantes de chanes


Une constante de type chane en SQL est une squence arbitraire de caractres entoure par des guillemets simples ('), par
exemple 'Ceci est une chane'. Pour inclure un guillemet simple dans une chane constante, saisissez deux guillemets
simples adjacents, par exemple 'Le cheval d''Anne'. Notez que ce n'est pas identique un guillemet double (").
Deux constantes de type chane spares par un espace blanc avec au moins une nouvelle ligne sont concatnes et traites relle21

Syntaxe SQL

ment comme si la chane avait t crite dans une constante. Par exemple :
SELECT 'foo'
'bar';
est quivalent :
SELECT 'foobar';
mais :
SELECT 'foo'

'bar';

n'a pas une syntaxe valide (ce comportement lgrement bizarre est spcifi par le standard SQL ; PostgreSQL suit le standard).

4.1.2.2. Constantes chane avec des chappements de style C


PostgreSQL accepte aussi les constantes de chane utilisant des chappements qui sont une extension au standard SQL. Une
constante de type chane d'chappement est indique en crivant la lettre E (en majuscule ou minuscule) juste avant le guillemet
d'ouverture, par exemple E'foo'. (Pour continuer une constante de ce type sur plusieurs lignes, crire E seulement avant le premier guillemet d'ouverture.) l'intrieur d'une chane d'chappement, un caractre antislash (\) est gr comme une squence
d'chappement avec antislash du langage C. La combinaison d'antislash et du (ou des) caractre(s) suivant reprsente une valeur
spciale, comme indiqu dans le Tableau 4.1, Squences d'chappements avec antislash .
Tableau 4.1. Squences d'chappements avec antislash

Squence d'chappement avec antislash

Interprtation

\b

suppression

\f

retour en dbut de ligne

\n

saut de ligne

\r

saut de ligne

\t

tabulation

\o, \oo, \ooo (o = 0 - 7)

valeur octale

\xh, \xhh (h = 0 - 9, A - F)

valeur hexadcimale

\uxxxx, \Uxxxxxxxx (x = 0 - 9, A - F)

caractre Unicode hexadcimal sur 16 ou 32 bits

Tout autre caractre suivi d'un antislash est pris littralement. Du coup, pour inclure un caractre antislash, crivez deux antislashs
(\\). De plus, un guillemet simple peut tre inclus dans une chane d'chappement en crivant \', en plus de la faon normale
''.
Il est de votre responsabilit que les squences d'octets que vous crez, tout spcialement lorsque vous utilisez les chappements
octaux et hexadcimaux, soient des caractres valides dans l'encodage du jeu de caractres du serveur. Quand l'encodage est UTF8, alors les chappements Unicode ou l'autre syntaxe d'chappement Unicode, expliqus dans la Section 4.1.2.3, Constantes de
chanes avec des chappements Unicode , devraient tre utiliss. (L'alternative serait de raliser l'encodage UTF-8 manuellement
et d'crire les octets, ce qui serait trs lourd.)
La syntaxe d'chappement Unicode fonctionne compltement mais seulement quand l'encodage du serveur est justement UTF8.
Lorsque d'autres encodages serveur sont utiliss, seuls les points de code dans l'chelle ASCII (jusqu' \u007F) peuvent tre utiliss. La forme sur quatre chiffres et la forme sur six chiffres peuvent tre utilises pour indiquer des paires UTF-16 composant
ainsi des caractres comprenant des points de code plus grands que U+FFFF et ce, bien que la disponibilit de la forme sur six
chiffres ne le ncessite pas techniquement. (Quand des paires de substitution sont utilises et que l'encodage du serveur est UTF8,
elles sont tout d'abord combines en un point code seul qui est ensuite encod en UTF-8.)

Attention
Si le paramtre de configuration standard_conforming_strings est dsactiv (off), alors PostgreSQL reconnat
les chappements antislashs dans les constantes traditionnelles de type chanes et celles chappes. Nanmoins,
partir de PostgreSQL 9.1, la valeur par dfaut est on, ce qui signifie que les chappements par antislash ne sont
reconnus que dans les constantes de chanes d'chappement. Ce comportement est plus proche du standard SQL
mais pourrait causer des problmes aux applications qui se basent sur le comportement historique o les chappements par antislash taient toujours reconnus. Pour contourner ce problme, vous pouvez configurer ce paramtre
off bien qu'il soit prfrable de ne plus utiliser les chappements par antislash. Si vous avez besoin d'un chappement par antislash pour reprsenter un caractre spcial, crivez la chane fixe avec un E.
22

Syntaxe SQL

En plus de standard_conforming_strings, les paramtres de configuration escape_string_warning et


backslash_quote imposent le traitement des antislashs dans les constantes de type chane.
Le caractre de code zro ne peut pas tre plac dans une constante de type chane.

4.1.2.3. Constantes de chanes avec des chappements Unicode


PostgreSQL supporte aussi un autre type de syntaxe d'chappement pour les chanes qui permettent d'indiquer des caractres
Unicode arbitraires par code. Une constante de chane d'chappement Unicode commence avec U& (U en majuscule ou minuscule
suivi par un et commercial ) immdiatement suivi par un guillemet double d'ouverture, sans espace entre eux. Par exemple
U&"foo". (Notez que c'est source d'ambigut avec l'oprateur &. Utilisez les espaces autour de l'oprateur pour viter ce problme.) l'intrieur des guillemets, les caractres Unicode peuvent tre indiqus dans une forme chappe en crivant un antislash suivi par le code hexadcimal sur quatre chiffres ou, autre possibilit, un antislash suivi du signe plus suivi d'un code hexadcimal sur six chiffres. Par exemple, l'identificateur 'data' peut tre crit ainsi :
U&'d\0061t\+000061'
L'exemple suivant, moins trivial, crit le mot russe slon (lphant) en lettres cyrilliques :
U&'\0441\043B\043E\043D'
Si un caractre d'chappement autre que l'antislash est souhait, il peut tre indiqu en utilisant la clause UESCAPE aprs la
chane. Par exemple :
U&'d!0061t!+000061' UESCAPE '!'
Le caractre d'chappement peut tre tout caractre simple autre qu'un chiffre hexadcimal, le signe plus, un guillement simple ou
double, ou un espace blanc.
La syntaxe d'chappement Unicode fonctionne seulement quand l'encodage du serveur est UTF8. Quand d'autres encodages de
serveur sont utiliss, seuls les codes dans l'chelle ASCII (jusqu' \007F) peuvent tre utiliss. La forme sur quatre chiffres et la
forme sur six chiffres peuvent tre utilises pour indiquer des paires de substitution UTF-16 composant ainsi des caractres comprenant des points de code plus grands que U+FFFF (et ce, bien que la disponibilit de la forme sur six chiffres ne le ncessite pas
techniquement). (Quand des paires de substitution sont utilises avec un encodage serveur UTF8, elles sont tout d'abord combines en un seul point de code, qui est ensuite encod en UTF-8.)
De plus, la syntaxe d'chappement de l'Unicode pour les constantes de chanes fonctionne seulement quand le paramtre de configuration standard_conforming_strings est activ. Dans le cas contraire, cette syntaxe est confuse pour les clients qui analysent les
instructions SQL au point que cela pourrait amener des injections SQL et des problmes de scurit similaires. Si le paramtre est
dsactiv, cette syntaxe sera rejete avec un message d'erreur.
Pour inclure le caractre d'chappement littralement dans la chane, crivez-le deux fois.

4.1.2.4. Constantes de chanes avec guillemet dollar


Alors que la syntaxe standard pour la spcification des constantes de chanes est gnralement agrable, elle peut tre difficile
comprendre quand la chane dsire contient un grand nombre de guillemets ou d'antislashs car chacun d'entre eux doit tre doubl. Pour permettre la saisie de requtes plus lisibles dans de telles situations, PostgreSQL fournit une autre faon, appele
guillemet dollar , pour crire des constantes de chanes. Une constante de chane avec guillemet dollar consiste en un signe dollar ($), une balise optionnelle de zro ou plus de caractres, un autre signe dollar, une squence arbitraire de caractres qui
constitue le contenu de la chane, un signe dollar, la mme balise et un signe dollar. Par exemple, voici deux faons de spcifier la
chane Le cheval d'Anne en utilisant les guillemets dollar :
$$Le cheval d'Anne$$
$UneBalise$Le cheval d'Anne$UneBalise$
Notez qu' l'intrieur de la chane avec guillemet dollar, les guillemets simples peuvent tre utiliss sans devoir tre chapps. En
fait, aucun caractre l'intrieur d'une chane avec guillemet dollar n'a besoin d'tre chapp : le contenu est toujours crit littralement. Les antislashs ne sont pas spciaux, pas plus que les signes dollar, sauf s'ils font partie d'une squence correspondant la
balise ouvrante.
Il est possible d'imbriquer les constantes de chanes avec guillemets dollar en utilisant diffrentes balises pour chaque niveau
d'imbrication. Ceci est habituellement utilis lors de l'criture de dfinition de fonctions. Par exemple :
$fonction$
BEGIN
23

Syntaxe SQL

RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);


END;
$fonction$
Dans cet exemple, la squence $q$[\t\r\n\v\\]$q$ reprsente une chane constante avec guillemet dollar
[\t\r\n\v\\], qui sera reconnue quand le corps de la fonction est excut par PostgreSQL. Mais comme la squence ne
correspond pas au dlimiteur $fonction$, il s'agit juste de quelques caractres l'intrieur de la constante pour ce qu'en sait la
chane externe.
La balise d'une chane avec guillemets dollar, si elle existe, suit les mmes rgles qu'un identificateur sans guillemets, sauf qu'il ne
peut pas contenir de signes dollar. Les balises sont sensibles la casse, du coup $balise$Contenu de la
chane$balise$ est correct mais $BALISE$Contenu de la chane$balise$ ne l'est pas.
Une chane avec guillemets dollar suivant un mot cl ou un identificateur doit en tre spar par un espace blanc ; sinon, le dlimiteur du guillemet dollar serait pris comme faisant parti de l'identificateur prcdent.
Le guillemet dollar ne fait pas partie du standard SQL mais c'est un moyen bien plus agrable pour crire des chanes constantes
que d'utiliser la syntaxe des guillemets simples, bien que compatible avec le standard. Elle est particulirement utile pour reprsenter des constantes de type chane l'intrieur d'autres constantes, comme cela est souvent le cas avec les dfinitions de fonctions. Avec la syntaxe des guillemets simples, chaque antislash dans l'exemple prcdent devrait avoir t crit avec quatre antislashs, ce qui sera rduit deux antislashs dans l'analyse de la constante originale, puis un lorsque la constante interne est analyse de nouveau lors de l'excution de la fonction.

4.1.2.5. Constantes de chanes de bits


Les constantes de chanes de bits ressemblent aux constantes de chanes standards avec un B (majuscule ou minuscule) juste avant
le guillemet du dbut (sans espace blanc), c'est--dire B'1001'. Les seuls caractres autoriss dans les constantes de type chane
de bits sont 0 et 1.
Les constantes de chanes de bits peuvent aussi tre spcifies en notation hexadcimale en utilisant un X avant (minuscule ou majuscule), c'est--dire X'1FF'. Cette notation est quivalente une constante de chane de bits avec quatre chiffres binaires pour
chaque chiffre hexadcimal.
Les deux formes de constantes de chanes de bits peuvent tre continues sur plusieurs lignes de la mme faon que les constantes
de chanes habituelles. Le guillemet dollar ne peut pas tre utilis dans une constante de chane de bits.

4.1.2.6. Constantes numriques


Les constantes numriques sont acceptes dans ces formes gnrales :
chiffres
chiffres.[chiffres][e[+-]chiffres]
[chiffres].chiffres[e[+-]chiffres]
chiffrese[+-]chiffres
o chiffres est un ou plusieurs chiffres dcimaux (de 0 9). Au moins un chiffre doit tre avant ou aprs le point dcimal, s'il
est utilis. Au moins un chiffre doit suivre l'indicateur d'exponentiel (e), s'il est prsent. Il ne peut pas y avoir d'espaces ou d'autres
caractres imbriqus dans la constante. Notez que tout signe plus ou moins en avant n'est pas considr comme faisant part de la
constante ; il est un oprateur appliqu la constante.
Voici quelques exemples de constantes numriques valides :
42
3.5
4.
.001
5e2
1.925e-3
Une constante numrique ne contenant ni un point dcimal ni un exposant est tout d'abord prsume du type integer si sa valeur
est contenue dans le type integer (32 bits) ; sinon, il est prsum de type bigint si sa valeur entre dans un type bigint (64 bits) ; sinon, il est pris pour un type numeric. Les constantes contenant des poins dcimaux et/ou des exposants sont toujours prsumes de
type numeric.
Le type de donnes affect initialement une constante numrique est seulement un point de dpart pour les algorithmes de rsolution de types. Dans la plupart des cas, la constante sera automatiquement convertie dans le type le plus appropri suivant le
contexte. Si ncessaire, vous pouvez forcer l'interprtation d'une valeur numrique sur un type de donnes spcifique en la convertissant. Par exemple, vous pouvez forcer une valeur numrique tre traite comme un type real (float4) en crivant :
24

Syntaxe SQL

REAL '1.23'
1.23::REAL

-- style chane
-- style PostgreSQL (historique)

Ce sont en fait des cas spciaux des notations de conversion gnrales discutes aprs.

4.1.2.7. Constantes d'autres types


Une constante de type arbitraire peut tre saisie en utilisant une des notations suivantes :
type 'chane'
'chane'::type
CAST ( 'chane' AS type )
Le texte de la chane constante est pass dans la routine de conversion pour le type appel type. Le rsultat est une constante du
type indiqu. La conversion explicite de type peut tre omise s'il n'y a pas d'ambigut sur le type de la constante (par exemple,
lorsqu'elle est affecte directement une colonne de la table), auquel cas elle est convertie automatiquement.
La constante chane peut tre crite en utilisant soit la notation SQL standard soit les guillemets dollar.
Il est aussi possible de spcifier une conversion de type en utilisant une syntaxe style fonction :
nom_type ( 'chane' )
mais tous les noms de type ne peuvent pas tre utiliss ainsi ; voir la Section 4.2.9, Conversions de type pour plus de dtails.
Les syntaxes ::, CAST() et d'appels de fonctions sont aussi utilisables pour spcifier les conversions de type l'excution
d'expressions arbitraires, comme discut dans la Section 4.2.9, Conversions de type . Pour viter une ambigut syntaxique, la
syntaxe type 'chane' peut seulement tre utilise pour spcifier le type d'une constante. Une autre restriction sur la syntaxe
type 'chane' est qu'il ne fonctionne pas pour les types de tableau ; utilisez :: ou CAST() pour spcifier le type d'une
constante de type tableau.
La syntaxe de CAST() est conforme au standard SQL. La syntaxe type 'chaine' est une gnralisation du standard : SQL
spcifie cette syntaxe uniquement pour quelques types de donnes mais PostgreSQL l'autorise pour tous les types. La syntaxe
:: est un usage historique dans PostgreSQL, comme l'est la syntaxe d'appel de fonction.

4.1.3. Oprateurs
Un nom d'oprateur est une squence d'au plus NAMEDATALEN-1 (63 par dfaut) caractres provenant de la liste suivante :
+-*/<>=~!@#%^&|`?
Nanmoins, il existe quelques restrictions sur les noms d'oprateurs :

-- et /* ne peuvent pas apparatre quelque part dans un nom d'oprateur car ils seront pris pour le dbut d'un commentaire.

Un nom d'oprateur plusieurs caractres ne peut pas finir avec + ou -, sauf si le nom contient aussi un de ces caractres :
~!@#%^&|`?
Par exemple, @- est un nom d'oprateur autoris mais *- ne l'est pas. Cette restriction permet PostgreSQL d'analyser des
requtes compatibles avec SQL sans requrir des espaces entre les jetons.

Lors d'un travail avec des noms d'oprateurs ne faisant pas partie du standard SQL, vous aurez habituellement besoin de sparer
les oprateurs adjacents avec des espaces pour viter toute ambigut. Par exemple, si vous avez dfini un oprateur unaire gauche
nomm @, vous ne pouvez pas crire X*@Y ; vous devez crire X* @Y pour vous assurer que PostgreSQL le lit comme deux
noms d'oprateurs, et non pas comme un seul.

4.1.4. Caractres spciaux


Quelques caractres non alphanumriques ont une signification spciale, diffrente de celui d'un oprateur. Les dtails sur leur utilisation sont disponibles l'endroit o l'lment de syntaxe respectif est dcrit. Cette section existe seulement pour avertir de leur
existence et pour rsumer le but de ces caractres.

Un signe dollar ($) suivi de chiffres est utilis pour reprsenter un paramtre de position dans le corps de la dfinition d'une
fonction ou d'une instruction prpare. Dans d'autres contextes, le signe dollar pourrait faire partie d'un identificateur ou d'une
constante de type chane utilisant le dollar comme guillemet.

Les parenthses (()) ont leur signification habituelle pour grouper leurs expressions et renforcer la prcdence. Dans certains
cas, les parenthses sont requises car faisant partie de la syntaxe d'une commande SQL particulire.

Les crochets ([]) sont utiliss pour slectionner les lments d'un tableau. Voir la Section 8.14, Tableaux pour plus
25

Syntaxe SQL

d'informations sur les tableaux.

Les virgules (,) sont utilises dans quelques constructions syntaxiques pour sparer les lments d'une liste.

Le point-virgule (;) termine une commande SQL. Il ne peut pas apparatre quelque part dans une commande, sauf l'intrieur
d'une constante de type chane ou d'un identificateur entre guillemets.

Le caractre deux points (:) est utilis pour slectionner des morceaux de tableaux (voir la Section 8.14, Tableaux ).
Dans certains dialectes SQL (tel que le SQL embarqu), il est utilis pour prfixer les noms de variables.

L'astrisque (*) est utilis dans certains contextes pour indiquer tous les champs de la ligne d'une table ou d'une valeur composite. Elle a aussi une signification spciale lorsqu'elle est utilise comme argument d'une fonction d'agrgat. Cela signifie que
l'agrgat ne requiert par de paramtre explicite.

Le point (.) est utilis dans les constantes numriques et pour sparer les noms de schma, table et colonne.

4.1.5. Commentaires
Un commentaire est une squence de caractres commenant avec deux tirets et s'tendant jusqu' la fin de la ligne, par exemple :
-- Ceci est un commentaire standard en SQL
Autrement, les blocs de commentaires style C peuvent tre utiliss :
/* commentaires multilignes
* et imbriqus: /* bloc de commentaire imbriqu */
*/
o le commentaire commence avec /* et s'tend jusqu' l'occurrence de */. Ces blocs de commentaires s'imbriquent, comme spcifi dans le standard SQL mais pas comme dans le langage C. De ce fait, vous pouvez commenter des blocs importants de code
pouvant contenir des blocs de commentaires dj existants.
Un commentaire est supprim du flux en entre avant une analyse plus pousse de la syntaxe et est remplac par un espace blanc.

4.1.6. Prcdence d'oprateurs


Le Tableau 4.2, Prcdence des oprateurs (en ordre dcroissant) affiche la prcdence et l'associativit des oprateurs dans
PostgreSQL. La plupart des oprateurs ont la mme prcdence et sont associatifs par la gauche. La prcdence et l'associativit
des oprateurs sont codes en dur dans l'analyseur. Ceci pourrait conduire un comportement non intuitif ; par exemple, les oprateurs boolens < et > ont une prcdence diffrente des oprateurs boolens <= et >=. De mme, vous aurez quelque fois besoin
d'ajouter des parenthses lors de l'utilisation de combinaisons d'oprateurs binaires et unaires. Par exemple :
SELECT 5 ! - 6;
sera analys comme :
SELECT 5 ! (- 6);
parce que l'analyseur n'a aucune ide, jusqu' ce qu'il ne soit trop tard, que ! est dfini comme un oprateur suffixe, et non pas prfixe. Pour obtenir le comportement dsir dans ce cas, vous devez crire :
SELECT (5 !) - 6;
C'est le prix payer pour l'extensibilit.
Tableau 4.2. Prcdence des oprateurs (en ordre dcroissant)

Oprateur/lment

Associativit

Description

gauche

sparateur de noms de table et de colonne

::

gauche

conversion de type, style PostgreSQL

[]

gauche

slection d'un lment d'un tableau

+-

droite

plus unaire, moins unaire

gauche

exposant

*/%

gauche

multiplication, division, modulo

+-

gauche

addition, soustraction

IS

IS TRUE, IS FALSE, IS NULL, etc


26

Syntaxe SQL

Oprateur/lment

Associativit

Description

ISNULL

test pour NULL

NOTNULL

test pour non NULL

(autres)

gauche

tout autre oprateur natif ou dfini par l'utilisateur

IN

appartenance un ensemble

BETWEEN

compris entre

OVERLAPS

surcharge un intervalle de temps

LIKE ILIKE SIMILAR

correspondance de motifs de chanes

<>

infrieur, suprieur

droite

galit, affectation

NOT

droite

ngation logique

AND

gauche

conjonction logique

OR

gauche

disjonction logique

Notez que les rgles de prcdence des oprateurs s'appliquent aussi aux oprateurs dfinis par l'utilisateur qui ont le mme nom
que les oprateurs internes mentionns ici. Par exemple, si vous dfinissez un oprateur + pour un type de donnes personnalis, il aura la mme prcdence que l'oprateur interne + , peu importe ce que fait le votre.
Lorsqu'un nom d'oprateur qualifi par un schma est utilis dans la syntaxe OPERATOR, comme par exemple dans :
SELECT 3 OPERATOR(pg_catalog.+) 4;
la construction OPERATOR est prise pour avoir la prcdence par dfaut affiche dans le Tableau 4.2, Prcdence des oprateurs
(en ordre dcroissant) pour les oprateurs autres . Ceci est vrai quelque soit le nom spcifique de l'oprateur apparaissant
l'intrieur de OPERATOR().

4.2. Expressions de valeurs


Les expressions de valeurs sont utilises dans une grande varit de contextes, tels que dans la liste cible d'une commande SELECT, dans les nouvelles valeurs de colonnes d'une commande INSERT ou UPDATE, ou dans les conditions de recherche d'un
certain nombre de commandes. Le rsultat d'une expression de valeurs est quelquefois appel scalaire, pour le distinguer du rsultat d'une expression de table (qui est une table). Les expressions de valeurs sont aussi appeles des expressions scalaires (voire
mme simplement des expressions). La syntaxe d'expression permet le calcul des valeurs partir de morceaux primitifs en utilisant les oprations arithmtiques, logiques, d'ensemble et autres.
Une expression de valeur peut tre :

une constante ou une valeur constante ;

une rfrence de colonne ;

une rfrence de la position d'un paramtre, dans le corps d'une dfinition de fonction ou d'instruction prpare ;

une expression indice ;

une expression de slection de champs ;

un appel d'oprateur ;

un appel de fonction ;

une expression d'agrgat ;

un appel de fonction de fentrage ;

une conversion de type ;

une expression de collationnement ;

une sous-requte scalaire ;

un constructeur de tableau ;

un constructeur de ligne ;

27

Syntaxe SQL

toute expression de valeur entre parenthses, utile pour grouper des sous-expressions et surcharger la prcdence.

En plus de cette liste, il existe un certain nombre de constructions pouvant tre classes comme une expression mais ne suivant aucune rgle de syntaxe gnrale. Elles ont gnralement la smantique d'une fonction ou d'un oprateur et sont expliques au Chapitre 9, Fonctions et oprateurs. Un exemple est la clause IS NULL.
Nous avons dj discut des constantes dans la Section 4.1.2, Constantes . Les sections suivantes discutent des options restantes.

4.2.1. Rfrences de colonnes


Une colonne peut tre rfrence avec la forme :
correlation.nom_colonne
correlation est le nom d'une table (parfois qualifi par son nom de schma) ou un alias d'une table dfinie au moyen de la
clause FROM. Le nom de corrlation et le point de sparation peuvent tre omis si le nom de colonne est unique dans les tables utilises par la requte courante (voir aussi le Chapitre 7, Requtes).

4.2.2. Paramtres de position


Un paramtre de position est utilis pour indiquer une valeur fournie en externe par une instruction SQL. Les paramtres sont utiliss dans des dfinitions de fonction SQL et dans les requtes prpares. Quelques bibliothques clients supportent aussi la spcification de valeurs de donnes sparment de la chane de commande SQL, auquel cas les paramtres sont utiliss pour rfrencer
les valeurs de donnes en dehors. Le format d'une rfrence de paramtre est :
$numro
Par exemple, considrez la dfinition d'une fonction : dept :
CREATE FUNCTION dept(text) RETURNS dept
AS $$ SELECT * FROM dept WHERE nom = $1 $$
LANGUAGE SQL;
Dans cet exemple, $1 rfrence la valeur du premier argument de la fonction chaque appel de cette commande.

4.2.3. Indices
Si une expression rcupre une valeur de type tableau, alors un lment spcifique du tableau peut tre extrait en crivant :
expression[indice]
Des lments adjacents (un morceau de tableau ) peuvent tre extraits en crivant :
expression[indice_bas:indice_haut]
Les crochets [ ] doivent apparatre rellement. Chaque indice est lui-mme une expression, devant contenir une valeur entire.
En gnral, l'expression de type tableau doit tre entre parenthses mais ces dernires peuvent tre omises lorsque l'expression
utilise comme indice est seulement une rfrence de colonne ou un paramtre de position. De plus, les indices multiples peuvent
tre concatns lorsque le tableau original est multi-dimensionnel. Par exemple :
ma_table.colonnetableau[4]
ma_table.colonnes_deux_d[17][34]
$1[10:42]
(fonctiontableau(a,b))[42]
Dans ce dernier exemple, les parenthses sont requises. Voir la Section 8.14, Tableaux pour plus d'informations sur les tableaux.

4.2.4. Slection de champs


Si une expression rcupre une valeur de type composite (type row), alors un champ spcifique de la ligne est extrait en crivant :
expression.nom_champ
En gnral, l'expression de ligne doit tre entre parenthses mais les parenthses peuvent tre omises lorsque l'expression
partir de laquelle se fait la slection est seulement une rfrence de table ou un paramtre de position. Par exemple :
28

Syntaxe SQL

ma_table.macolonne
$1.unecolonne
(fonctionligne(a,b)).col3
En fait, une rfrence de colonne qualifie est un cas spcial de syntaxe de slection de champ. Un cas spcial important revient
extraire un champ de la colonne de type composite d'une table :
(colcomposite).unchamp
(matable.colcomposite).unchamp
Les parenthses sont requises ici pour montrer que colcomposite est un nom de colonne, et non pas un nom de table, ou que
matable est un nom de table, pas un nom de schma dans le deuxime cas.
Dans une liste d'extraction (voir la Section 7.3, Listes de slection ), vous pouvez demander tous les champs d'une valeur composite en crivant .* :
(compositecol).*

4.2.5. Appels d'oprateurs


Il existe trois syntaxes possibles pour l'appel d'un oprateur :
expression oprateur expression (oprateur binaire prfixe)
oprateur expression (oprateur unaire prfixe)
expression oprateur (oprateur unaire suffixe)
o le jeton oprateur suit les rgles de syntaxe de la Section 4.1.3, Oprateurs , ou est un des mots cls AND, OR et NOT,
ou est un nom d'oprateur qualifi de la forme
OPERATOR(schema.nom_operateur)
Quel oprateur particulier existe et est-il unaire ou binaire dpend des oprateurs dfinis par le systme ou l'utilisateur. Le Chapitre 9, Fonctions et oprateurs dcrit les oprateurs internes.

4.2.6. Appels de fonctions


La syntaxe pour un appel de fonction est le nom d'une fonction (qualifi ou non du nom du schma) suivi par sa liste d'arguments
entre parenthses :
nom_fonction([expression [,expression ...]] )
Par exemple, ce qui suit calcule la racine carr de 2 :
sqrt(2)
La liste des fonctions intgres se trouve dans le Chapitre 9, Fonctions et oprateurs. D'autres fonctions pourraient tre ajoutes
par l'utilisateur.
En option, les arguments peuvent avoir leur nom attach. Voir la Section 4.3, Fonctions appelantes pour les dtails.

Note
Une fonction qui prend un seul argument de type composite peut aussi tre appele en utilisant la syntaxe de slection de champ. Du coup, un champ peut tre crit dans le style fonctionnel. Cela signifie que les notations
col(table) et table.col sont interchangeables. Ce comportement ne respecte pas le standard SQL mais il
est fourni dans PostgreSQL car il permet l'utilisation de fonctions mulant les champs calculs . Pour plus
d'informations, voir la Section 35.4.2, Fonctions SQL sur les types composites .

4.2.7. Expressions d'agrgat


Une expression d'agrgat reprsente l'application d'une fonction d'agrgat travers les lignes slectionnes par une requte. Une
fonction d'agrgat rduit les nombres entrs en une seule valeur de sortie, comme la somme ou la moyenne des valeurs en entre.
La syntaxe d'une expression d'agrgat est une des suivantes :
nom_agregat (expression [ , ... ] [ clause_order_by ] )
nom_agregat (ALL expression [ , ... ] [ clause_order_by ] )
nom_agregat (DISTINCT expression [ , ... ] [ clause_order_by ] )
29

Syntaxe SQL

nom_agregat ( * )
o nom_agregat est un agrgat prcdemment dfini (parfois qualifi d'un nom de schma), expression est toute expression de valeur qui ne contient pas lui-mme une expression d'agrgat ou un appel une fonction de fentrage. order_by_clause est une clause ORDER BY optionnelle comme dcrite ci-dessous.
La premire forme d'expression d'agrgat appelle l'agrgat une fois pour chaque ligne en entre. La seconde forme est identique
la premire car ALL est une clause active par dfaut. La troisime forme fait appel l'agrgat une fois pour chaque valeur distincte
de l'expression (ou ensemble distinct de valeurs, pour des expressions multiples) trouve dans les lignes en entre. La dernire
forme appelle l'agrgat une fois pour chaque ligne en entre ; comme aucune valeur particulire en entre n'est spcifie, c'est gnralement utile pour la fonction d'agrgat count(*).
La plupart des fonctions d'agrgats ignorent les entres NULL, pour que les lignes qui renvoient une ou plusieurs expressions
NULL soient disqualifies. Ceci peut tre considr vrai pour tous les agrgats internes sauf indication contraire.
Par exemple, count(*) trouve le nombre total de lignes en entre alors que count(f1) rcupre le nombre de lignes en entre
pour lesquelles f1 n'est pas NULL. En effet, la fonction count ignore les valeurs NULL mais count(distinct f1) retrouve le nombre de valeurs distinctes non NULL de f1.
D'habitude, les lignes en entre sont passes la fonction d'agrgat dans un ordre non spcifi. Dans la plupart des cas, cela n'a pas
d'importance. Par exemple, min donne le mme rsultat quelque soit l'ordre dans lequel il reoit les donnes. Nanmoins, certaines fonctions d'agrgat (tels que array_agg et string_agg) donnent un rsultat dpendant de l'ordre des lignes en entre.
Lors de l'utilisation de ce type d'agrgat, la clause clause_order_by peut tre utilise pour prciser l'ordre de tri dsir. La
clause clause_order_by a la mme syntaxe que la clause ORDER BY d'une requte, qui est dcrite dans la Section 7.5, Tri
des lignes , sauf que ses expressions sont toujours des expressions simples et ne peuvent pas tre des noms de colonne en sortie
ou des numros. Par exemple :
SELECT array_agg(a ORDER BY b DESC) FROM table;
Lors de l'utilisation de fonctions d'agrgat plusieurs arguments, la clause ORDER BY arrive aprs tous les arguments de
l'agrgat. Par exemple, il faut crire ceci :
SELECT string_agg(a, ',' ORDER BY a) FROM table;
et non pas ceci :
SELECT string_agg(a ORDER BY a, ',') FROM table;

-- incorrect

Ce dernier exemple est syntaxiquement correct mais il concerne un appel une fonction d'agrgat un seul argument avec deux
cls pour le ORDER BY (le deuxime tant inutile car il est constant).
Si DISTINCT est indiqu en plus de la clause clause_order_by, alors toutes les expressions de l'ORDER BY doivent correspondre aux arguments de l'agrgat ; autrement dit, vous ne pouvez pas trier sur une expression qui n'est pas inclus dans la liste
DISTINCT.

Note
La possibilit de spcifier la fois DISTINCT et ORDER BY dans une fonction d'agrgat est une extension de
PostgreSQL.
Les fonctions d'agrgat prdfinies sont dcrites dans la Section 9.18, Fonctions d'agrgat . D'autres fonctions d'agrgat pourraient tre ajoutes par l'utilisateur.
Une expression d'agrgat peut seulement apparatre dans la liste de rsultats ou dans la clause HAVING d'une commande SELECT. Elle est interdite dans d'autres clauses, tels que WHERE, parce que ces clauses sont logiquement values avant que les rsultats des agrgats ne soient calculs.
Lorsqu'une expression d'agrgat apparat dans une sous-requte (voir la Section 4.2.11, Sous-requtes scalaires et la Section 9.20, Expressions de sous-requtes ), l'agrgat est normalement valu sur les lignes de la sous-requte. Cependant, une
exception survient si les arguments de l'agrgat contiennent seulement des niveaux externes de variables : ensuite, l'agrgat appartient au niveau externe le plus proche et est valu sur les lignes de cette requte. L'expression de l'agrgat est une rfrence externe pour la sous-requte dans laquelle il apparat et agit comme une constante sur toute valuation de cette requte. La restriction
apparaissant seulement dans la liste de rsultat ou dans la clause HAVING s'applique avec respect du niveau de requte auquel appartient l'agrgat.

4.2.8. Appels de fonction de fentrage


Un appel de fonction de fentrage reprsente l'application d'une fonction de type agrgat sur une portion des lignes slectionnes
par une requte. Contrairement aux appels de fonction d'agrgat standard, ce n'est pas li au groupement des lignes slectionnes
30

Syntaxe SQL

en une seule ligne rsultat -- chaque ligne reste spare dans les rsultats. Nanmoins, la fonction de fentrage est capable de parcourir toutes les lignes qui font partie du groupe de la ligne courante d'aprs la spcification du groupe (liste PARTITION BY) de
l'appel de la fonction de fentrage. La syntaxe d'un appel de fonction de fentrage est une des suivantes :
nom_fonction
nom_fonction
nom_fonction
nom_fonction

([expression [, expression ... ]]) OVER nom_window


([expression [, expression ... ]]) OVER ( dfinition_window )
( * ) OVER nom_window
( * ) OVER ( dfinition_window )

o dfinition_fentrage a comme syntaxe :


[ nom_fentrage_existante ]
[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC | USING oprateur ] [ NULLS { FIRST | LAST } ] [,
...] ]
[ clause_porte ]
et la clause clause_porte optionnelle fait partie de :
[ RANGE | ROWS ] dbut_porte
[ RANGE | ROWS ] BETWEEN dbut_porte AND fin_porte
avec dbut_porte et fin_porte pouvant faire partie de
UNBOUNDED PRECEDING
valeur PRECEDING
CURRENT ROW
valeur FOLLOWING
UNBOUNDED FOLLOWING
Ici, expression reprsente toute expression de valeur qui ne contient pas elle-mle d'appel des fonctions window. Les listes
PARTITION BY et ORDER BY ont essentiellement la mme syntaxe et la mme smantique que les clauses GROUP BY et ORDER BY de la requte complte, sauf que leur expressions sont toujours seulement des expressions et ne peuvent pas tre des
noms ou des numros de colonnes en sortie. nom_window est une rfrence la spcification d'une window nomme, dfinie
dans la clause WINDOW de la requte. Autrement, une dfinition_window complte peut tre donne dans des parenthses,
en utilisant la mme syntaxe que pour la dfintion d'une fentre nomme dans la clause WINDOW ; voir la page de rfrence SELECT(7) pour les dtails. Il est prfrable de prciser que OVER nom_fentre n'est pas strictement quivalent OVER
(nom_fentre) ; ce dernier signifie la copie et la modification de la dfinition de la fentre, et sera rejet si la spcification de
la fentre rfrence inclut une clause de porte.
La clause clause_frame indique l'ensemble de lignes constituant le frame window, pour les fonctions window qui agissent sur
le frame et non pas sur la partition entire. Si fin_frame est omis, sa valeur par dfaut est CURRENT ROW. Les restrictions sont
les suivantes : dbut_frame ne peut pas valoir UNBOUNDED FOLLOWING, fin_frame ne peut pas valoir UNBOUNDED
PRECEDING et fin_frame ne peut pas apparatre avant dbut_frame -- par exemple, RANGE BETWEEN CURRENT ROW
AND valeur PRECEDING n'est pas autoris. L'option de frame par dfaut est RANGE UNBOUNDED PRECEDING, qui est
identique RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ; cela configure la frame toutes les lignes
partir du dbut de la partition jusqu' la ligne actuelle du prochain dans l'ordre du ORDER BY (ce qui signifie toutes les lignes si la
clause ORDER BY est absente). En gnral, UNBOUNDED PRECEDING signifie que la frame commence avec la premire ligne
de la partition et, de faon similaire, UNBOUNDED FOLLOWING signifie que la frame se termine avec la dernire ligne de la partition (quel que soit le mode, RANGE ou ROWS. Dans le mode ROWS, CURRENT ROW signifie que la frame commence ou finit
avec la ligne actuelle ; mais dans le mode RANGE, cela signifie que la frame commence ou finit avec le premier ou le prochain lment partir de la ligne actuel dans l'ordre indiqu par la clause ORDER BY. Les cas valeur PRECEDING et valeur FOLLOWING sont actuellement seulement autoriss dans le mode ROWS. Ils indiquent que la frame commence ou finit avec la ligne qui
se trouve ce nombre de lignes avant ou aprs la ligne actuelle. valeur doit tre une expression entire ne contenant aucune variable, fonction d'agrgat ou fonction de fentrage. La valeur ne doit pas tre NULL ou ngative. Par contre, elle peut valoir zro,
ce qui a pour effet de slectionner la ligne actuelle.
Les fonctions de fentrage internes sont dcrites dans la Tableau 9.44, Fonctions Window gnralistes . D'autres fonctions de
fentrage peuvent tre ajoutes par l'utilisateur. De plus, toute fonction d'agrgat interne ou dfinie par l'utilisateur peut tre utilise comme fonction de fentrage.
Les syntaxes utilisant * sont utilises pour appeler des fonctions d'agrgats sans paramtres en tant que fonctions de fentrage. Par
exemple : count(*) OVER (PARTITION BY x ORDER BY y). * n'est habituellement pas utilis pour les fonctions de fentrage qui ne sont pas des agrgats. Les fonctions de fentrage agrgats, contrairement aux fonctions d'agrgats normales,
n'autorisent pas l'utilisation de DISTINCT ou ORDER BY dans la liste des arguments de la fonction.
31

Syntaxe SQL

Les appels de fonctions de fentrage sont autoriss seulement dans la liste SELECT et dans la clause ORDER BY de la requte.
Il existe plus d'informations sur les fonctions de fentrages dans la Section 3.5, Fonctions de fentrage , dans la Section 9.19,
Fonctions Window et dans la Section 7.2.4, Traitement de fonctions Window .

4.2.9. Conversions de type


Une conversion de type spcifie une conversion partir d'un type de donnes vers un autre. PostgreSQL accepte deux syntaxes
quivalentes pour les conversions de type :
CAST ( expression AS type )
expression::type
La syntaxe CAST est conforme SQL ; la syntaxe avec :: est historique dans PostgreSQL.
Lorsqu'une conversion est applique une expression de valeur pour un type connu, il reprsente une conversion de type
l'excution. Cette conversion russira seulement si une opration convenable de conversion de type a t dfinie. Notez que ceci
est subtilement diffrent de l'utilisation de conversion avec des constantes, comme indiqu dans la Section 4.1.2.7, Constantes
d'autres types . Une conversion applique une chane constante reprsente l'affectation initiale d'un type pour une valeur
constante, et donc cela russira pour tout type (si le contenu de la chane constante est une syntaxe accepte en entre pour le type
de donne).
Une conversion de type explicite pourrait tre habituellement omise s'il n'y a pas d'ambigut sur le type qu'une expression de valeur pourrait produire (par exemple, lorsqu'elle est affecte une colonne de table) ; le systme appliquera automatiquement une
conversion de type dans de tels cas. Nanmoins, la conversion automatique est ralise seulement pour les conversions marques
OK pour application implicite dans les catalogues systme. D'autres conversions peuvent tre appeles avec la syntaxe de
conversion explicite. Cette restriction a pour but d'empcher l'excution silencieuse de conversions surprenantes.
Il est aussi possible de spcifier une conversion de type en utilisant une syntaxe de type fonction :
nom_type ( expression )
Nanmoins, ceci fonctionne seulement pour les types dont les noms sont aussi valides en tant que noms de fonctions. Par exemple,
double precision ne peut pas tre utilis de cette faon mais son quivalent float8 le peut. De mme, les noms interval, time et timestamp peuvent seulement tre utiliss de cette faon s'ils sont entre des guillemets doubles cause des
conflits de syntaxe. Du coup, l'utilisation de la syntaxe de conversion du style fonction amne des incohrences et devrait probablement tre vite.

Note
La syntaxe par fonction est en fait seulement un appel de fonction. Quand un des deux standards de syntaxe de
conversion est utilis pour faire une conversion l'excution, elle appellera en interne une fonction enregistre pour
raliser la conversion. Par convention, ces fonctions de conversion ont le mme nom que leur type de sortie et, du
coup, la syntaxe par fonction n'est rien de plus qu'un appel direct la fonction de conversion sous-jacente. videmment, une application portable ne devrait pas s'y fier. Pour plus d'informations, voir la page de manuel de CREATE
CAST(7).

4.2.10. Expressions de collationnement


La clause COLLATE surcharge le collationnement d'une expression. Elle est ajoute l'expression laquelle elle s'applique :
expr COLLATE collationnement
o collationnement est un identificateur pouvant tre qualifi par son schma. La clause COLLATE a priorit par rapport aux
oprateurs ; des parenthses peuvent tre utilises si ncessaire.
Si aucun collationnement n'est spcifiquement indiqu, le systme de bases de donnes dduit cette information du collationnement des colonnes impliques dans l'expression. Si aucune colonne ne se trouve dans l'expression, il utilise le collationnement par
dfaut de la base de donnes.
Les deux utilisations principales de la clause COLLATE sont la surcharge de l'ordre de tri dans une clause ORDER BY, par
exemple :
SELECT a, b, c FROM tbl WHERE ... ORDER BY a COLLATE "C";
et la surcharge du collationnement d'une fonction ou d'un oprateur qui produit un rsultat sensible la locale, par exemple :
SELECT * FROM tbl WHERE a > 'foo' COLLATE "C";
32

Syntaxe SQL

Notez que, dans le dernier cas, la clause COLLATE est attache l'argument en entre de l'oprateur. Peu importe l'argument de
l'oprateur ou de la fonction qui a la clause COLLATE parce que le collationnement appliqu l'oprateur ou la fonction est driv en considrant tous les arguments, et une clause COLLATE explicite surchargera les collationnements des autres arguments.
(Attacher des clauses COLLATE diffrentes sur les arguments aboutit une erreur. Pour plus de dtails, voir la Section 22.2,
Support des collations .) Du coup, ceci donne le mme rsultat que l'exemple prcdent :
SELECT * FROM tbl WHERE a COLLATE "C" > 'foo';
Mais ceci n'est pas valide :
SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C";
car cette requte cherche appliquer un collationnement au rsultat de l'oprateur >, qui est du type boolean, type non sujet au collationnement.

4.2.11. Sous-requtes scalaires


Une sous-requte scalaire est une requte SELECT ordinaire entre parenthses renvoyant exactement une ligne avec une colonne
(voir le Chapitre 7, Requtes pour plus d'informations sur l'criture des requtes). La requte SELECT est excute et la seule valeur renvoye est utilise dans l'expression de valeur englobante. C'est une erreur d'utiliser une requte qui renvoie plus d'une ligne
ou plus d'une colonne comme requte scalaire. Mais si, lors d'une excution particulire, la sous-requte ne renvoie pas de lignes,
alors il n'y a pas d'erreur ; le rsultat scalaire est suppos NULL. La sous-requte peut rfrencer des variables de la requte englobante, qui agiront comme des constantes durant toute valuation de la sous-requte. Voir aussi la Section 9.20, Expressions de
sous-requtes pour d'autres expressions impliquant des sous-requtes.
Par exemple, ce qui suit trouve la ville disposant de la population la plus importante dans chaque tat :
SELECT nom, (SELECT max(pop) FROM villes WHERE villes.etat = etat.nom)
FROM etats;

4.2.12. Constructeurs de tableaux


Un constructeur de tableau est une expression qui construit une valeur de tableau partir de la valeur de ses membres. Un
constructeur de tableau simple utilise le mot cl ARRAY, un crochet ouvrant [, une liste d'expressions (spares par des virgules)
pour les valeurs des lments du tableau et finalement un crochet fermant ]. Par exemple :
SELECT ARRAY[1,2,3+4];
array
--------{1,2,7}
(1 row)
Par dfaut, le type d'lment du tableau est le type commun des expressions des membres, dtermin en utilisant les mmes rgles
que pour les constructions UNION ou CASE (voir la Section 10.5, Constructions UNION, CASE et constructions relatives ).
Vous pouvez surcharger ceci en convertissant explicitement le constructeur de tableau vers le type dsir. Par exemple :
SELECT ARRAY[1,2,22.7]::integer[];
array
---------{1,2,23}
(1 row)
Ceci a le mme effet que la conversion de chaque expression vers le type d'lment du tableau individuellement. Pour plus
d'informations sur les conversions, voir la Section 4.2.9, Conversions de type .
Les valeurs de tableaux multidimensionnels peuvent tre construits par des constructeurs de tableaux imbriqus. Pour les constructeurs internes, le mot-cl ARRAY peut tre omis. Par exemple, ces expressions produisent le mme rsultat :
SELECT ARRAY[ARRAY[1,2], ARRAY[3,4]];
array
--------------{{1,2},{3,4}}
(1 row)
SELECT ARRAY[[1,2],[3,4]];
array
--------------{{1,2},{3,4}}
(1 row)
33

Syntaxe SQL

Comme les tableaux multidimensionnels doivent tre rectangulaires, les constructeurs internes du mme niveau doivent produire
des sous-tableaux de dimensions identiques. Toute conversion applique au constructeur ARRAY externe se propage automatiquement tous les constructeurs internes.
Les lments d'un constructeur de tableau multidimensionnel peuvent tre tout ce qui rcupre un tableau du bon type, pas seulement une construction d'un tableau imbriqu. Par exemple :
CREATE TABLE tab(f1 int[], f2 int[]);
INSERT INTO tab VALUES (ARRAY[[1,2],[3,4]], ARRAY[[5,6],[7,8]]);
SELECT ARRAY[f1, f2, '{{9,10},{11,12}}'::int[]] FROM tab;
array
-----------------------------------------------{{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}}
(1 row)
Vous pouvez construire un tableau vide mais, comme il est impossible d'avoir un tableau sans type, vous devez convertir explicitement votre tableau vide dans le type dsir. Par exemple :
SELECT ARRAY[]::integer[];
array
------{}
(1 row)
Il est aussi possible de construire un tableau partir des rsultats d'une sous-requte. Avec cette forme, le constructeur de tableau
est crit avec le mot cl ARRAY suivi par une sous-requte entre parenthses (et non pas des crochets). Par exemple :
SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
?column?
------------------------------------------------------------{2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31}
(1 row)
La sous-requte doit renvoyer une seule colonne. Le tableau une dimension rsultant aura un lment pour chaque ligne dans le
rsultat de la sous-requte, avec un type lment correspondant celui de la colonne en sortie de la sous-requte.
Les indices d'un tableau construit avec ARRAY commencent toujours un. Pour plus d'informations sur les tableaux, voir la Section 8.14, Tableaux .

4.2.13. Constructeurs de lignes


Un constructeur de ligne est une expression qui construit une valeur de ligne (aussi appele une valeur composite) partir des valeurs de ses membres. Un constructeur de ligne consiste en un mot cl ROW, une parenthse gauche, zro ou une ou plus d'une expression (spares par des virgules) pour les valeurs des champs de la ligne, et enfin une parenthse droite. Par exemple :
SELECT ROW(1,2.5,'ceci est un test');
Le mot cl ROW est optionnel lorsqu'il y a plus d'une expression dans la liste.
Un constructeur de ligne peut inclure la syntaxe valeurligne.*, qui sera tendue en une liste d'lments de la valeur ligne, ce
qui est le comportement habituel de la syntaxe .* utilise au niveau haut d'une liste SELECT. Par exemple, si la table t a les colonnes f1 et f2, ces deux requtes sont identiques :
SELECT ROW(t.*, 42) FROM t;
SELECT ROW(t.f1, t.f2, 42) FROM t;

Note
Avant PostgreSQL 8.2, la syntaxe .* n'tait pas tendue. De ce fait, ROW(t.*, 42) crait une ligne deux
champs dont le premier tait une autre valeur de ligne. Le nouveau comportement est gnralement plus utile. Si
vous avez besoin de l'ancien comportement de valeurs de ligne imbriques, crivez la valeur de ligne interne sans
.*, par exemple ROW(t, 42).
Par dfaut, la valeur cre par une expression ROW est d'un type d'enregistrement anonyme. Si ncessaire, il peut tre converti en
un type composite nomm -- soit le type de ligne d'une table soit un type composite cr avec CREATE TYPE AS. Une conver34

Syntaxe SQL

sion explicite pourrait tre ncessaire pour viter toute ambigut. Par exemple :
CREATE TABLE ma_table(f1 int, f2 float, f3 text);
CREATE FUNCTION recup_f1(ma_table) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
-- Aucune conversion ncessaire parce que seul un recup_f1() existe
SELECT recup_f1(ROW(1,2.5,'ceci est un test'));
recup_f1
---------1
(1 row)
CREATE TYPE mon_typeligne AS (f1 int, f2 text, f3 numeric);
CREATE FUNCTION recup_f1(mon_typeligne) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
-- Maintenant, nous avons besoin d'une conversion
-- pour indiquer la fonction appeler
SELECT recup_f1(ROW(1,2.5,'ceci est un test'));
ERROR: function recup_f1(record) is not unique
SELECT recup_f1(ROW(1,2.5,'ceci est un test')::ma_table);
getf1
------1
(1 row)
SELECT recup_f1(CAST(ROW(11,'ceci est un test',2.5) AS mon_typeligne));
getf1
------11
(1 row)
Les constructeurs de lignes peuvent tre utiliss pour construire des valeurs composites stocker dans une colonne de table de
type composite ou pour tre pass une fonction qui accepte un paramtre composite. De plus, il est possible de comparer deux
valeurs de lignes ou pour tester une ligne avec IS NULL ou IS NOT NULL, par exemple
SELECT ROW(1,2.5,'ceci est un test') = ROW(1, 3, 'pas le mme');
SELECT ROW(table.*) IS NULL FROM table; -- dtecte toutes les lignes non NULL
Pour plus de dtails, voir la Section 9.21, Comparaisons de lignes et de tableaux . Les constructeurs de lignes peuvent aussi tre
utiliss en relation avec des sous-requtes, comme discut dans la Section 9.20, Expressions de sous-requtes .

4.2.14. Rgles d'valuation des expressions


L'ordre d'valuation des sous-expressions n'est pas dfini. En particulier, les entres d'un oprateur ou d'une fonction ne sont pas
obligatoirement values de la gauche vers la droite ou dans un autre ordre fix.
De plus, si le rsultat d'une expression peut tre dtermin par l'valuation de certaines parties de celle-ci, alors d'autres sousexpressions devraient ne pas tre values du tout. Par exemple, si vous crivez :
SELECT true OR une_fonction();
alors une_fonction() pourrait (probablement) ne pas tre appele du tout. Pareil dans le cas suivant :
SELECT une_fonction() OR true;
Notez que ceci n'est pas identique au court-circuitage de gauche droite des oprateurs boolens utilis par certains langages
de programmation.
En consquence, il est dconseill d'utiliser des fonctions ayant des effets de bord dans une partie des expressions complexes. Il
est particulirement dangereux de se fier aux effets de bord ou l'ordre d'valuation dans les clauses WHERE et HAVING car ces
clauses sont reproduites de nombreuses fois lors du dveloppement du plan d'excution. Les expressions boolennes
(combinaisons AND/OR/NOT) dans ces clauses pourraient tre rorganises d'une autre faon autorise dans l'algbre boolenne.
Quand il est essentiel de forcer l'ordre d'valuation, une construction CASE (voir la Section 9.16, Expressions conditionnelles )
peut tre utilise. Voici un exemple qui ne garantie pas qu'une division par zro ne soit faite dans une clause WHERE :
SELECT ... WHERE x > 0 AND y/x > 1.5;
35

Syntaxe SQL

Mais ceci est sr :


SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;
Une construction CASE utilise de cette faon djouera les tentatives d'optimisation, donc cela ne sera faire que si c'est ncessaire (dans cet exemple particulier, il serait sans doute mieux de contourner le problme en crivant y > 1.5*x).

4.3. Fonctions appelantes


PostgreSQL permet aux fonctions qui ont des paramtres nomms d'tre appeles en utilisant soit la notation par position soit la
notation par nom. La notation par nom est particulirement utile pour les fonctions qui ont un grand nombre de paramtres car elle
rend l'association entre paramtre et argument plus explicite et fiable. Dans la notation par position, un appel de fonction prcise
les valeurs en argument dans le mme ordre que ce qui a t dfini la cration de la fonction. Dans la notation nomme, les arguments sont prciss par leur nom et peuvent du coup tre intgrs dans n'importe quel ordre.
Quel que soit la notation, les paramtres qui ont des valeurs par dfaut dans leur dclaration n'ont pas besoin d'tre prciss dans
l'appel. Ceci est particulirement utile dans la notation nomme car toute combinaison de paramtre peut tre omise alors que dans
la notation par position, les paramtres peuvent seulement tre omis de la droite vers la gauche.
PostgreSQL supporte aussi la notation mixe. Elle combine la notation par position avec la notation par nom. Dans ce cas, les
paramtres de position sont crits en premier, les paramtres nomms apparaissent aprs.
Les exemples suivants illustrent l'utilisation des trois notations, en utilisant la dfinition de fonction suivante :
CREATE FUNCTION assemble_min_ou_maj(a text, b text, majuscule boolean DEFAULT false)
RETURNS text
AS
$$
SELECT CASE
WHEN $3 THEN UPPER($1 || ' ' || $2)
ELSE LOWER($1 || ' ' || $2)
END;
$$
LANGUAGE SQL IMMUTABLE STRICT;
La fonction assemble_min_ou_maj a deux paramtres obligatoires, a et b. Il existe en plus un paramtre optionnel, majuscule, qui vaut par dfaut false. Les arguments a et b seront concatns et forcs soit en majuscule soit en minuscule suivant la
valeur du paramtre majuscule. Les dtails restant ne sont pas importants ici (voir le Chapitre 35, tendre SQL pour plus
d'informations).

4.3.1. En utilisant la notation par position


La notation par position est le mcanisme traditionnel pour passer des arguments aux fonctions avec PostgreSQL. En voici un
exemple :
SELECT assemble_min_ou_maj('Hello', 'World', true);
assemble_min_ou_maj
--------------------HELLO WORLD
(1 row)
Tous les arguments sont indiqus dans l'ordre. Le rsultat est en majuscule car l'argument majuscule est indiqu true. Voici
un autre exemple :
SELECT assemble_min_ou_maj('Hello', 'World');
assemble_min_ou_maj
----------------------hello world
(1 row)
Ici, le paramtre majuscule est omis, donc il rcupre la valeur par dfaut, soit false, ce qui a pour rsultat une sortie en minuscule. Dans la notation par position, les arguments peuvent tre omis de la droite la gauche partir du moment o ils ont des
valeurs par dfaut.

4.3.2. En utilisant la notation par nom


Dans la notation par nom, chaque nom d'argument est prcis en utilisant := pour le sparer de l'expression de la valeur de
36

Syntaxe SQL

l'argument. Par exemple :


SELECT assemble_min_ou_maj(a := 'Hello', b := 'World');
assemble_min_ou_maj
----------------------hello world
(1 row)
Encore une fois, l'argument majuscule a t omis, donc il dispose de sa valeur par dfaut, false, implicitement. Un avantage
utiliser la notation par nom est que les arguments peuvent tre saisis dans n'importe quel ordre. Par exemple :
SELECT assemble_min_ou_maj(a := 'Hello', b := 'World', majuscule := true);
assemble_min_ou_maj
----------------------HELLO WORLD
(1 row)
SELECT assemble_min_ou_maj(a := 'Hello', majuscule := true, b := 'World');
assemble_min_ou_maj
----------------------HELLO WORLD
(1 row)

4.3.3. En utilisant la notation mixe


La notation mixe combine les notations par position et par nom. Nanmoins, comme cela a dj t expliqu, les arguments par
nom ne peuvent pas prcder les arguments par position. Par exemple :
SELECT assemble_min_ou_maj('Hello', 'World', majuscule := true);
assemble_min_ou_maj
----------------------HELLO WORLD
(1 row)
Dans la requte ci-dessus, les arguments a et b sont prciss par leur position alors que majuscule est indiqu par son nom.
Dans cet exemple, cela n'apporte pas grand-chose, sauf pour une documentation de la fonction. Avec une fonction plus complexe,
comprenant de nombreux paramtres avec des valeurs par dfaut, les notations par nom et mixes amliorent l'criture des appels
de fonction et permettent de rduire les risques d'erreurs.

Note
Les notations par appel nomm ou mixe ne peuvent pas tre utilis lors de l'appel d'une fonction d'agrgat (mais
elles fonctionnent quand une fonction d'agrgat est utilise en tant que fonction de fentrage).

37

Chapitre 5. Dfinition des donnes


Ce chapitre couvre la cration des structures de donnes amenes contenir les donnes. Dans une base relationnelle, les donnes brutes sont stockes dans des tables. De ce fait, une grande partie de ce chapitre est consacre l'explication de la cration
et de la modification des tables et aux fonctionnalits disponibles pour contrler les donnes stockes dans les tables.
L'organisation des tables dans des schmas et l'attribution de privilges sur les tables sont ensuite dcrits. Pour finir, d'autres
fonctionnalits, telles que l'hritage, les vues, les fonctions et les dclencheurs sont passes en revue.

5.1. Notions fondamentales sur les tables


Une table dans une base relationnelle ressemble beaucoup un tableau sur papier : elle est constitue de lignes et de colonnes.
Le nombre et l'ordre des colonnes sont fixes et chaque colonne a un nom. Le nombre de lignes est variable -- il reprsente le
nombre de donnes stockes un instant donn. Le SQL n'apporte aucune garantie sur l'ordre des lignes dans une table. Quand
une table est lue, les lignes apparaissent dans un ordre non spcifi, sauf si un tri est demand explicitement. Tout cela est expliqu dans le Chapitre 7, Requtes. De plus, le SQL n'attribue pas d'identifiant unique aux lignes. Il est donc possible d'avoir plusieurs lignes identiques au sein d'une table. C'est une consquence du modle mathmatique sur lequel repose le SQL, mme si
cela n'est habituellement pas souhaitable. Il est expliqu plus bas dans ce chapitre comment traiter ce problme.
Chaque colonne a un type de donnes. Ce type limite l'ensemble de valeurs qu'il est possible d'attribuer une colonne. Il attribue
galement une smantique aux donnes stockes dans la colonne pour permettre les calculs sur celles-ci. Par exemple, une colonne dclare dans un type numrique n'accepte pas les chanes textuelles ; les donnes stockes dans une telle colonne peuvent
tre utilises dans des calculs mathmatiques. Par opposition, une colonne dclare de type chane de caractres accepte pratiquement n'importe quel type de donne mais ne se prte pas aux calculs mathmatiques. D'autres types d'oprations, telle la
concatnation de chanes, sont cependant disponibles.
PostgreSQL inclut un ensemble consquent de types de donnes intgrs pour s'adapter diverses applications. Les utilisateurs peuvent aussi dfinir leurs propres types de donnes.
La plupart des types de donnes intgrs ont des noms et des smantiques vidents. C'est pourquoi leur explication dtaille est
reporte au Chapitre 8, Types de donnes.
Parmi les types les plus utiliss, on trouve integer pour les entiers, numeric pour les ventuelles fractions, text pour les chanes
de caractres, date pour les dates, time pour les heures et timestamp pour les valeurs qui contiennent la fois une date et une
heure.
Pour crer une table, on utilise la commande bien nomme CREATE TABLE(7). Dans cette commande, il est ncessaire
d'indiquer, au minimum, le nom de la table, les noms des colonnes et le type de donnes de chacune d'elles. Par exemple :
CREATE TABLE ma_premiere_table (
premiere_colonne text,
deuxieme_colonne integer
);
Cela cre une table nomme ma_premiere_table avec deux colonnes. La premire colonne, nomme premiere_colonne, est de type text ; la seconde colonne, nomme deuxieme_colonne, est de type integer. Les noms des
table et colonnes se conforment la syntaxe des identifiants explique dans la Section 4.1.1, identificateurs et mots cls . Les
noms des types sont souvent aussi des identifiants mais il existe des exceptions. Le sparateur de la liste des colonnes est la virgule. La liste doit tre entre parenthses.
L'exemple qui prcde est l'vidence extrmement simpliste. On donne habituellement aux tables et aux colonnes des noms
qui indiquent les donnes stockes. L'exemple ci-dessous est un peu plus raliste :
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric
);
(Le type numeric peut stocker des fractions telles que les montants.)

Astuce
Quand de nombreuses tables lies sont cres, il est prfrable de dfinir un motif cohrent pour le nommage des
tables et des colonnes. On a ainsi la possibilit d'utiliser le pluriel ou le singulier des noms, chacune ayant ses fidles et ses dtracteurs.

38

Dfinition des donnes

Le nombre de colonnes d'un table est limit. En fonction du type de colonnes, il oscille entre 250 et 1600. Dfinir une table avec
un nombre de colonnes proche de cette limite est, cependant, trs inhabituel et doit conduire se poser des questions quant la
conception du modle.
Lorsqu'une table n'est plus utile, elle peut tre supprime l'aide de la commande DROP TABLE(7). Par exemple :
DROP TABLE ma_premiere_table;
DROP TABLE produits;
Tenter de supprimer une table qui n'existe pas lve une erreur. Il est, nanmoins, habituel dans les fichiers de scripts SQL
d'essayer de supprimer chaque table avant de la crer. Les messages d'erreur sont alors ignors afin que le script fonctionne que la
table existe ou non. (La variante DROP TABLE IF EXISTS peut aussi tre utilise pour viter les messages d'erreur mais elle
ne fait pas partie du standard SQL.)
Pour la procduure de modification d'une table qui existe dj, voir la Section 5.5, Modification des tables plus loin dans ce
chapitre.
Les outils prcdemment dcrits permettent de crer des tables fonctionnelles. Le reste de ce chapitre est consacr l'ajout de
fonctionnalits la dfinition de tables pour garantir l'intgrit des donnes, la scurit ou l'ergonomie. Le lecteur impatient
d'insrer des donnes dans ses tables peut sauter au Chapitre 6, Manipulation de donnes et lire le reste de ce chapitre plus tard.

5.2. Valeurs par dfaut


Une valeur par dfaut peut tre attribue une colonne. Quand une nouvelle ligne est cre et qu'aucune valeur n'est indique pour
certaines de ses colonnes, celles-ci sont remplies avec leurs valeurs par dfaut respectives. Une commande de manipulation de
donnes peut aussi demander explicitement que la valeur d'une colonne soit positionne la valeur par dfaut, sans qu'il lui soit
ncessaire de connatre cette valeur (les dtails concernant les commandes de manipulation de donnes sont donns dans le Chapitre 6, Manipulation de donnes).
Si aucune valeur par dfaut n'est dclare explicitement, la valeur par dfaut est la valeur NULL. Cela a un sens dans la mesure o
l'on peut considrer que la valeur NULL reprsente des donnes inconnues.
Dans la dfinition d'une table, les valeurs par dfaut sont listes aprs le type de donnes de la colonne. Par exemple:
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric DEFAULT 9.99
);
La valeur par dfaut peut tre une expression, alors value l'insertion de cette valeur (pas la cration de la table). Un exemple
commun est la colonne de type timestamp dont la valeur par dfaut est now(). Elle se voit ainsi attribue l'heure d'insertion. Un
autre exemple est la gnration d'un numro de srie pour chaque ligne. Dans PostgreSQL, cela s'obtient habituellement par
quelque chose comme
CREATE TABLE produits (
no_produit integer DEFAULT nextval('produits_no_produit_seq'),
...
);
o la fonction nextval() fournit des valeurs successives partir d'un objet squence (voir la Section 9.15, Fonctions de manipulation de squences ). Cet arrangement est suffisamment commun pour qu'il ait son propre raccourci :
CREATE TABLE produits (
no_produit SERIAL,
...
);
Le raccourci SERIAL est discut plus tard dans la Section 8.1.4, Types seris .

5.3. Contraintes
Les types de donnes sont un moyen de restreindre la nature des donnes qui peuvent tre stockes dans une table. Pour beaucoup
d'applications, toutefois, la contrainte fournie par ce biais est trop grossire. Par exemple, une colonne qui contient le prix d'un
produit ne doit accepter que des valeurs positives. Mais il n'existe pas de type de donnes standard qui n'accepte que des valeurs
positives. Un autre problme peut provenir de la volont de contraindre les donnes d'une colonne par rapport aux autres colonnes
ou lignes. Par exemple, dans une table contenant des informations de produit, il ne peut y avoir qu'une ligne par numro de produit.

39

Dfinition des donnes

Pour cela, SQL permet de dfinir des contraintes sur les colonnes et les tables. Les contraintes donnent autant de contrle sur les
donnes des tables qu'un utilisateur peut le souhaiter. Si un utilisateur tente de stocker des donnes dans une colonne en violation
d'une contrainte, une erreur est leve. Cela s'applique mme si la valeur vient de la dfinition de la valeur par dfaut.

5.3.1. Contraintes de vrification


La contrainte de vrification est la contrainte la plus gnrique qui soit. Elle permet d'indiquer que la valeur d'une colonne particulire doit satisfaire une expression boolenne (valeur de vrit). Par exemple, pour obliger les prix des produits tre positifs, on
peut utiliser :
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric CHECK (prix > 0)
);
La dfinition de contrainte vient aprs le type de donnes, comme pour les dfinitions de valeur par dfaut. Les valeurs par dfaut
et les contraintes peuvent tre donnes dans n'importe quel ordre. Une contrainte de vrification s'utilise avec le mot cl CHECK
suivi d'une expression entre parenthses. L'expression de la contrainte implique habituellement la colonne laquelle elle
s'applique, la contrainte n'ayant dans le cas contraire que peu de sens.
la contrainte peut prendre un nom distinct. Cela clarifie les messages d'erreur et permet de faire rfrence la contrainte lorsqu'elle
doit tre modifie. La syntaxe est :
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric CONSTRAINT prix_positif CHECK (prix > 0)
);
Pour indiquer une contrainte nomme, on utilise le mot-cl CONSTRAINT suivi d'un identifiant et de la dfinition de la contrainte
(si aucun nom n'est prcis, le systme en choisit un).
Une contrainte de vrification peut aussi faire rfrence plusieurs colonnes. Dans le cas d'un produit, on peut vouloir stocker le
prix normal et un prix rduit en s'assurant que le prix rduit soit bien infrieur au prix normal.
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric CHECK (prix > 0),
prix_promotion numeric CHECK (prix_promotion > 0),
CHECK (prix > prix_promotion)
);
Si les deux premires contraintes n'offrent pas de nouveaut, la troisime utilise une nouvelle syntaxe. Elle n'est pas attache une
colonne particulire mais apparat comme un lment distinct dans la liste des colonnes. Les dfinitions de colonnes et ces dfinitions de contraintes peuvent tre dfinies dans un ordre quelconque.
Les deux premires contraintes sont appeles contraintes de colonne tandis que la troisime est appele contrainte de table parce
qu'elle est crite sparment d'une dfinition de colonne particulire. Les contraintes de colonne peuvent tre crites comme des
contraintes de table, mais l'inverse n'est pas forcment possible puisqu'une contrainte de colonne est suppose ne faire rfrence
qu' la colonne laquelle elle est attache (PostgreSQL ne vrifie pas cette rgle mais il est prfrable de la suivre pour s'assurer
que les dfinitions de tables fonctionnent avec d'autres systmes de bases de donnes). L'exemple ci-dessus peut aussi s'crire :
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric,
CHECK (prix > 0),
prix_promotion numeric,
CHECK (prix_promotion > 0),
CHECK (prix > prix_promotion)
);
ou mme :
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric CHECK (prix > 0),
40

Dfinition des donnes

prix_promotion numeric,
CHECK (prix_promotion > 0 AND prix > prix_promotion)
);
C'est une question de got.
Les contraintes de table peuvent tre nommes, tout comme les contraintes de colonne :
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric,
CHECK (prix > 0),
prix_promotion numeric,
CHECK (prix_promotion > 0),
CONSTRAINT promo_valide CHECK (prix > prix_promotion)
);
Une contrainte de vrification est satisfaite si l'expression est value vraie ou NULL. Puisque la plupart des expressions sont values NULL si l'une des oprandes est nulle, elles n'interdisent pas les valeurs NULL dans les colonnes contraintes. Pour s'assurer
qu'une colonne ne contient pas de valeurs NULL, la contrainte NOT NULL dcrite dans la section suivante peut tre utilise.

5.3.2. Contraintes de non nullit (NOT NULL)


Une contrainte NOT NULL indique simplement qu'une colonne ne peut pas prendre la valeur NULL. Par exemple :
CREATE TABLE produits (
no_produit integer NOT NULL,
nom text NOT NULL,
prix numeric
);
Une contrainte NOT NULL est toujours crite comme une contrainte de colonne. Elle est fonctionnellement quivalente la cration d'une contrainte de vrification CHECK (nom_colonne IS NOT NULL). Toutefois, dans PostgreSQL, il est plus efficace de crer explicitement une contrainte NOT NULL. L'inconvnient est que les contraintes de non-nullit ainsi cres ne
peuvent pas tre explicitement nommes.
Une colonne peut videmment avoir plusieurs contraintes. Il suffit d'crire les contraintes les unes aprs les autres :
CREATE TABLE produits (
no_produit integer NOT NULL,
nom text NOT NULL,
prix numeric NOT NULL CHECK (prix > 0)
);
L'ordre n'a aucune importance. Il ne dtermine pas l'ordre de vrification des contraintes.
La contrainte NOT NULL a un contraire ; la contrainte NULL. Elle ne signifie pas que la colonne doit tre NULL, ce qui est assurment inutile, mais slectionne le comportement par dfaut, savoir que la colonne peut tre NULL. La contrainte NULL n'est
pas prsente dans le standard SQL et ne doit pas tre utilise dans des applications portables (elle n'a t ajoute dans
PostgreSQL que pour assurer la compatibilit avec d'autres bases de donnes). Certains utilisateurs l'apprcient nanmoins car
elle permet de basculer aisment d'une contrainte l'autre dans un fichier de script. On peut, par exemple, commencer avec :
CREATE TABLE produits (
no_produit integer NULL,
nom text NULL,
prix numeric NULL
);
puis insrer le mot-cl NOT en fonction des besoins.

Astuce
Dans la plupart des bases de donnes, il est prfrable que la majorit des colonnes soient marques NOT NULL.

5.3.3. Contraintes d'unicit


Les contraintes d'unicit garantissent l'unicit des donnes contenues dans une colonne ou un groupe de colonnes par rapport
toutes les lignes de la table. La syntaxe est :
41

Dfinition des donnes

CREATE TABLE produits (


no_produit integer UNIQUE,
nom text,
prix numeric
);
lorsque la contrainte est crite comme contrainte de colonne et :
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric,
UNIQUE (no_produit)
);
lorsqu'elle est crite comme contrainte de table.
Lorsqu'une contrainte d'unicit fait rfrence un groupe de colonnes, celles-ci sont listes spares par des virgules :
CREATE TABLE exemple (
a integer,
b integer,
c integer,
UNIQUE (a, c)
);
Cela prcise que la combinaison de valeurs dans les colonnes indiques est unique sur toute la table. Sur une colonne prise isolment ce n'est pas ncessairement le cas (et habituellement cela ne l'est pas).
Une contrainte d'unicit peut tre nomme, de la faon habituelle :
CREATE TABLE produits (
no_produit integer CONSTRAINT doit_etre_different UNIQUE,
nom text,
prix numeric
);
L'ajout d'une contrainte unique crera automatiquement un index B-tree unique sur la colonne ou le groupe de colonnes utilis
dans la contrainte.
En gnral, une contrainte d'unicit est viole lorsque plus d'une ligne de la table possdent des valeurs identiques sur toutes les
colonnes de la contrainte. En revanche, deux valeurs NULL ne sont pas considres gales. Cela signifie qu'il est possible de stocker des lignes dupliques contenant une valeur NULL dans au moins une des colonnes contraintes. Ce comportement est
conforme au standard SQL, mais d'autres bases SQL n'appliquent pas cette rgle. Il est donc prfrable d'tre prudent lors du dveloppement d'applications portables.

5.3.4. Cls primaires


Techniquement, une contrainte de cl primaire n'est que la combinaison d'une contrainte d'unicit et d'une contrainte NOT NULL.
Les dfinitions de table suivantes acceptent de ce fait les mmes donnes :
CREATE TABLE produits (
no_produit integer UNIQUE NOT NULL,
nom text,
prix numeric
);
CREATE TABLE produits (
no_produit integer PRIMARY KEY,
nom text,
prix numeric
);
Les cls primaires peuvent galement contraindre plusieurs colonnes ; la syntaxe est semblable aux contraintes d'unicit :
CREATE TABLE exemple (
a integer,
b integer,
c integer,
PRIMARY KEY (a, c)
);
42

Dfinition des donnes

Une cl primaire indique qu'une colonne ou un groupe de colonnes peut tre utilis(e) comme identifiant unique des lignes de la
table. (C'est une consquence directe de la dfinition d'une cl primaire. Une contrainte d'unicit ne suffit pas fournir un identifiant unique car elle n'exclut pas les valeurs NULL). Ceci est utile la fois pour des raisons documentaires et pour les applications
clientes. Par exemple, une application graphique qui permet de modifier les valeurs de lignes a probablement besoin de connatre
la cl primaire d'une table pour pouvoir identifier les lignes de manire unique.
L'ajout d'une cl primaire crera automatiquement un index B-tree unique sur la colonne ou le groupe de colonnes utilis dans la
cl primaire.
Une table a, au plus, une cl primaire. (Le nombre de contraintes UNIQUE NOT NULL, qui assurent la mme fonction, n'est pas
limit, mais une seule peut tre identifie comme cl primaire.) La thorie des bases de donnes relationnelles impose que chaque
table ait une cl primaire. Cette rgle n'est pas force par PostgreSQL, mais il est prfrable de la respecter.

5.3.5. Cls trangres


Une contrainte de cl trangre stipule que les valeurs d'une colonne (ou d'un groupe de colonnes) doivent correspondre aux valeurs qui apparaissent dans les lignes d'une autre table. On dit que cela maintient l'intgrit rfrentielle entre les deux tables.
Soit la table de produits, dj utilise plusieurs fois :
CREATE TABLE produits (
no_produit integer PRIMARY KEY,
nom text,
prix numeric
);
Soit galement une table qui stocke les commandes de ces produits. Il est intressant de s'assurer que la table des commandes ne
contient que des commandes de produits qui existent rellement. Pour cela, une contrainte de cl trangre est dfinie dans la table
des commandes qui rfrence la table produit :
CREATE TABLE commandes (
id_commande integer PRIMARY KEY,
no_produit integer REFERENCES produits (no_produit),
quantite integer
);
Il est dsormais impossible de crer des commandes pour lesquelles no_produit n'apparat pas dans la table produits.
Dans cette situation, on dit que la table des commandes est la table qui rfrence et la table des produits est la table rfrence. De
la mme faon, il y a des colonnes qui rfrencent et des colonnes rfrences.
La commande prcdente peut tre raccourcie en
CREATE TABLE commandes (
id_commande integer PRIMARY KEY,
no_produit integer REFERENCES produits,
quantite integer
);
parce qu'en l'absence de liste de colonnes, la cl primaire de la table de rfrence est utilise comme colonne de rfrence.
Une cl trangre peut aussi contraindre et rfrencer un groupe de colonnes. Comme cela a dj t voqu, il faut alors l'crire
sous forme d'une contrainte de table. Exemple de syntaxe :
CREATE TABLE t1 (
a integer PRIMARY KEY,
b integer,
c integer,
FOREIGN KEY (b, c) REFERENCES autre_table (c1, c2)
);
Le nombre et le type des colonnes contraintes doivent correspondre au nombre et au type des colonnes rfrences.
Une contrainte de cl trangre peut tre nomme de la faon habituelle.
Une table peut contenir plusieurs contraintes de cl trangre. Les relation n-n entre tables sont implantes ainsi. Soient des tables
qui contiennent des produits et des commandes, avec la possibilit d'autoriser une commande contenir plusieurs produits (ce que
la structure ci-dessus ne permet pas). On peut pour cela utiliser la structure de table suivante :
CREATE TABLE produits (
no_produit integer PRIMARY KEY,
nom text,
prix numeric
43

Dfinition des donnes

);
CREATE TABLE commandes (
id_commande integer PRIMARY KEY,
adresse_de_livraison text,
...
);
CREATE TABLE commande_produits (
no_produit integer REFERENCES produits,
id_commande integer REFERENCES commandes,
quantite integer,
PRIMARY KEY (no_produit, id_commande)
);
La cl primaire de la dernire table recouvre les cls trangres.
Les cls trangres interdisent dsormais la cration de commandes qui ne soient pas lies un produit. Qu'arrive-t-il si un produit
est supprim alors qu'une commande y fait rfrence ? SQL permet aussi de le grer. Intuitivement, plusieurs options existent :

interdire d'effacer un produit rfrenc ;


effacer aussi les commandes ;
autre chose ?

Pour illustrer ce cas, la politique suivante est implante sur l'exemple de relations n-n voqu plus haut :

quand quelqu'un veut retirer un produit qui est encore rfrenc par une commande (au travers de commande_produits),
on l'interdit ;
si quelqu'un supprime une commande, les lments de la commande sont aussi supprims.

CREATE TABLE produits (


no_produit integer PRIMARY KEY,
nom text,
prix numeric
);
CREATE TABLE commandes (
id_commande integer PRIMARY KEY,
adresse_de_livraison text,
...
);
CREATE TABLE commande_produits (
no_produit integer REFERENCES produits ON DELETE RESTRICT,
id_commande integer REFERENCES commandes ON DELETE CASCADE,
quantite integer,
PRIMARY KEY (no_produit, id_commande)
);
Restreindre les suppressions et les cascader sont les deux options les plus communes. RESTRICT empche la suppression d'une
ligne rfrence. NO ACTION impose la leve d'une erreur si des lignes rfrenant existent lors de la vrification de la
contrainte. Il s'agit du comportement par dfaut en l'absence de prcision. La diffrence entre RESTRICT et NO ACTION est
l'autorisation par NO ACTION du report de la vrification la fin de la transaction, ce que RESTRICT ne permet pas. CASCADE
indique que, lors de la suppression d'une ligne rfrence, les lignes la rfrenant doivent tre automatiquement supprimes. Il
existe deux autres options : SET NULL et SET DEFAULT. Celles-ci imposent que les colonnes qui rfrencent soient rinitialises NULL ou leur valeur par dfaut, respectivement, lors de la suppression d'une ligne rfrence. Elles ne dispensent pas
pour autant d'observer les contraintes. Par exemple, si une action prcise SET DEFAULT mais que la valeur par dfaut ne satisfait
pas la cl trangre, l'opration choue.
l'instar de ON DELETE, existe ON UPDATE, voqu lorsqu'une colonne rfrence est modifie (actualise). Les actions possibles sont les mmes.
Comme la suppression d'une ligne de la table rfrence ou la mise jour d'une colonne rfrence ncessitera un parcours de la
table rfre pour trouver les lignes correspondant l'ancienne valeur, il est souvent intressant d'indexer les colonnes rfrences.
Comme cela n'est pas toujours ncessaire et qu'il y a du choix sur la faon d'indexer, l'ajout d'une contrainte de cl trangre ne
cre pas automatiquement un index sur les colonnes rfrences.
Le Chapitre 6, Manipulation de donnes contient de plus amples informations sur l'actualisation et la suppression de donnes.
44

Dfinition des donnes

Une cl trangre peut faire rfrence des colonnes qui constituent une cl primaire ou forment une contrainte d'unicit. Si la cl
trangre rfrence une contrainte d'unicit, des possibilits supplmentaires sont offertes concernant la correspondance des valeurs NULL. Celles-ci sont expliques dans la documentation de rfrence de CREATE TABLE(7).

5.3.6. Contraintes d'exclusion


Les contraintes d'exclusion vous assurent que si deux lignes sont compares sur les colonnes ou expressions spcifies en utilisant
les oprateurs indiqus, au moins une de ces comparaisons d'oprateurs reverra false ou NULL. La syntaxe est :
CREATE TABLE cercles (
c circle,
EXCLUDE USING gist (c WITH &&)
);
Voir aussi CREATE TABLE ... CONSTRAINT ... EXCLUDE pour plus de dtails.
L'ajout d'une contrainte d'exclusion crera automatiquement un index du type spcifi dans la dclaration de la contrainte.

5.4. Colonnes systme


Chaque table contient plusieurs colonnes systme implicitement dfinies par le systme. De ce fait, leurs noms ne peuvent pas tre
utiliss comme noms de colonnes utilisateur (ces restrictions sont distinctes de celles sur l'utlisation de mot-cls ; mettre le nom
entre guillemets ne permet pas d'chapper cette rgle). Il n'est pas vraiment utile de se proccuper de ces colonnes, mais au minimum de savoir qu'elles existent.
oid
L'identifiant objet (object ID) d'une ligne. Cette colonne n'est prsente que si la table a t cre en prcisant WITH OIDS ou
si la variable de configuration default_with_oids tait active ce moment-l. Cette colonne est de type oid (mme nom que
la colonne) ; voir la Section 8.16, Types identifiant d'objet pour obtenir plus d'informations sur ce type.
tableoid
L' OID de la table contenant la ligne. Cette colonne est particulirement utile pour les requtes qui utilisent des hirarchies
d'hritage (voir Section 5.8, L'hritage ). Il est, en effet, difficile, en son absence, de savoir de quelle table provient une
ligne. tableoid peut tre joint la colonne oid de pg_class pour obtenir le nom de la table.
xmin
L'identifiant (ID de transaction) de la transaction qui a insr cette version de la ligne. (Une version de ligne est un tat individuel de la ligne ; toute mise jour d'une ligne cre une nouvelle version de ligne pour la mme ligne logique.)
cmin
L'identifiant de commande ( partir de zro) au sein de la transaction d'insertion.
xmax
L'identifiant (ID de transaction) de la transaction de suppression, ou zro pour une version de ligne non efface. Il est possible
que la colonne ne soit pas nulle pour une version de ligne visible ; cela indique habituellement que la transaction de suppression n'a pas t effectue, ou qu'une tentative de suppression a t annule.
cmax
L'identifiant de commande au sein de la transaction de suppression, ou zro.
ctid
La localisation physique de la version de ligne au sein de sa table. Bien que le ctid puisse tre utilis pour trouver la version
de ligne trs rapidement, le ctid d'une ligne change si la ligne est actualise ou dplace par un VACUUM FULL. ctid
est donc inutilisable comme identifiant de ligne sur le long terme. Il est prfrable d'utiliser l'OID, ou, mieux encore, un numro de srie utilisateur, pour identifier les lignes logiques.
Les OID sont des nombres de 32 bits et sont attribus partir d'un compteur unique sur le cluster. Dans une base de donnes volumineuse ou age, il est possible que le compteur boucle. Il est de ce fait peu pertinent de considrer que les OID puissent tre
uniques ; pour identifier les lignes d'une table, il est fortement recommand d'utiliser un gnrateur de squence. Nanmoins, les
OID peuvent galement tre utiliss sous rserve que quelques prcautions soient prises :

une contrainte d'unicit doit tre ajoute sur la colonne OID de chaque table dont l'OID est utilis pour identifier les lignes.
45

Dfinition des donnes

Dans ce cas (ou dans celui d'un index d'unicit), le systme n'engendre pas d'OID qui puisse correspondre celui d'une ligne
dj prsente. Cela n'est videmment possible que si la table contient moins de 232 (4 milliards) lignes ; en pratique, la taille de
la table a tout intrt tre bien plus petite que a, dans un souci de performance ;

l'unicit inter-tables des OID ne doit jamais tre envisage ; pour obtenir un identifiant unique sur l'ensemble de la base, il faut
utiliser la combinaison du tableoid et de l'OID de ligne ;

les tables en question doivent tre cres avec l'option WITH OIDS. Depuis PostgreSQL 8.1, WITHOUT OIDS est l'option
par dfaut.

Les identifiants de transaction sont aussi des nombres de 32 bits. Dans une base de donnes age, il est possible que les ID de transaction bouclent. Cela n'est pas un problme fatal avec des procdures de maintenance appropries ; voir le Chapitre 23, Planifier
les tches de maintenance pour les dtails. Il est, en revanche, imprudent de considrer l'unicit des ID de transaction sur le long
terme (plus d'un milliard de transactions).
Les identifiants de commande sont aussi des nombres de 32 bits. Cela cre une limite dure de 232 (4 milliards) commandes SQL
au sein d'une unique transaction. En pratique, cette limite n'est pas un problme -- la limite est sur le nombre de commandes SQL,
pas sur le nombre de lignes traites. De plus, partir de PostgreSQL 8.3, seules les commandes qui modifient rellement le
contenu de la base de donnes consomment un identifiant de commande.

5.5. Modification des tables


Lorsqu'une table est cre et qu'une erreur a t commise ou que les besoins de l'application changent, il est alors possible de la
supprimer et de la rcrer. Cela n'est toutefois pas pratique si la table contient dj des donnes ou qu'elle est rfrence par
d'autres objets de la base de donnes (une contrainte de cl trangre, par exemple). C'est pourquoi PostgreSQL offre une srie
de commandes permettant de modifier une table existante. Cela n'a rien voir avec la modification des donnes contenues dans la
table ; il ne s'agit ici, que de modifier la dfinition, ou structure, de la table.
Il est possible

d'ajouter des colonnes ;


de supprimer des colonnes ;
d'ajouter des contraintes ;
de supprimer des contraintes ;
de modifier des valeurs par dfaut ;
de modifier les types de donnes des colonnes ;
de renommer des colonnes ;
de renommer des tables.

Toutes ces actions sont ralises l'aide de la commande ALTER TABLE(7), dont la page de rfrence est bien plus dtaille.

5.5.1. Ajouter une colonne


La commande d'ajout d'une colonne ressemble :
ALTER TABLE produits ADD COLUMN description text;
La nouvelle colonne est initialement remplie avec la valeur par dfaut prcise (NULL en l'absence de clause DEFAULT).
Des contraintes de colonne peuvent tre dfinies dans la mme commande, l'aide de la syntaxe habituelle :
ALTER TABLE produits ADD COLUMN description text CHECK (description <> '');
En fait, toutes les options applicables la description d'une colonne dans CREATE TABLE peuvent tre utilises ici. Il ne faut
toutefois pas oublier que la valeur par dfaut doit satisfaire les contraintes donnes. Dans le cas contraire, ADD choue. Il est aussi
possible d'ajouter les contraintes ultrieurement (voir ci-dessous) aprs avoir rempli la nouvelle colonne correctement.

Astuce
Ajouter une colonne avec une valeur par dfaut ncessite la mise jour de chaque ligne de la table pour stocker la
valeur de la nouvelle colonne. Cependant, si aucune valeur par dfaut n'est prcise, PostgreSQL peut viter la
mise jour physique. Il est, de ce fait, prfrable, si la colonne doit tre remplie en majorit avec des valeurs diffrentes de la valeur par dfaut, d'ajouter la colonne sans valeur par dfaut, d'insrer les bonnes valeurs avec une
commande UPDATE puis d'ajouter la valeur par dfaut dsire comme dcrit ci-dessus.

5.5.2. Retirer une colonne


46

Dfinition des donnes

La commande de suppression d'une colonne ressemble celle-ci :


ALTER TABLE produits DROP COLUMN description;
Toute donne dans cette colonne disparat. Les contraintes de table impliquant la colonne sont galement supprimes. Nanmoins,
si la colonne est rfrence par une contrainte de cl trangre d'une autre table, PostgreSQL ne supprime pas silencieusement
cette contrainte. La suppression de tout ce qui dpend de la colonne peut tre autorise en ajoutant CASCADE :
ALTER TABLE produits DROP COLUMN description CASCADE;
Voir la Section 5.12, Gestion des dpendances pour une description du mcanisme gnral.

5.5.3. Ajouter une contrainte


Pour ajouter une contrainte, la syntaxe de contrainte de table est utilise. Par exemple :
ALTER TABLE produits ADD CHECK (nom <> '');
ALTER TABLE produits ADD CONSTRAINT autre_nom UNIQUE (no_produit);
ALTER TABLE produits ADD FOREIGN KEY (id_groupe_produit) REFERENCES groupes_produits;
Pour ajouter une contrainte NOT NULL, qui ne peut pas tre crite sous forme d'une contrainte de table, la syntaxe suivante est
utilise :
ALTER TABLE produits ALTER COLUMN no_produit SET NOT NULL;
La contrainte tant immdiatement vrifie, les donnes de la table doivent satisfaire la contrainte avant qu'elle ne soit ajoute.

5.5.4. Supprimer une contrainte


Pour supprimer une contrainte, il faut connatre son nom. Si elle a t explicitement nomm, il n'y a aucune difficult. Dans le cas
contraire, le systme a engendr et attribu un nom qu'il faut dcouvrir. La commande \d table de psql peut tre utile ici ;
d'autres interfaces offrent aussi la possibilit d'examiner les dtails de table. La commande est :
ALTER TABLE produits DROP CONSTRAINT un_nom;
(Dans le cas d'un nom de contrainte engendr, comme $2, il est ncessaire de l'entourer de guillemets doubles pour en faire un
identifiant valable.)
Comme pour la suppression d'une colonne, CASCADE peut tre ajout pour supprimer une contrainte dont dpendent d'autres objets. Une contrainte de cl trangre, par exemple, dpend d'une contrainte de cl primaire ou d'unicit sur la(les) colonne(s) rfrence(s).
Cela fonctionne de la mme manire pour tous les types de contrainte, l'exception des contraintes NOT NULL. Pour supprimer
une contrainte NOT NULL, on crit :
ALTER TABLE produits ALTER COLUMN no_produit DROP NOT NULL;
(Les contraintes NOT NULL n'ont pas de noms.)

5.5.5. Modifier la valeur par dfaut d'une colonne


La commande de dfinition d'une nouvelle valeur par dfaut de colonne ressemble celle-ci :
ALTER TABLE produits ALTER COLUMN prix SET DEFAULT 7.77;
Cela n'affecte pas les lignes existantes de la table, mais uniquement la valeur par dfaut pour les futures commandes INSERT.
Pour retirer toute valeur par dfaut, on crit :
ALTER TABLE produits ALTER COLUMN prix DROP DEFAULT;
C'est quivalent mettre la valeur par dfaut NULL. En consquence, il n'y a pas d'erreur retirer une valeur par dfaut qui n'a
pas t dfinie car NULL est la valeur par dfaut implicite.

5.5.6. Modifier le type de donnes d'une colonne


La commande de conversion du type de donnes d'une colonne ressemble celle-ci :
ALTER TABLE produits ALTER COLUMN prix TYPE numeric(10,2);
Elle ne peut russir que si chaque valeur de la colonne peut tre convertie dans le nouveau type par une conversion implicite. Si
une conversion plus complexe est ncessaire, une clause USING peut tre ajoute qui indique comment calculer les nouvelles valeurs partir des anciennes.
47

Dfinition des donnes

PostgreSQL tente de convertir la valeur par dfaut de la colonne le cas chant, ainsi que toute contrainte impliquant la colonne.
Mais ces conversions peuvent chouer ou produire des rsultats surprenants. Il est souvent prfrable de supprimer les contraintes
de la colonne avant d'en modifier le type, puis d'ajouter ensuite les contraintes convenablement modifies.

5.5.7. Renommer une colonne


Pour renommer une colonne :
ALTER TABLE produits RENAME COLUMN no_produit TO numero_produit;

5.5.8. Renommer une table


Pour renommer une table :
ALTER TABLE produits RENAME TO elements;

5.6. Droits
Quand un objet est cr, il se voit affecter un propritaire. Le propritaire est normalement le rle qui a excut la requte de cration. Pour la plupart des objets, l'tat initial est que seul le propritaire (et les superutilisateurs) peuvent faire quelque chose avec
cet objet. Pour permettre aux autres rles de l'utiliser, des droits doivent tre donns.
Il existe un certain nombre de droits diffrents : SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER,
CREATE, CONNECT, TEMPORARY, EXECUTE et USAGE. Les droits applicables un objet particulier varient selon le type d'objet
(table, fonction...). La page de rfrence GRANT(7) fournit une information complte sur les diffrents types de droits grs par
PostgreSQL. La section et les chapitres suivants prsentent l'utilisation de ces droits.
Le droit de modifier ou de dtruire un objet est le privilge du seul propritaire.
Un objet peut se voir affecter un nouveau propritaire avec la commande ALTER correspondant l'objet, par exemple ALTER
TABLE(7). Les superutilisateurs peuvent toujours le faire. Les rles ordinaires peuvent seulement le faire s'ils sont le propritaire
actuel de l'objet (ou un membre du rle propitaire) et un membre du nouveau rle propritaire.
La commande GRANT est utilise pour accorder des privilges (on dit aussi granter un privilge ). Par exemple, si joe est un
utilisateur et comptes une table, le privilge d'actualiser la table comptes peut tre accord joe avec :
GRANT UPDATE ON comptes TO joe;
crire ALL la place d'un droit spcifique accorde tous les droits applicables ce type d'objet.
Le nom d' utilisateur spcial PUBLIC peut tre utilis pour donner un privilge tous les utilisateurs du systme. De plus, les
rles de type group peuvent tre configurs pour aider la gestion des droits quand il y a beaucoup d'utilisateurs dans une base
-- pour les dtails, voir Chapitre 20, Rles de la base de donnes.
Pour rvoquer un privilge, on utilise la commande bien-nomme REVOKE, comme dans l'exemple ci-dessous :
REVOKE ALL ON comptes FROM PUBLIC;
Les privilges spciaux du propritaire de l'objet (c'est--dire, le droit d'excuter DROP, GRANT, REVOKE, etc.) appartiennent
toujours implicitement au propritaire. Il ne peuvent tre ni accords ni rvoqus. Mais le propritaire de l'objet peut choisir de rvoquer ses propres droits ordinaires pour, par exemple, mettre une table en lecture seule pour lui-mme et pour les autres.
Habituellement, seul le propritaire de l'objet (ou un superutilisateur) peut granter ou rvoquer les droits sur un objet. Nanmoins,
il est possible de donner un privilge avec possibilit de transmission ( with grant option ), qui donne celui qui le reoit la
permission de le donner d'autres. Si cette option est ensuite rvoque, alors tous ceux qui ont reu ce privilge par cet utilisateur
(directement ou indirectement via la chane des dons) perdent ce privilge. Pour les dtails, voir les pages de rfrences
GRANT(7) et REVOKE(7).

5.7. Schmas
Un cluster de bases de donnes PostgreSQL contient une ou plusieurs base(s) nomme(s). Si les utilisateurs et groupes
d'utilisateurs sont partags sur l'ensemble du cluster, aucune autre donne n'est partage. Toute connexion cliente au serveur ne
peut accder qu'aux donnes d'une seule base, celle indique dans la requte de connexion.

Note
Les utilisateurs d'un cluster n'ont pas obligatoirement le droit d'accder toutes les bases du cluster. Le partage des
48

Dfinition des donnes

noms d'utilisateur signifie qu'il ne peut pas y avoir plusieurs utilisateurs nomms joe, par exemple, dans deux
bases du mme cluster ; mais le systme peut tre configur pour n'autoriser joe accder qu' certaines bases.
Une base de donnes contient un ou plusieurs schma(s) nomm(s) qui, eux, contiennent des tables. Les schmas contiennent aussi d'autres types d'objets nomms (types de donnes, fonctions et oprateurs, par exemple). Le mme nom d'objet peut tre utilis
dans diffrents schmas sans conflit ; par exemple, schema1 et mon_schema peuvent tous les deux contenir une table nomme
ma_table. la diffrence des bases de donnes, les schmas ne sont pas spars de manire rigide : un utilisateur peut accder
aux objets de n'importe quel schma de la base de donnes laquelle il est connect, sous rserve qu'il en ait le droit.
Il existe plusieurs raisons d'utiliser les schmas :

autoriser de nombreux utilisateurs utiliser une base de donnes sans interfrer avec les autres ;

organiser les objets de la base de donnes en groupes logiques afin de faciliter leur gestion ;

les applications tiers peuvent tre places dans des schmas spars pour viter les collisions avec les noms d'autres objets.

Les schmas sont comparables aux rpertoires du systme d'exploitation, ceci prs qu'ils ne peuvent pas tre imbriqus.

5.7.1. Crer un schma


Pour crer un schma, on utilise la commande CREATE SCHEMA(7). Le nom du schma est libre. Par exemple :
CREATE SCHEMA mon_schema;
Pour crer les objets d'un schma ou y accder, on crit un nom qualifi constitu du nom du schma et du nom de la table spars
par un point :
schema.table
Cela fonctionne partout o un nom de table est attendu, ce qui inclut les commandes de modification de la table et les commandes
d'accs aux donnes discutes dans les chapitres suivants. (Pour des raisons de simplification, seules les tables sont voques, mais
les mmes principes s'appliquent aux autres objets nomms, comme les types et les fonctions.)
La syntaxe encore plus gnrale
base.schema.table
peut aussi tre utilise, mais l'heure actuelle, cette syntaxe n'existe que pour des raisons de conformit avec le standard SQL. Si
un nom de base de donnes est prcis, ce doit tre celui de la base laquelle l'utilisateur est connect.
Pour crer une table dans le nouveau schma, on utilise :
CREATE TABLE mon_schema.ma_table (
...
);
Pour effacer un schma vide (tous les objets qu'il contient ont t supprims), on utilise :
DROP SCHEMA mon_schema;
Pour effacer un schma et les objets qu'il contient, on utilise :
DROP SCHEMA mon_schema CASCADE;
La Section 5.12, Gestion des dpendances dcrit le mcanisme gnral sous-jacent.
Il n'est pas rare de vouloir crer un schma dont un autre utilisateur est propritaire (puisque c'est l'une des mthodes de restriction
de l'activit des utilisateurs des namespaces pr-dfinis). La syntaxe en est :
CREATE SCHEMA nom_schema AUTHORIZATION nom_utilisateur;
Le nom du schma peut tre omis, auquel cas le nom de l'utilisateur est utilis. Voir la Section 5.7.6, Utilisation pour en
connatre l'utilit.
Les noms de schma commenant par pg_ sont rservs pour les besoins du systme et ne peuvent tre crs par les utilisateurs.

5.7.2. Le schma public


Dans les sections prcdentes, les tables sont cres sans qu'un nom de schma soit indiqu. Par dfaut, ces tables (et les autres objets) sont automatiquement places dans un schma nomm public . Toute nouvelle base de donnes contient un tel schma.
Les instructions suivantes sont donc quivalentes :
49

Dfinition des donnes

CREATE TABLE produits ( ... );


et :
CREATE TABLE public.produits ( ... );

5.7.3. Chemin de parcours des schmas


Non seulement l'criture de noms qualifis est contraignante, mais il est, de toute faon, prfrable de ne pas fixer un nom de schma dans les applications. De ce fait, les tables sont souvent appeles par des noms non-qualifis, soit le seul nom de la table. Le
systme dtermine la table appele en suivant un chemin de recherche, liste de schmas dans lesquels chercher. La premire table
correspondante est considre comme la table voulue. S'il n'y a pas de correspondance, une erreur est remonte, quand bien mme
il existerait des tables dont le nom correspond dans d'autres schmas de la base.
Le premier schma du chemin de recherche est appel schma courant. En plus d'tre le premier schma parcouru, il est aussi le
schma dans lequel les nouvelles tables sont cres si la commande CREATE TABLE ne prcise pas de nom de schma.
Le chemin de recherche courant est affich l'aide de la commande :
SHOW search_path;
Dans la configuration par dfaut, ceci renvoie :
search_path
-------------"$user",public
Le premier lment prcise qu'un schma de mme nom que l'utilisateur courant est recherch. En l'absence d'un tel schma,
l'entre est ignore. Le deuxime lment renvoie au schma public prcdemment voqu.
C'est, par dfaut, dans le premier schma du chemin de recherche qui existe que sont crs les nouveaux objets. C'est la raison
pour laquelle les objets sont crs, par dfaut, dans le schma public. Lorsqu'il est fait rfrence un objet, dans tout autre
contexte, sans qualification par un schma (modification de table, modification de donnes ou requtes), le chemin de recherche
est travers jusqu' ce qu'un objet correspondant soit trouv. C'est pourquoi, dans la configuration par dfaut, tout accs non qualifi ne peut que se rfrer au schma public.
Pour ajouter un schma au chemin, on crit :
SET search_path TO mon_schema,public;
($user est omis ce niveau car il n'est pas immdiatement ncessaire.) Il est alors possible d'accder la table sans qu'elle soit
qualifie par un schma :
DROP TABLE ma_table;
Puisque mon_schema est le premier lment du chemin, les nouveaux objets sont, par dfaut, crs dans ce schma.
On peut aussi crire :
SET search_path TO mon_schema;
Dans ce cas, le schma public n'est plus accessible sans qualification explicite. Hormis le fait qu'il existe par dfaut, le schma public n'a rien de spcial. Il peut mme tre effac.
On peut galement se rfrer la Section 9.23, Fonctions d'informations systme qui dtaille les autres faons de manipuler le
chemin de recherche des schmas.
Le chemin de recherche fonctionne de la mme faon pour les noms de type de donnes, les noms de fonction et les noms
d'oprateur que pour les noms de table. Les noms des types de donnes et des fonctions peuvent tre qualifis de la mme faon
que les noms de table. S'il est ncessaire d'crire un nom d'oprateur qualifi dans une expression, il y a une condition spciale. Il
faut crire :
OPERATOR(schma.oprateur)
Cela afin d'viter toute ambigut syntaxique. Par exemple :
SELECT 3 OPERATOR(pg_catalog.+) 4;
En pratique, il est prfrable de s'en remettre au chemin de recherche pour les oprateurs, afin de ne pas avoir crire quelque
chose d'aussi trange.

5.7.4. Schmas et privilges


Par dfaut, les utilisateurs ne peuvent pas accder aux objets prsents dans les schmas qui ne leur appartiennent pas. Pour le per50

Dfinition des donnes

mettre, le propritaire du schma doit donner le droit USAGE sur le schma. Pour autoriser les utilisateurs manipuler les objets
d'un schma, des privilges supplmentaires doivent ventuellement tre accords, en fonction de l'objet.
Un utilisateur peut aussi tre autoris crer des objets dans le schma d'un d'autre. Pour cela, le privilge CREATE sur le schma
doit tre accord. Par dfaut, tout le monde bnficie des droits CREATE et USAGE sur le schma public. Cela permet tous les
utilisateurs qui peuvent se connecter une base de donnes de crer des objets dans son schma public. Si cela ne doit pas tre
le cas, ce privilge peut tre rvoqu :
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
Le premier public est le schma, le second public signifie tout utilisateur . Dans le premier cas, c'est un identifiant, dans
le second, un mot cl, d'o la casse diffrente. (Se reporter aux rgles de la Section 4.1.1, identificateurs et mots cls .)

5.7.5. Le schma du catalogue systme


En plus du schma public et de ceux crs par les utilisateurs, chaque base de donnes contient un schma pg_catalog. Celui-ci contient les tables systmes et tous les types de donnes, fonctions et oprateurs intgrs. pg_catalog est toujours dans le
chemin de recherche. S'il n'est pas nomm explicitement dans le chemin, il est parcouru implicitement avant le parcours des schmas du chemin. Cela garantit que les noms internes sont toujours accessibles. En revanche, pg_catalog peut tre explicitement
plac la fin si les noms utilisateur doivent surcharger les noms internes.
Dans les versions de PostgreSQL antrieures la 7.3, les noms de table commenant par pg_ taient rservs. Cela n'est plus
vrai : une telle table peut tre cre dans n'importe quel schma qui n'est pas un schma systme. En revanche, il est prfrable de
continuer viter d'utiliser de tels noms pour se prmunir d'ventuels conflits si une version ultrieure devait dfinir une table systme qui porte le mme nom que la table cre. (Le chemin de recherche par dfaut implique qu'une rfrence non qualifie cette
table pointe sur la table systme). Les tables systmes continueront de suivre la convention qui leur impose des noms prfixs par
pg_. Il n'y a donc pas de conflit possible avec des noms de table utilisateur non qualifis, sous rserve que les utilisateurs vitent
le prfixe pg_.

5.7.6. Utilisation
Les schmas peuvent tre utiliss de diffrentes faons pour organiser les donnes. Certaines d'entre elles, recommandes, sont facilement supports par la configuration par dfaut :

si aucun schma n'est cr, alors tous les utilisateurs ont implicitement accs au schma public. Cela permet de simuler une situation dans laquelle les schmas ne sont pas disponibles. Cette situation est essentiellement recommande lorsqu'il n'y a qu'un
utilisateur, ou un trs petit nombre d'utilisateurs qui cooprent au sein d'une base de donnes. Cette configuration permet aussi
d'oprer une transition en douceur depuis un monde o les schmas sont inconnus ;

pour chaque utilisateur, un schma, de nom identique celui de l'utilisateur, peut tre cr. Le chemin de recherche par dfaut
commence par $user, soit le nom de l'utilisateur. Si tous les utilisateurs disposent d'un schma distinct, ils accdent, par dfaut, leur propre schma. Dans cette configuration, il est possible de rvoquer l'accs au schma public (voire de supprimer
ce schma) pour confiner les utilisateurs dans leur propre schma ;

l'installation d'applications partages (tables utilisables par tout le monde, fonctionnalits supplmentaires fournies par des applications tiers, etc) peut se faire dans des schmas distincts. Il faut alors accorder des privilges appropris pour permettre aux
autres utilisateurs d'y accder. Les utilisateurs peuvent alors se rfrer ces objets additionnels en qualifiant leur nom du nom
de schma ou ajouter les schmas supplmentaires dans leur chemin de recherche, au choix.

5.7.7. Portabilit
Dans le standard SQL, la notion d'objets d'un mme schma appartenant des utilisateurs diffrents n'existe pas. De plus, certaines implantations ne permettent pas de crer des schmas de nom diffrent de celui de leur propritaire. En fait, les concepts de
schma et d'utilisateur sont presque quivalents dans un systme de base de donnes qui n'implante que le support basique des
schmas tel que spcifi dans le standard. De ce fait, beaucoup d'utilisateurs considrent les noms qualifis comme correspondant
en ralit utilisateur.table. C'est comme cela que PostgreSQL se comporte si un schma utilisateur est cr pour
chaque utilisateur.
Le concept de schma public n'existe pas non plus dans le standard SQL. Pour plus de conformit au standard, le schma public ne devrait pas tre utilis (voire tre supprim).
Certains systmes de bases de donnes n'implantent pas du tout les schmas, ou fournissent le support de namespace en autorisant
(peut-tre de faon limite) l'accs inter-bases de donnes. Dans ce cas, la portabilit maximale est obtenue en n'utilisant pas les
schmas.

51

Dfinition des donnes

5.8. L'hritage
PostgreSQL implante l'hritage des tables, qui peut s'avrer trs utile pour les concepteurs de bases de donnes. (SQL:1999 et
les versions suivantes dfinissent une fonctionnalit d'hritage de type qui diffre par de nombreux aspects des fonctionnalits dcrites ici.)
Soit l'exemple d'un modle de donnes de villes. Chaque tat comporte plusieurs villes mais une seule capitale. Pour rcuprer rapidement la ville capitale d'un tat donn, on peut crer deux tables, une pour les capitales et une pour les villes qui ne sont pas des
capitales. Mais, que se passe-t'il dans le cas o toutes les donnes d'une ville doivent tre rcupres, qu'elle soit une capitale ou
non ? L'hritage peut aider rsoudre ce problme. La table capitales est dfinie pour hriter de villes :
CREATE TABLE villes
nom
population
altitude
);

(
text,
float,
int

-- (en pied)

CREATE TABLE capitales (


etat
char(2)
) INHERITS (villes);
Dans ce cas, la table capitales hrite de toutes les colonnes de sa table parent, villes. Les capitales ont aussi une colonne supplmentaire, etat, qui indique l'tat dont elles sont capitales.
Dans PostgreSQL, une table peut hriter de zro plusieurs autres tables et une requte faire rfrence aux lignes d'une table ou
celles d'une table et de ses descendantes. Ce dernier comportement est celui par dfaut.
Par exemple, la requte suivante retourne les noms et altitudes de toutes les villes, y compris les capitales, situes une altitude
suprieure 500 pieds :
SELECT nom, altitude
FROM villes
WHERE altitude > 500;
Avec les donnes du tutoriel de PostgreSQL (voir Section 2.1, Introduction ), ceci renvoie :
nom
| altitude
-----------+---------Las Vegas |
2174
Mariposa |
1953
Madison
|
845
D'un autre ct, la requte suivante retourne les noms et altitudes de toutes les villes, qui ne sont pas des capitales, situes une altitude suprieure 500 pieds :
SELECT nom, altitude
FROM ONLY villes
WHERE altitude > 500;
nom
| altitude
-----------+---------Las Vegas |
2174
Mariposa |
1953
Le mot cl ONLY indique que la requte s'applique uniquement aux villes, et non pas toutes les tables en-dessous de villes dans
la hirarchie de l'hritage. Un grand nombre des commandes dj voques -- SELECT, UPDATE et DELETE -- supportent le
mot cl ONLY.
Vous pouvez aussi crire le nom de la table avec une * la fin pour indiquer spcifiquement que les tables filles sont inclues :
SELECT name, altitude
FROM cities*
WHERE altitude > 500;
Indiquer * n'est pas ncessaire car ce comportement est le comportement par dfaut (sauf si vous avez modifi la configuration du
paramtre sql_inheritance). Nanmoins, crire * pourrait tre utile pour insister sur le fait que des tables supplmentaires seront
parcourues.
Dans certains cas, il peut tre intressant de savoir de quelle table provient une ligne donne. Une colonne systme appele TABLEOID prsente dans chaque table donne la table d'origine :
SELECT v.tableoid, v.nom, v.altitude
52

Dfinition des donnes

FROM villes v
WHERE v.altitude > 500;
qui renvoie :
tableoid |
nom
| altitude
----------+-----------+---------139793 | Las Vegas |
2174
139793 | Mariposa |
1953
139798 | Madison
|
845
(Reproduire cet exemple conduit probablement des OID numriques diffrents). Une jointure avec pg_class, permet d'obtenir les
noms rels des tables :
SELECT p.relname, v.nom, v.altitude
FROM villes v, pg_class p
WHERE v.altitude > 500 AND v.tableoid = p.oid;
ce qui retourne :
relname
|
nom
| altitude
-----------+-----------+---------villes
| Las Vegas |
2174
villes
| Mariposa |
1953
capitales | Madison
|
845
L'hritage ne propage pas automatiquement les donnes des commandes INSERT ou COPY aux autres tables de la hirarchie de
l'hritage. Dans l'exemple considr, l'instruction INSERT suivante choue :
INSERT INTO villes (nom, population, altitude, etat)
VALUES ('New York', NULL, NULL, 'NY');
On pourrait esprer que les donnes soient magiquement routes vers la table capitales mais ce n'est pas le cas : INSERT insre
toujours dans la table indique. Dans certains cas, il est possible de rediriger l'insertion en utilisant une rgle (voir Chapitre 37,
Systme de rgles). Nanmoins, cela n'est d'aucune aide dans le cas ci-dessus car la table villes ne contient pas la colonne etat.
La commande est donc rejete avant que la rgle ne soit applique.
Toutes les contraintes de vrification et toutes les contraintes NOT NULL sur une table parent sont automatiquement hrites par
les tables enfants. Les autres types de contraintes (unicit, cl primaire, cl trangre) ne sont pas hrits.
Une table peut hriter de plusieurs tables, auquel cas elle possde l'union des colonnes dfinies par les tables mress. Toute colonne dclare dans la dfinition de la table enfant est ajoute cette dernire. Si le mme nom de colonne apparat dans plusieurs
tables mres, ou la fois dans une table mre et dans la dfinition de la table enfant, alors ces colonnes sont assembles pour
qu'il n'en existe qu'une dans la table enfant. Pour tre assembles, les colonnes doivent avoir le mme type de donnes, sinon une
erreur est leve. La colonne assemble hrite de toutes les contraintes de vrification en provenance de chaque dfinition de colonnes dont elle provient, et est marque NOT NULL si une d'entre elles l'est.
L'hritage de table est tabli la cration de la table enfant, l'aide de la clause INHERITS de l'instruction CREATE TABLE(7).
Alternativement, il est possible d'ajouter une table, dfinie de faon compatible, une nouvelle relation de parent l'aide de la
clause INHERIT de ALTER TABLE(7). Pour cela, la nouvelle table enfant doit dj inclure des colonnes de mmes nom et type
que les colonnes de la table parent. Elle doit aussi contenir des contraintes de vrification de mmes nom et expression que celles
de la table parent.
De la mme faon, un lien d'hritage peut tre supprim d'un enfant l'aide de la variante NO INHERIT d'ALTER TABLE.
Ajouter et supprimer dynamiquement des liens d'hritage de cette faon est utile quand cette relation d'hritage est utilise pour le
partitionnement des tables (voir Section 5.9, Partitionnement ).
Un moyen pratique de crer une table compatible en vue d'en faire ultrieurement une table enfant est d'utiliser la clause LIKE
dans CREATE TABLE. Ceci cre une nouvelle table avec les mme colonnes que la table source. S'il existe des contraintes
CHECK dfinies sur la table source, l'option INCLUDING CONSTRAINTS de LIKE doit tre indique car le nouvel enfant doit
avoir des contraintes qui correspondent celles du parent pour tre considre compatible.
Une table mre ne peut pas tre supprime tant qu'elle a des enfants. Pas plus que les colonnes ou les contraintes de vrification
des tables enfants ne peuvent tre supprimes ou modifies si elles sont hrites. La suppression d'une table et de tous ces descendants peut tre aisment obtenue en supprimant la table mre avec l'option CASCADE.
ALTER TABLE(7) propage toute modification dans les dfinitions des colonnes et contraintes de vrification travers la hirarchie d'hritage. L encore, supprimer des colonnes qui dpendent d'autres tables mres n'est possible qu'avec l'option CASCADE.
ALTER TABLE suit les mmes rgles d'assemblage de colonnes dupliques et de rejet que l'instruction CREATE TABLE.
Notez comment sont grs les droits d'accs aux tables. Excuter une requte sur une table parent permet automatiquement
53

Dfinition des donnes

d'accder aux donnes des tables enfants sans vrification supplmentaire sur les droits. Ceci prserve l'apparence que les donnes
proviennent de la table parent. L'accs aux tables enfants directement est, nanmoins, pas automatiquement permis et ncessitera
la vrification des droits sur ces tables.

5.8.1. Restrictions
Notez que toutes les commandes SQL fonctionnent avec les hritages. Les commandes utilises pour rcuprer des donnes, pour
modifier des donnes ou pour modifier le schma (autrement dit SELECT, UPDATE, DELETE, la plupart des variantes de ALTER
TABLE, mais pas INSERT ou ALTER TABLE ... RENAME) incluent par dfaut les tables filles et supportent la notation ONLY pour les exclure. Les commandes qui font de la maintenance de bases de donnes et de la configuration (par exemple REINDEX, VACUUM) fonctionnent typiquement uniquement sur les tables physiques, individuelles et ne supportent pas la rcursion sur
les tables de l'hritage. Le comportement respectif de chaque commande individuelle est document dans la rfrence (Commandes SQL).
Il existe une relle limitation la fonctionnalit d'hritage : les index (dont les contraintes d'unicit) et les contraintes de cls trangres ne s'appliquent qu'aux tables mres, pas leurs hritiers. Cela est valable pour le ct rfrenant et le ct rfrenc d'une
contrainte de cl trangre. Ce qui donne, dans les termes de l'exemple ci-dessus :

si villes.nom est dclare UNIQUE ou cl primaire (PRIMARY KEY), cela n'empche pas la table capitales de possder des
lignes avec des noms dupliqus dans villes. Et ces lignes upliques s'affichent par dfaut dans les requtes sur villes. En fait,
par dfaut, capitales n'a pas de contrainte d'unicit du tout et, du coup, peut contenir plusieurs lignes avec le mme nom. Une
contrainte d'unicit peut tre ajoute capitales mais cela n'empche pas la duplication avec villes ;

de faon similaire, si villes.nom fait rfrence (REFERENCES) une autre table, cette contrainte n'est pas automatiquement
propage capitales. Il est facile de contourner ce cas de figure en ajoutant manuellement la mme contrainte REFERENCES
capitales ;

si une autre table indique REFERENCES villes(nom), cela l'autorise contenir les noms des villes mais pas les noms des
capitales. Il n'existe pas de contournement efficace de ce cas.

Ces dficiences seront probablement corriges dans une version future, mais, en attendant, il est obligatoire de rflchir consciencieusement l'utilit de l'hritage pour une application donne.

5.9. Partitionnement
PostgreSQL offre un support basique du partitionnement de table. Cette section explique pourquoi et comment implanter le partitionnement lors de la conception de la base de donnes.

5.9.1. Aperu
Le partitionnement fait rfrence la division d'une table logique volumineuse en plusieurs parties physiques plus petites. Le partitionnement comporte de nombreux avantages :

les performances des requtes peuvent tre significativement amliores dans certaines situations, particulirement lorsque la
plupart des lignes fortement accdes d'une table se trouvent sur une seule partition ou sur un petit nombre de partitions. Le
partitionnement se substitue aux colonnes principales des index, rduisant ainsi la taille des index et facilitant la tenue en mmoire des parties les plus utilises de l'index ;

lorsque les requtes ou les mises jour accdent un important pourcentage d'une seule partition, les performances peuvent
tre grandement amliores par l'utilisation avantageuse de parcours squentiels sur cette partition plutt que d'utiliser un index et des lectures alatoires rparties sur toute la table ;

les chargements et suppressions importants de donnes peuvent tre obtenus par l'ajout ou la suppression de partitions, sous rserve que ce besoin ait t pris en compte lors de la conception du partitionnement. ALTER TABLE NO INHERIT et
DROP TABLE sont bien plus rapides qu'une opration de masse. Cela supprime galement la surcharge d au VACUUM
caus par un DELETE massif ;

les donnes peu utilises peuvent tre dplaces sur un mdia de stockage moins cher et plus lent.

Les bnfices ne sont rellement intressants que si cela permet d'viter une table autrement plus volumineuse. Le point
d'quilibre exact partir duquel une table tire des bnfices du partitionnement dpend de l'application. Toutefois, le partitionnement doit tre envisag si la taille de la table peut tre amene dpasser la taille de la mmoire physique du serveur.
Actuellement, PostgreSQL supporte le partitionnement travers l'hritage de tables. Chaque partition doit tre cre comme une
table enfant d'une unique table parent. La table parent est, elle, habituellement vide ; elle n'existe que pour reprsenter l'ensemble
complet des donnes. Il est impratif de matriser les concepts de l'hritage (voir Section 5.8, L'hritage ) avant de tenter
54

Dfinition des donnes

d'implanter le partitionnement.
Les formes suivantes de partitionnement peuvent tre implantes dans PostgreSQL :
Partitionnement par chelon
La table est partitionne en intervalles (ou chelles) dfinis par une colonne cl ou par un ensemble de colonnes, sans recouvrement entre les chelles de valeurs affectes aux diffrentes partitions. Il est possible, par exemple, de partitionner par
chelles de date ou par chelles d'identifiants pour des objets mtier particuliers.
Partitionnement par liste
La table est partitionne en listant explicitement les valeurs cls qui apparaissent dans chaque partition.

5.9.2. Partitionner
Pour partionner une table, la procdure est la suivante :
1. Crer la table matre . C'est de celle-ci qu'hritent toutes les partitions.
Cette table ne contient pas de donnes. Les contraintes de vrification ne doivent tre dfinies sur cette table que si elles sont
appliques toutes les partitions. Il n'y a de plus aucune raison de dfinir des index ou des contraintes d'unicit sur cette table.
2. Crer plusieurs tables filles (ou enfants) qui hritent chacune de la table matre. Normalement, ces tables n'ajoutent pas de
colonnes l'ensemble hrit du matre.
Par la suite, les tables enfants sont appeles partitions, bien qu'elles soient, en tout point, des tables PostgreSQL normales.
3. Ajouter les contraintes de tables aux tables de partitions pour dfinir les valeurs des cls autorises dans chacune.
Quelques exemples typiques :
CHECK ( x = 1 )
CHECK ( comt IN ( 'Oxfordshire', 'Buckinghamshire', 'Warwickshire' ))
CHECK ( ID >= 100 AND ID < 200 )
Les contraintes doivent garantir qu'il n'y a pas de recouvrement entre les valeurs cls autorises dans les diffrentes partitions.
Une erreur commune est de configurer des contraintes d'chelle de cette faon :
CHECK ( comt BETWEEN 100 AND 200 )
CHECK ( comt BETWEEN 200 AND 300 )
Il est dans ce cas difficile de savoir quelle partition appartient la cl 200.
Il n'y a aucune diffrence entre les syntaxes de partitionnement par chelon et de partitionnement par liste ; ces termes ne sont
que descriptifs.
4. Pour chaque partition, crer un index sur la (ou les) colonne(s) cl(s), ainsi que tout autre index ncessaire. (L'index cl n'est
pas vraiment ncessaire mais, dans la plupart des scnarios, il est utile. Si les valeurs cls doivent tre uniques, alors il faut toujours crer une contrainte d'unicit ou de cl primaire pour chaque partition.)
5. Optionnellement, dfinir un dclencheur ou une rgle pour rediriger les donnes insres dans la table matre vers la partition
approprie.
6. S'assurer que le paramtre de configuration constraint_exclusion n'est pas dsactiv dans postgresql.conf. S'il l'est, les
requtes ne sont pas optimises.
Soit la base de donnes d'une grande fabrique de glaces. La compagnie mesure le pic de temprature journalier ainsi que les ventes
de glaces dans chaque rgion. Conceptuellement, la table ressemble :
CREATE TABLE mesure
id_ville
date_trace
temperature
ventes
);

(
int not null,
date not null,
int,
int

La plupart des requtes n'accdent qu'aux donnes de la dernire semaine, du dernier mois ou du dernier trimestre car cette table
est essentiellement utilise pour prparer des rapports en ligne pour la direction. Pour rduire le nombre de donnes anciennes
stocker, seules les trois dernires annes sont conserves. Au dbut de chaque mois, les donnes du mois le plus ancien sont supprimes.
Dans cette situation, le partitionnement permet de rpondre aux diffrents besoins identifis sur la table des mesures. En suivant
les tapes indiques ci-dessus, le partitionnement peut tre configur de la faon suivante :
1. la table matre est la table mesure, dclare exactement comme ci-dessus ;
2. une partition est ensuite cre pour chaque mois actif :
55

Dfinition des donnes

CREATE
CREATE
...
CREATE
CREATE
CREATE

TABLE mesure_a2006m02 ( ) INHERITS (mesure);


TABLE mesure_a2006m03 ( ) INHERIT (mesure);
TABLE mesure_a2007m11 ( ) INHERITS (mesure);
TABLE mesure_a2007m12 ( ) INHERITS (mesure);
TABLE mesure_a2008m01 ( ) INHERITS (mesure);

Chaque partition est une table part entire mais sa dfinition est hrite de la table mesure.
Ceci rsoud un des problmes : la suppression d'anciennes donnes. Chaque mois, il suffit d'effectuer un DROP TABLE sur la
table enfant la plus ancienne et de crer une nouvelle table enfant pour les donnes du nouveau mois.
3. Il est ncessaire de fournir des contraintes de table qui interdisent les recouvrements. Plutt que de simplement crer les tables
de la partition comme ci-dessus, le script de cration de tables ressemble ;
CREATE TABLE mesure_a2006m02 (
CHECK ( date_trace >= DATE
) INHERITS (mesure);
CREATE TABLE mesure_a2006m03 (
CHECK ( date_trace >= DATE
) INHERITS (mesure);
...
CREATE TABLE mesure_a2007m11 (
CHECK ( date_trace >= DATE
) INHERITS (mesure);
CREATE TABLE mesure_a2007m12 (
CHECK ( date_trace >= DATE
) INHERITS (mesure);
CREATE TABLE mesure_a2008m01 (
CHECK ( date_trace >= DATE
) INHERITS (mesure);

'2006-02-01' AND date_trace < DATE '2006-03-01' )


'2006-03-01' AND date_trace < DATE '2006-04-01' )

'2007-11-01' AND date_trace < DATE '2007-12-01' )


'2007-12-01' AND date_trace < DATE '2007-01-01' )
'2008-01-01' AND date_trace < DATE '2008-02-01' )

4. Des index sur les colonnes cls sont probablement ncessaires :


CREATE
CREATE
...
CREATE
CREATE
CREATE

INDEX mesure_a2006m02_date_trace ON mesure_a2006m02 (date_trace);


INDEX mesure_a2006m03_date_trace ON mesure_a2006m03 (date_trace);
INDEX mesure_a2007m11_date_trace ON mesure_a2007m11 (date_trace);
INDEX mesure_a2007m12_date_trace ON mesure_a2007m12 (date_trace);
INDEX mesure_a2008m01_date_trace ON mesure_a2008m01 (date_trace);

ce stade, c'est suffisant.


5. L'application doit dire INSERT INTO mesure... et les donnes tre rediriges dans la table de partition approprie. Pour
cela une fonction dclencheur est attache la table matre. Si les donnes ne sont ajoutes que dans la dernire partition, la
fonction est trs simple.
CREATE OR REPLACE FUNCTION mesure_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO mesure_a2008m01 VALUES (NEW.*);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
Le dclencheur qui appelle la fonction est cr sa suite :
CREATE TRIGGER insert_mesure_trigger
BEFORE INSERT ON mesure
FOR EACH ROW EXECUTE PROCEDURE mesure_insert_trigger();
La fonction dclencheur doit tre redfinie chaque mois pour qu'elle pointe toujours sur la partition active. La dfinition du dclencheur n'a pas besoin d'tre redfinie.
Il est galement possible de laisser le serveur localiser la partition dans laquelle doit tre insre la ligne propose en entre.
Une fonction dclencheur plus complexe peut tre utilise pour cela :
CREATE OR REPLACE FUNCTION mesure_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
56

Dfinition des donnes

IF ( NEW.date_trace >= DATE '2006-02-01' AND


NEW.date_trace < DATE '2006-03-01' ) THEN
INSERT INTO mesure_a2006m02 VALUES (NEW.*);
ELSIF ( NEW.date_trace >= DATE '2006-03-01' AND
NEW.date_trace < DATE '2006-04-01' ) THEN
INSERT INTO mesure_a2006m03 VALUES (NEW.*);
...
ELSIF ( NEW.date_trace >= DATE '2008-01-01' AND
NEW.date_trace < DATE '2008-02-01' ) THEN
INSERT INTO mesure_a2008m01 VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'Date en dehors de l''chelle. Corrigez la fonction
mesure_insert_trigger() !';
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
La dfinition du dclencheur ne change pas. Chaque test IF doit correspondre exactement la contrainte CHECK de cette partition.
Bien que cette fonction soit plus complexe que celle du mois seul, il n'est pas ncessaire de l'actualiser aussi frquemment, les
branches pouvant tre ajoutes avant d'tre utiles.

Note
En pratique, il pourrait prfrable de vrifier prioritairement la dernire partition cre si la plupart des insertions lui sont destines. Pour des raisons de simplicit, les tests du dclencheur sont prsents dans le mme
ordre que les autres parties de l'exemple.
Un schma complexe de partitionnement peut amener crire une grande quantit de DDL. Dans l'exemple ci-dessus, une nouvelle partition est crite chaque mois. Il est donc conseill d'crire un script qui engendre automatiquement la DDL requise.

5.9.3. Grer les partitions


Gnralement, l'ensemble des partitions tablies lors de la dfinition initiale de la table n'a pas pour but de rester statique. Il n'est
pas inhabituel de supprimer d'anciennes partitions de donnes et d'en ajouter priodiquement de nouvelles pour de nouvelles donnes. Un des principaux avantages du partitionnement est prcisment qu'il autorise une excution quasi-instantane de cette
tche, bien plus difficile autrement, en permettant la manipulation de la structure de la partition, plutt que de dplacer physiquement de grands volumes de donnes.
L'option la plus simple pour supprimer d'anciennes donnes consiste supprimer la partition qui n'est plus ncessaire :
DROP TABLE mesure_a2006m02;
Cela permet de supprimer trs rapidement des millions d'enregistrements car il n'est nul besoin de supprimer sparment chaque
enregistrement.
Une autre option, souvent prfrable, consiste supprimer la partition de la table partitionne mais de conserver l'accs la table
en tant que telle :
ALTER TABLE mesure_a2006m02 NO INHERIT mesure;
Ceci permet la ralisation d'oprations ultrieures sur les donnes avant qu'elles ne soient supprimes. Par exemple, c'est souvent
le bon moment pour sauvegarder les donnes en utilisant COPY, pg_dump ou tout autres outil. C'est aussi le moment d'agrger
des donnes en des formats plus denses, de raliser d'autres oprations sur les donnes ou de crer des rapports.
De faon similaire, une nouvelle partition peut tre ajoute pour grer les nouvelles donnes. Une partition vide peut tre cre
dans la table partitionne de la mme faon que les partitions individuelles cres plus haut :
CREATE TABLE mesure_a2008m02 (
CHECK ( date_trace >= DATE '2008-02-01' AND date_trace < DATE '2008-03-01' )
) INHERITS (mesure);
Alternativement, il est parfois plus intressant de crer la nouvelle table en dehors de la structure de partitionnement et de la transformer en une partition adquate plus tard. Cela permet de charger les donnes, les vrifier et les transformer avant leur apparition
dans la table partitionne :
57

Dfinition des donnes

CREATE TABLE mesure_a2008m02


(LIKE mesure INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
ALTER TABLE mesure_a2008m02 ADD CONSTRAINT y2008m02
CHECK ( date_trace >= DATE '2008-02-01' AND date_trace < DATE '2008-03-01' );
\copy mesure_a2008m02 from 'mesure_a2008m02'
-- quelques travaux de prparation des donnes
ALTER TABLE mesure_a2008m02 INHERIT mesure;

5.9.4. Partitionnement et exclusion de contrainte


L'exclusion de contrainte est une technique d'optimisation des requtes pour amliorer les performances sur les tables partitionnes telles que dcrites plus haut. Par exemple :
SET constraint_exclusion = on;
SELECT count(*) FROM mesure WHERE date_trace >= DATE '2008-01-01';
Sans exclusion de contrainte, la requte ci-dessus parcourt chacune des partitions de la table mesure. Avec l'exclusion de
contrainte active, le planificateur examine les contraintes de chaque partition et tente de prouver que la partition qui n'a pas besoin d'tre parcourue parce qu'elle ne peut pas contenir de lignes correspondant la clause WHERE de la requte. Quand le planificateur peut le prouver, il exclut la partition du plan de requte.
La commande EXPLAIN permet d'afficher la diffrence entre un plan avec constraint_exclusion activ (on) et un plan
avec ce paramtre dsactiv (off). Un plan typique non optimis pour ce type de table est :
SET constraint_exclusion = off;
EXPLAIN SELECT count(*) FROM mesure WHERE date_trace >= DATE '2008-01-01';
QUERY PLAN
------------------------------------------------------------------------------------Aggregate (cost=158.66..158.68 rows=1 width=0)
-> Append (cost=0.00..151.88 rows=2715 width=0)
-> Seq Scan on mesure (cost=0.00..30.38 rows=543 width=0)
Filter: (date_trace >= '2008-01-01'::date)
-> Seq Scan on mesure_a2006m02 mesure (cost=0.00..30.38 rows=543 width=0)
Filter: (date_trace >= '2008-01-01'::date)
-> Seq Scan on mesure_ay2006m03 mesure (cost=0.00..30.38 rows=543 width=0)
Filter: (date_trace >= '2008-01-01'::date)
...
-> Seq Scan on mesure_a2007m12 mesure (cost=0.00..30.38 rows=543 width=0)
Filter: (date_trace >= '2008-01-01'::date)
-> Seq Scan on mesure_a2008m01 mesure (cost=0.00..30.38 rows=543 width=0)
Filter: (date_trace >= '2008-01-01'::date)
Quelques partitions, voire toutes, peuvent utiliser des parcours d'index la place des parcours squentiels de la table complte
mais le fait est qu'il n'est pas besoin de parcourir les anciennes partitions pour rpondre cette requte. Lorsque l'exclusion de
contrainte est active, un plan significativement moins coteux est obtenu, qui dlivre la mme rponse :
SET constraint_exclusion = on;
EXPLAIN SELECT count(*) FROM mesure WHERE date_trace >= DATE '2008-01-01';
QUERY PLAN
------------------------------------------------------------------------------------Aggregate (cost=63.47..63.48 rows=1 width=0)
-> Append (cost=0.00..60.75 rows=1086 width=0)
-> Seq Scan on mesure (cost=0.00..30.38 rows=543 width=0)
Filter: (date_trace >= '2008-01-01'::date)
-> Seq Scan on mesure_a2008m01 mesure (cost=0.00..30.38 rows=543 width=0)
Filter: (date_trace >= '2008-01-01'::date)
L'exclusion de contraintes n'est pilote que par les contraintes CHECK, pas par la prsence d'index. Il n'est donc pas ncessaire de
dfinir des index sur les colonnes cls. Le fait qu'un index doive tre cr pour une partition donne dpend de ce que les requtes
qui parcourent la partition parcourent en gnral une grande partie de la partition ou seulement une petite partie. Un index est utile
dans le dernier cas, pas dans le premier.
La valeur par dfaut (et donc recommande) de constraint_exclusion n'est ni on ni off, mais un tat intermdiaire appel partition, qui fait que la technique est applique seulement aux requtes qui semblent fonctionner avec des tables partitionnes. La
valeur on fait que le planificateur examine les contraintes CHECK dans chaque requte, y compris les requtes simples qui ont peu
de chance d'en profiter.

58

Dfinition des donnes

5.9.5. Autre mthode de partitionnement


Une approche diffrente pour la redirection des insertions dans la table fille approprie est de configurer des rgles, la place d'un
dclencheur, sur la table matre. Par exemple :
CREATE RULE mesure_insert_a2006m02 AS
ON INSERT TO mesure WHERE
( date_trace >= DATE '2006-02-01' AND date_trace < DATE '2006-03-01' )
DO INSTEAD
INSERT INTO mesure_a2006m02 VALUES (NEW.*);
...
CREATE RULE mesure_insert_a2008m01 AS
ON INSERT TO mesure WHERE
( date_trace >= DATE '2008-01-01' AND date_trace < DATE '2008-02-01' )
DO INSTEAD
INSERT INTO mesure_a2008m01 VALUES (NEW.*);
Une rgle est plus coteuse qu'un dclencheur mais ce cot est pay une fois par requte au lieu d'une fois par ligne, cette mthode
peut donc s'avrer avantageuse lors de grosses insertions. Nanmoins, dans la majorit des cas, la mthode du trigger offre de
meilleures performances.
La commande COPY ignore les rgles. Si COPY est utilis pour insrer des donnes, la copie doit tre effectue sur la partition
adquate plutt que dans la table matre. COPY active les dclencheurs. Elle peut donc tre utilise normalement lorsque cette approche est choisie.
Un autre inconvnient de la mthode des rgles est qu'il n'existe pas de moyens simples de forcer une erreur si l'ensemble des
rgles ne couvre pas la date d'insertion. La donne est alors silencieusement insre dans la table matre.
Le partitionnement peut aussi tre arrang l'aide d'une vue UNION ALL, en lieu et place de l'hritage. Par exemple :
CREATE VIEW mesure
SELECT *
UNION ALL SELECT *
...
UNION ALL SELECT *
UNION ALL SELECT *
UNION ALL SELECT *

AS
FROM mesure_a2006m02
FROM mesure_a2006m03
FROM mesure_a2007m11
FROM mesure_a2007m12
FROM mesure_a2008m01;

Nanmoins, le besoin de recrer la vue ajoute une tape supplmentaire l'ajout et la suppression de partitions individuelles de
l'ensemble des donnes. En pratique, cette mthode a peu d'intrt au regard de l'hritage.

5.9.6. Restrictions
Les restrictions suivantes s'appliquent aux tables partitionnes :

il n'existe pas de moyen automatique de vrifier que toutes les contraintes de vrification (CHECK) sont mutuellement exclusives. Il est plus sr de crer un code qui fabrique les partitions et cre et/ou modifie les objets associs plutt que de les crer
manuellement ;

les schmas montrs ici supposent que les colonnes cls du partitionnement d'une ligne ne changent jamais ou, tout du moins,
ne changent pas suffisamment pour ncessiter un dplacement vers une autre partition. Une commande UPDATE qui tente de
le faire choue cause des contraintes CHECK. Pour grer ce type de cas, des dclencheurs peuvent tre convenablement positionns pour la mise jour sur les tables de partition mais cela rend la gestion de la structure beaucoup plus complexe.

si VACUUM ou ANALYZE sont lancs manuellement, il est obligatoire de les utiliser sur chaque partition. Une commande
comme :
ANALYZE mesure;
ne traite que la table matre.

Les restrictions suivantes s'appliquent l'exclusion de contraintes :

l'exclusion de contrainte ne fonctionne que si la clause WHERE de la requte contient des constantes. Une requte avec paramtre n'est pas optimise car le planificateur ne peut avoir connaissance au pralable des partitions slectionnes par la valeur
du paramtre l'excution. Pour la mme raison, il faut viter les fonctions stable s comme CURRENT_DATE ;

59

Dfinition des donnes

les contraintes de partitionnement doivent rester simples. Dans le cas contraire, le planificateur peut rencontrer des difficults
dterminer les partitions qu'il n'est pas ncessaire de parcourir. Des conditions simples d'galit pour le partitionnement de
liste ou des tests d'chelle simples lors de partitionnement d'chelle sont recommandes, comme cela est illustr dans les
exemples prcdents. Une bonne rgle consiste s'assurer que les comparaisons entre colonnes de partitionnement et
constantes utilises par les contraintes de partitionnement se fassent uniquement l'aide d'oprateurs utilisables par les index
B-tree.

toutes les contraintes de toutes les partitions de la table matre sont examines lors de l'exclusion de contraintes. De ce fait, un
grand nombre de partitions augmente considrablement le temps de planification de la requte. Un partitionnement qui utilise
ces techniques fonctionne assez bien jusqu'environ une centaine de partitions ; il est impensable de vouloir atteindre des milliers de partitions.

5.10. Donnes distantes


PostgreSQL implmente des portions de la norme SQL/MED, vous permettant d'accder des donnes qui rsident en dehors
de PostgreSQL en utilisant des requtes SQL standards. On utilise le terme de donnes distantes pour de telles donnes. (Notez
que cet usage ne doit pas tre confondu avec les cls trangres qui sont un type de contrainte l'intrieur d'une base de donnes.)
Les donnes distantes sont accdes grce un wrapper de donnes distantes. Ce dernier est une bibliothque qui peut communiquer avec une source de donnes externe, cachant les dtails de la connexion vers la source de donnes et de la rcupration des
donnes partir de cette source. Il existe un wrapper de donnes distantes disponible en tant que module contrib qui peut lire
des fichiers de donnes plat rsidant sur le serveur. D'autres types de wrappers de donnes distantes peuvent faire partie de produits tiers. Si aucun des wrappers de donnes distantes ne vous convient, vous pouvez crire le votre. Voir Chapitre 50, crire un
wrapper de donnes distantes.
Pour accder aux donnes distantes, vous devez crer un objet de type serveur distant qui dfinit la faon de se connecter une
source de donnes externes particulire suivant un ensemble d'options utilises par un wrapper de donnes distantes. Ensuite, vous
aurez besoin de crer une ou plusieurs tables distantes, qui dfinissent la structure des donnes distantes. Une table distante peut
tre utilise dans des requtes comme tout autre table, mais une table distante n'est pas stocke sur le serveur PostgreSQL.
chaque utilisation, PostgreSQL demande au wrapper de donnes distantes de rcuprer les donnes provenant de la source externe.
Accder des donnes distantes pourrait ncessiter une authentification auprs de la source de donnes externes. Cette information peut tre passe par une correspondance d'utilisateur, qui peut fournir des options supplmentaires en se basant sur le rle
PostgreSQL actuel.
Actuellement, les tables distantes sont en lecture sule. Cette limitation sera peut-tre corrige dans une version future.

5.11. Autres objets de la base de donnes


Les tables sont les objets centraux dans une structure de base de donnes relationnelles, car ce sont elles qui stockent les donnes.
Mais ce ne sont pas les seuls objets qui existent dans une base de donnes. De nombreux autres types d'objets peuvent tre crs
afin de rendre l'utilisation et la gestion des donnes plus efficace ou pratique. Ils ne sont pas abords dans ce chapitre mais une
liste en est dresse titre d'information.

Vues

Fonctions et oprateurs

Types de donnes et domaines

Dclencheurs et rgles de rcriture

Des informations dtailles sur ces sujets apparaissent dans la Partie V, Programmation serveur .

5.12. Gestion des dpendances


Lorsque des structures de base complexes sont cres qui impliquent beaucoup de tables avec des contraintes de cls trangres,
des vues, des dclencheurs, des fonctions, etc., un rseau de dpendances entre les objets est implicitement cr. Par exemple, une
table avec une contrainte de cl trangre dpend de la table laquelle elle fait rfrence.
Pour garantir l'intgrit de la structure entire de la base, PostgreSQL s'assure qu'un objet dont d'autres objets dpendent ne peut
pas tre supprim. Ainsi, toute tentative de suppression de la table des produits utilise dans la Section 5.3.5, Cls trangres ,
sachant que la table des commandes en dpend, lve un message d'erreur comme celui-ci :
DROP TABLE produits;
60

Dfinition des donnes

NOTICE: constraint commandes_no_produit_fkey on table commandes depends on table


produits
ERROR: cannot drop table produits because other objects depend on it
HINT: Use DROP ... CASCADE to drop the dependent objects too.
ou en franais :
DROP TABLE produits;
NOTICE: la contrainte commandes_no_produit_fkey sur la table commandes dpend
de la table produits
ERREUR: la table produits ne peut pas tre supprime, car d'autre objets en
dpendent
HINT: Utiliser DROP ... CASCADE pour supprimer galement les objets
dpendants.
Le message d'erreur contient un indice utile : pour ne pas avoir supprimer individuellement chaque objet dpendant, on peut lancer
DROP TABLE produits CASCADE;
et tous les objets dpendants sont ainsi effacs. Dans ce cas, la table des commandes n'est pas supprime, mais seulement la
contrainte de cl trangre. (Pour vrifier ce que fait DROP ... CASCADE, on peut lancer DROP sans CASCADE et lire les messages NOTICE.)
Toutes les commandes de suppression dans PostgreSQL supportent l'utilisation de CASCADE. La nature des dpendances est
videmment fonction de la nature des objets. On peut aussi crire RESTRICT au lieu de CASCADE pour obtenir le comportement
par dfaut, savoir interdire les suppressions d'objets dont dpendent d'autres objets.

Note
D'aprs le standard SQL, il est ncessaire d'indiquer RESTRICT ou CASCADE. Aucun systme de base de donne
ne force cette rgle, en ralit, mais le choix du comportement par dfaut, RESTRICT ou CASCADE, varie suivant
le systme.

Note
Les dpendances de contraintes de cls trangres et de colonnes serial des versions de PostgreSQL antrieures
7.3 ne sont pas maintenues ou cres pendant le processus de mise jour. Tout autre type de dpendance est proprement cr pendant une mise jour partir d'une base de donnes antrieure la 7.3.

61

Chapitre 6. Manipulation de donnes


Ce chapitre est toujours assez incomplet.
Le chapitre prcdent prsente la cration des tables et des autres structures de stockage des donnes. Il est temps de remplir ces
tables avec des donnes. Le prsent chapitre couvre l'insertion, la mise jour et la suppression des donnes des tables. Aprs cela, le chapitre prsente l'limination des donnes perdues.

6.1. Insrer des donnes


Quand une table est cre, elle ne contient aucune donne. La premire chose faire, c'est d'y insrer des donnes. Sans quoi la
base de donnes n'est pas d'une grande utilit. Les donnes sont conceptuellement insres ligne par ligne. Il est videmment
possible d'insrer plus d'une ligne, mais il n'est pas possible d'entrer moins d'une ligne. Mme lorsque seules les valeurs d'une
partie des colonnes sont connues, une ligne complte doit tre cre.
Pour crer une nouvelle ligne, la commande INSERT(7) est utilise. La commande a besoin du nom de la table et des valeurs de
colonnes.
Soit la table des produits du Chapitre 5, Dfinition des donnes :
CREATE TABLE produits (
no_produit integer,
nom text,
prix numeric
);
Une commande d'insertion d'une ligne peut tre :
INSERT INTO produits VALUES (1, 'Fromage', 9.99);
Les donnes sont listes dans l'ordre des colonnes de la table, spares par des virgules. Souvent, les donnes sont des libells
(constantes) mais les expressions scalaires sont aussi acceptes.
La syntaxe prcdente oblige connatre l'ordre des colonnes. Pour viter cela, les colonnes peuvent tre explicitement listes.
Les deux commandes suivantes ont, ainsi, le mme effet que la prcdente :
INSERT INTO produits (no_produit, nom, prix) VALUES (1, 'Fromage', 9.99);
INSERT INTO produits (nom, prix, no_produit) VALUES ('Fromage', 9.99, 1);
Beaucoup d'utilisateurs recommandent de toujours lister les noms de colonnes.
Si les valeurs de certaines colonnes ne sont pas connues, elles peuvent tre omises. Dans ce cas, elles sont remplies avec leur valeur par dfaut. Par exemple :
INSERT INTO produits (no_produit, nom) VALUES (1, 'Fromage');
INSERT INTO produits VALUES (1, 'Fromage');
La seconde instruction est une extension PostgreSQL. Elle remplit les colonnes de gauche droite avec toutes les valeurs
donnes, et les autres prennent leur valeur par dfaut.
Il est possible, pour plus de clart, d'appeler explicitement les valeurs par dfaut pour des colonnes particulires ou pour la ligne
complte.
INSERT INTO produits (no_produit, nom, prix) VALUES (1, 'Fromage', DEFAULT);
INSERT INTO produits DEFAULT VALUES;
Plusieurs lignes peuvent tre insres en une seule commande :
INSERT INTO produits (no_produit, nom, prix) VALUES
(1, 'Fromage', 9.99),
(2, 'Pain', 1.99),
(3, 'Lait', 2.99);

Astuce
Lors de l'insertion d'une grande quantit de donnes en mme temps, il est prfrable d'utiliser la commande COPY(7). Elle n'est pas aussi flexible que la commande INSERT(7) mais elle est plus efficace. Se rfrer Section 14.4, Remplir une base de donnes pour plus d'informations sur l'amlioration des performances lors de
62

Manipulation de donnes

gros chargements de donnes.

6.2. Actualiser les donnes


La modification de donnes prsentes en base est appele mise jour ou actualisation (update en anglais). Il est possible de mettre
jour une ligne spcifique, toutes les lignes ou un sous-ensemble de lignes de la table. Chaque colonne peut tre actualise sparment ; les autres colonnes ne sont alors pas modifies.
Pour mettre jour les lignes existantes, utilisez la commande UPDATE(7). Trois informations sont ncessaires :
1. le nom de la table et de la colonne mettre jour ;
2. la nouvelle valeur de la colonne ;
3. les lignes mettre jour.
Comme cela a t vu dans le Chapitre 5, Dfinition des donnes, le SQL ne donne pas, par dfaut, d'identifiant unique pour les
lignes. Il n'est, de ce fait, pas toujours possible d'indiquer directement la ligne mettre jour. On prcise plutt les conditions
qu'une ligne doit remplir pour tre mise jour. Si la table possde une cl primaire (qu'elle soit dclare ou non), une ligne unique
peut tre choisie en prcisant une condition sur la cl primaire. Les outils graphiques d'accs aux bases de donnes utilisent ce
principe pour permettre les modifications de lignes individuelles.
La commande suivante, par exemple, modifie tous les produits dont le prix est 5 en le passant 10.
UPDATE produits SET prix = 10 WHERE prix = 5;
Cela peut mettre jour zro, une, ou plusieurs lignes. L'excution d'une commande UPDATE qui ne met jour aucune ligne ne reprsente pas une erreur.
Dans le dtail de la commande, on trouve tout d'abord, le mot cl UPDATE suivi du nom de la table. Le nom de la table peut toujours tre prfix par un nom de schma dans le cas contraire elle est recherche dans le chemin. On trouve ensuite le mot cl
SET suivi du nom de la colonne, un signe gal et la nouvelle valeur de la colonne, qui peut tre une constante ou une expression
scalaire.
Par exemple, pour augmenter de 10% le prix de tous les produits, on peut excuter :
UPDATE produits SET prix = prix * 1.10;
L'expression donnant la nouvelle valeur peut faire rfrence aux valeurs courantes de la ligne.
Il n'a pas t indiqu ici de clause WHERE. Si elle est omise, toutes les lignes de la table sont modifies. Si elle est prsente, seules
les lignes qui remplissent la condition WHERE sont mises jour. Le signe gal dans la clause SET ralise une affectation, alors que
celui de la clause WHERE permet une comparaison. Pour autant, cela ne cre pas d'ambigut. La condition WHERE n'est pas ncessairement un test d'galit de nombreux autres oprateurs existent (voir le Chapitre 9, Fonctions et oprateurs). Mais le rsultat de
l'expression est boolen.
Il est possible d'actualiser plusieurs colonnes en une seule commande UPDATE par l'indication de plusieurs colonnes dans la
clause SET.
Par exemple :
UPDATE ma_table SET a = 5, b = 3, c = 1 WHERE a > 0;

6.3. Supprimer des donnes


Les parties prcdentes prsentent l'ajout et la modification de donnes. Il reste voir leur suppression quand elles ne sont plus ncessaires. Comme pour l'insertion, la suppression ne peut se faire que par ligne entire. Le SQL ne propose pas de moyen
d'accder une ligne particulire. C'est pourquoi la suppression de lignes se fait en indiquant les conditions remplir par les lignes
supprimer. S'il y a une cl primaire dans la table, alors il est possible d'indiquer prcisment la ligne supprimer. Mais on peut
aussi supprimer un groupe de lignes qui remplissent une condition, ou mme toutes les lignes d'une table en une fois.
Pour supprimer des lignes, on utilise la commande DELETE(7) ; la syntaxe est trs similaire la commande UPDATE.
Par exemple, pour supprimer toutes les lignes de la table produits qui ont un prix de 10, on excute :
DELETE FROM produits WHERE prix = 10;
En indiquant simplement :
DELETE FROM produits;
63

Manipulation de donnes

on supprime toutes les lignes de la table. Attention aux mauvaises manipulations !

64

Chapitre 7. Requtes
Les prcdents chapitres ont expliqu comme crer des tables, comment les remplir avec des donnes et comment manipuler ces
donnes. Maintenant, nous discutons enfin de la faon de rcuprer ces donnes depuis la base de donnes.

7.1. Aperu
Le processus et la commande de rcupration des donnes sont appels une requte. En SQL, la commande SELECT(7) est utilise pour spcifier des requtes. La syntaxe gnrale de la commande SELECT est
[WITH with_requtes] SELECT liste_select FROM expression_table [specification_tri]
Les sections suivantes dcrivent le dtail de la liste de slection, l'expression des tables et la spcification du tri. Les requtes
WITH sont traites en dernier car il s'agit d'une fonctionnalit avance.
Un type de requte simple est de la forme :
SELECT * FROM table1;
En supposant qu'il existe une table appele table1, cette commande rcuprera toutes les lignes et toutes les colonnes de
table1. La mthode de rcupration dpend de l'application cliente. Par exemple, le programme psql affichera une table,
faon art ASCII, alors que les bibliothques du client offriront des fonctions d'extraction de valeurs individuelles partir du rsultat de la requte. * comme liste de slection signifie que toutes les colonnes de l'expression de table seront rcupres. Une
liste de slection peut aussi tre un sous-ensemble des colonnes disponibles ou effectuer un calcul en utilisant les colonnes. Par
exemple, si table1 dispose des colonnes nommes a, b et c (et peut-tre d'autres), vous pouvez lancer la requte suivante :
SELECT a, b + c FROM table1;
(en supposant que b et c soient de type numrique). Voir la Section 7.3, Listes de slection pour plus de dtails.
FROM table1 est un type trs simple d'expression de tables : il lit une seule table. En gnral, les expressions de tables sont
des constructions complexes de tables de base, de jointures et de sous-requtes. Mais vous pouvez aussi entirement omettre
l'expression de table et utiliser la commande SELECT comme une calculatrice :
SELECT 3 * 4;
Ceci est plus utile si les expressions de la liste de slection renvoient des rsultats variants. Par exemple, vous pouvez appeler
une fonction de cette faon :
SELECT random();

7.2. Expressions de table


Une expression de table calcule une table. L'expression de table contient une clause FROM qui peut tre suivie des clauses
WHERE, GROUP BY et HAVING. Les expressions triviales de table font simplement rfrence une table sur le disque, une
table de base, mais des expressions plus complexes peuvent tre utilises pour modifier ou combiner des tables de base de diffrentes faons.
Les clauses optionnelles WHERE, GROUP BY et HAVING dans l'expression de table spcifient un tube de transformations successives ralises sur la table drive de la clause FROM. Toutes ces transformations produisent une table virtuelle fournissant
les lignes passer la liste de slection qui choisira les lignes afficher de la requte.

7.2.1. Clause FROM


La la section intitule Clause FROM drive une table partir d'une ou plusieurs tables donnes dans une liste de rfrence
dont les tables sont spares par des virgules.
FROM reference_table [, reference_table [, ...]]
Une rfrence de table pourrait tre un nom de table (avec en option le nom du schma) ou une table drive comme une sousrequte, une table jointe ou une combinaison complexe de celles-ci. Si plus d'une rfrence de tables est liste dans la clause
FROM, elle sont jointes pour former une table virtuelle intermdiaire qui pourrait tre le sujet des transformations des clauses
WHERE, GROUP BY et HAVING, et est finalement le rsultat des expressions de table.
Lorsqu'une rfrence de table nomme une table qui est la table parent d'une table suivant la hirarchie de l'hritage, la rfrence
de table produit les lignes non seulement de la table mais aussi des descendants de cette table sauf si le mot cl ONLY prcde le
nom de la table. Nanmoins, la rfrence produit seulement les colonnes qui apparaissent dans la table nomme... toute colonne
65

Requtes

ajoute dans une sous-table est ignore.


Au lieu d'crire ONLY avant le nom de la table, vous pouvez crire * aprs le nom de la table pour indiquer spcifiquement que les
tables filles sont inclues. crire * n'est pas ncessaire car il s'agit du comportement par dfaut (sauf si vous avez choisi de modifier la configuration de sql_inheritance). Nanmoins, crire * peut tre utile pour indiquer fortement que les tables filles seront
parcourues.

7.2.1.1. Tables jointes


Une table jointe est une table drive de deux autres tables (relles ou drives) suivant les rgles du type de jointure particulier.
Les jointures internes (inner), externes (outer) et croises (cross) sont disponibles.
Types de jointures

Jointure croise (cross join)


T1 CROSS JOIN T2
Pour chaque combinaison possible de lignes provenant de T1 et T2 (c'est--dire un produit cartsien), la table jointe contiendra une ligne disposant de toutes les colonnes de T1 suivies par toutes les colonnes de T2. Si les tables ont respectivement N
et M lignes, la table jointe en aura N * M.
FROM T1 CROSS JOIN T2 est quivalent FROM T1, T2. C'est aussi quivalent FROM T1 INNER JOIN T2 ON
TRUE (voir ci-dessous).
Jointures qualifies (qualified joins)
T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 ON expression_booleenne
T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 USING ( liste des colonnes
jointes )
T1 NATURAL { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2
Les mots INNER et OUTER sont optionnels dans toutes les formes. INNER est la valeur par dfaut ; LEFT, RIGHT et FULL
impliquent une jointure externe.
La condition de la jointure est spcifie dans la clause ON ou USING, ou implicitement par le mot NATURAL. La condition de
jointure dtermine les lignes des deux tables source considres comme correspondante , comme l'explique le paragraphe
ci-dessous.
La clause ON est le type le plus gnral de condition de jointure : il prend une expression boolenne du mme genre que celle
utilise dans une clause WHERE. Une paires de lignes de T1 et T2 correspondent si l'expression ON est value vraie (true)
pour ces deux lignes.
USING est la notation raccourcie : elle prend une liste de noms de colonnes, spars par des virgules, que les tables jointes
ont en commun, et forme une condition de jointure spcifiant l'galit de chacune de ces paires de colonnes. De plus, la sortie
de JOIN USING a une colonne pour chaque paires gales des colonnes en entre, suivies par toutes les autres colonnes de
chaque table. Du coup, USING (a, b, c) est quivalent ON (t1.a = t2.a AND t1.b = t2.b AND t1.c =
t2.c) avec l'exception que si ON est utilis, il y aura deux colonnes a, b, puis c dans le rsultat, alors qu'avec USING, il n'y
en aurait eu qu'une de chaque (et elles apparatront en premier si SELECT * est utilis).
Enfin, NATURAL est un format raccourci de USING : il forme une liste USING consistant de tous les noms de colonnes apparaissant la fois dans les deux tables en entre. Comme avec USING, ces colonnes apparaissent seulement une fois dans la
table de sortie. S'il n'y a pas de colonnes communes, NATURAL se comporte comme CROSS JOIN.
Les types possibles de jointures qualifies sont :
INNER JOIN
Pour chaque ligne R1 de T1, la table jointe a une ligne pour chaque ligne de T2 satisfaisant la condition de jointure avec R1.
LEFT OUTER JOIN
Tout d'abord, une jointure interne est ralise. Puis, pour chaque ligne de T1 qui ne satisfait pas la condition de jointure avec
les lignes de T2, une ligne jointe est ajoute avec des valeurs NULL dans les colonnes de T2. Du coup, la table jointe a toujours au moins une ligne pour chaque ligne de T1 quelque soient les conditions.
RIGHT OUTER JOIN
Tout d'abord, une jointure interne est ralise. Puis, pour chaque ligne de T2 qui ne satisfait pas la condition de jointure avec
les lignes de T1, une ligne jointe est ajoute avec des valeurs NULL dans les colonnes de T1. C'est l'inverse d'une jointure
gauche : la table rsultante aura toujours une ligne pour chaque ligne de T2 quelque soient les conditions.
66

Requtes

FULL OUTER JOIN


Tout d'abord, une jointure interne est ralise. Puis, pour chaque ligne de T1 qui ne satisfait pas la condition de jointure avec
les lignes de T2, une ligne jointe est ajoute avec des valeurs NULL dans les colonnes de T2. De plus, pour chaque ligne de
T2 qui ne satisfait pas la condition de jointure avec les lignes de T1, une ligne jointe est ajoute avec des valeurs NULL dans
les colonnes de T1.
Les jointures de tous les types peuvent tre chanes ensemble ou imbriques : soit les deux soit une des deux, parmi T1 et T2,
peuvent tre des tables. Les parenthses peuvent tre utilises autour des clauses JOIN pour contrler l'ordre de jointure. En
l'absence de parenthses, les clauses JOIN sont imbriques de gauche droite.
Pour rassembler tout ceci, supposons que nous avons une table t1 :
no | nom
----+-----1 | a
2 | b
3 | c
et une table t2 :
no | valeur
----+------1 | xxx
3 | yyy
5 | zzz
nous obtenons les rsultats suivants pour les diffrentes jointures :
=> SELECT * FROM t1 CROSS JOIN t2;
no | nom | no | valeur
----+-----+----+------1 | a
| 1 | xxx
1 | a
| 3 | yyy
1 | a
| 5 | zzz
2 | b
| 1 | xxx
2 | b
| 3 | yyy
2 | b
| 5 | zzz
3 | c
| 1 | xxx
3 | c
| 3 | yyy
3 | c
| 5 | zzz
(9 rows)
=> SELECT * FROM t1 INNER JOIN t2 ON t1.no = t2.no;
no | nom | no | valeur
----+-----+----+------1 | a
| 1 | xxx
3 | c
| 3 | yyy
(2 rows)
=> SELECT * FROM t1 INNER JOIN t2 USING (no);
no | nom | valeur
----+-----+------1 | a
| xxx
3 | c
| yyy
(2 rows)
=> SELECT * FROM t1 NATURAL INNER JOIN t2;
no | nom | valeur
----+-----+------1 | a
| xxx
3 | c
| yyy
(2 rows)
=> SELECT * FROM t1 LEFT JOIN t2 ON t1.no = t2.no;
no | nom | no | valeur
----+-----+----+------1 | a
| 1 | xxx
2 | b
|
|
3 | c
| 3 | yyy
(3 rows)
67

Requtes

=> SELECT * FROM t1 LEFT JOIN t2 USING (no);


no | nom | valeur
----+-----+------1 | a
| xxx
2 | b
|
3 | c
| yyy
(3 rows)
=> SELECT * FROM t1 RIGHT JOIN t2 ON t1.no = t2.no;
no | nom | no | valeur
----+-----+----+------1 | a
| 1 | xxx
3 | c
| 3 | yyy
|
| 5 | zzz
(3 rows)
=> SELECT * FROM t1 FULL JOIN t2 ON t1.no = t2.no;
no | nom | no | valeur
----+-----+----+------1 | a
| 1 | xxx
2 | b
|
|
3 | c
| 3 | yyy
|
| 5 | zzz
(4 rows)
La condition de jointure spcifie avec ON peut aussi contenir des conditions sans relation directe avec la jointure. Ceci est utile
pour quelques requtes mais son utilisation doit avoir t rflchie. Par exemple :
=> SELECT * FROM t1 LEFT JOIN t2 ON t1.no = t2.no AND t2.valeur = 'xxx';
no | nom | no | valeur
----+-----+----+------1 | a
| 1 | xxx
2 | b
|
|
3 | c
|
|
(3 rows)
Notez que placer la restriction dans la clause WHERE donne un rsultat diffrent :
=> SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx';
num | name | num | value
-----+------+-----+------1 | a
|
1 | xxx
(1 row)
Ceci est d au fait qu'une restriction place dans la clause ON est traite avant la jointure alors qu'une restriction place dans la
clause WHERE est traite aprs la jointure.

7.2.1.2. Alias de table et de colonne


Un nom temporaire peut tre donn aux tables et aux rfrences de tables complexe, qui sera ensuite utilis pour rfrencer la
table drive dans la suite de la requte. Cela s'appelle un alias de table.
Pour crer un alias de table, crivez
FROM reference_table AS alias
ou
FROM reference_table alias
Le mot cl AS n'est pas obligatoire. alias peut tre tout identifiant.
Une application typique des alias de table est l'affectation d'identifieurs courts pour les noms de tables longs, ce qui permet de garder des clauses de jointures lisibles. Par exemple :
SELECT * FROM nom_de_table_tres_tres_long s
JOIN un_autre_nom_tres_long a ON s.id = a.no;
L'alias devient le nouveau nom de la table en ce qui concerne la requte en cours -- il n'est pas autoris de faire rfrence la table
par son nom original o que ce soit dans la requte. Du coup, ceci n'est pas valide :
68

Requtes

SELECT * FROM mon_table AS m WHERE mon_table.a > 5;

-- mauvais

Les alias de table sont disponibles principalement pour aider l'criture de requte mais ils deviennent ncessaires pour joindre
une table avec elle-mme, par exemple :
SELECT * FROM personnes AS mere JOIN personnes AS enfant ON mere.id = enfant.mere_id;
De plus, un alias est requis si la rfrence de la table est une sous-requte (voir la Section 7.2.1.3, Sous-requtes ).
Les parenthses sont utilises pour rsoudre les ambiguts. Dans l'exemple suivant, la premire instruction affecte l'alias b la
deuxime instance de ma_table mais la deuxime instruction affecte l'alias au rsultat de la jonction :
SELECT * FROM ma_table AS a CROSS JOIN ma_table AS b ...
SELECT * FROM (ma_table AS a CROSS JOIN ma_table) AS b ...
Une autre forme d'alias de tables donne des noms temporaires aux colonnes de la table ainsi qu' la table :
FROM reference_table [AS] alias ( colonne1 [, colonne2 [, ...]] )
Si le nombre d'alias de colonnes spcifi est plus petit que le nombre de colonnes dont dispose la table relle, les colonnes suivantes ne sont pas renommes. Cette syntaxe est particulirement utile dans le cas de jointure avec la mme table ou dans le cas de
sous-requtes.
Quand un alias est appliqu la sortie d'une clause JOIN, l'alias cache le nom original rfrenc l'intrieur du JOIN. Par
exemple :
SELECT a.* FROM ma_table AS a JOIN ta_table AS b ON ...
est du SQL valide mais :
SELECT a.* FROM (ma_table AS a JOIN ta_table AS b ON ...) AS c
n'est pas valide l'alias de table a n'est pas visible en dehors de l'alias c.

7.2.1.3. Sous-requtes
Une sous-requte spcifiant une table drive doit tre enferme dans des parenthses et doit se voir affect un alias de table (voir
la Section 7.2.1.2, Alias de table et de colonne ). Par exemple :
FROM (SELECT * FROM table1) AS nom_alias
Cet exemple est quivalent FROM table1 AS nom_alias. Des cas plus intressants, qui ne peuvent pas tre rduit une
jointure pleine, surviennent quand la sous-requte implique un groupement ou un agrgat.
Uns sous-requte peut aussi tre une liste VALUES :
FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow'))
AS noms(prenom, nom)
De nouveau, un alias de table est requis. Affecter des noms d'alias aux colonnes de la liste VALUES est en option mais c'est une
bonne pratique. Pour plus d'informations, voir Section 7.7, Listes VALUES .

7.2.1.4. Fonctions de table


Les fonctions de table sont des fonctions produisant un ensemble de lignes composes de types de donnes de base (types scalaires) ou de types de donnes composites (lignes de table). Elles sont utilises comme une table, une vue ou une sous-requte de
la clause FROM d'une requte. Les colonnes renvoyes par les fonctions de table peuvent tre incluses dans une clause SELECT,
JOIN ou WHERE de la mme manire qu'une colonne de table, vue ou sous-requte.
Si une fonction de table renvoie un type de donnes de base, la nom de la colonne de rsultat correspond celui de la fonction. Si
la fonction renvoie un type composite, les colonnes rsultantes ont le mme nom que les attributs individuels du type.
Une fonction de table peut avoir un alias dans la clause FROM mais elle peut tre laisse sans alias. Si une fonction est utilise
dans la clause FROM sans alias, le nom de la fonction est utilis comme nom de table rsultante.
Quelques exemples :
CREATE TABLE truc (trucid int, trucsousid int, trucnom text);
CREATE FUNCTION recuptruc(int) RETURNS SETOF foo AS $$
SELECT * FROM truc WHERE trucid = $1;
69

Requtes

$$ LANGUAGE SQL;
SELECT * FROM recuptruc(1) AS t1;
SELECT * FROM truc
WHERE trucsousid IN (
SELECT trucsousid
FROM recuptruc(truc.trucid) z
WHERE z.trucid = truc.trucid);
CREATE VIEW vue_recuptruc AS SELECT * FROM recuptruc(1);
SELECT * FROM vue_recuptruc;
Dans certains cas, il est utile de dfinir des fonctions de table pouvant renvoyer des ensembles de colonnes diffrentes suivant la
faon dont elles sont appeles. Pour supporter ceci, la fonction de table est dclare comme renvoyant le pseudotype record.
Quand une telle fonction est utilise dans une requte, la structure de ligne attendue doit tre spcifie dans la requte elle-mme,
de faon ce que le systme sache comment analyser et planifier la requte. Considrez cet exemple :
SELECT *
FROM dblink('dbname=mabd', 'SELECT proname, prosrc FROM pg_proc')
AS t1(proname nom, prosrc text)
WHERE proname LIKE 'bytea%';
La fonction dblink(3) (part of the dblink module>) excute une requte distante. Elle dclare renvoyer le type record car elle pourrait tre utilise pour tout type de requte. L'ensemble de colonnes relles doit tre spcifi dans la requte appelante de faon ce
que l'analyseur sache, par exemple, comment tendre *.

7.2.2. Clause WHERE


La syntaxe de la la section intitule Clause WHERE est
WHERE condition_recherche
o condition_recherche est toute expression de valeur (voir la Section 4.2, Expressions de valeurs ) renvoyant une valeur de type boolean.
Aprs le traitement de la clause FROM, chaque ligne de la table virtuelle drive est vrifie avec la condition de recherche. Si le
rsultat de la vrification est positif (true), la ligne est conserve dans la table de sortie, sinon (c'est--dire si le rsultat est faux ou
nul), la ligne est abandonne. La condition de recherche rfrence typiquement au moins une colonne de la table gnre dans la
clause FROM ; ceci n'est pas requis mais, dans le cas contraire, la clause WHERE n'aurait aucune utilit.

Note
La condition de jointure d'une jointure interne peut tre crite soit dans la clause WHERE soit dans la clause JOIN.
Par exemple, ces expressions de tables sont quivalentes :
FROM a, b WHERE a.id = b.id AND b.val > 5
et :
FROM a INNER JOIN b ON (a.id = b.id) WHERE b.val > 5
ou mme peut-tre :
FROM a NATURAL JOIN b WHERE b.val > 5
Laquelle vous utilisez est plutt une affaire de style. La syntaxe JOIN dans la clause FROM n'est probablement pas
aussi portable vers les autres systmes de gestion de bases de donnes SQL, mme si cela fait partie du standard
SQL. Pour les jointures externes, il n'y a pas d'autres choix : elles doivent tre faites dans la clause FROM. La clause
ON ou USING d'une jointure externe n'est pas quivalente une condition WHERE parce qu'elle dtermine l'ajout de
lignes (pour les lignes qui ne correspondent pas en entre) ainsi que pour la suppression de lignes dans le rsultat final.
Voici quelques exemples de clauses WHERE :
SELECT ... FROM fdt WHERE c1 > 5
SELECT ... FROM fdt WHERE c1 IN (1, 2, 3)
SELECT ... FROM fdt WHERE c1 IN (SELECT c1 FROM t2)
70

Requtes

SELECT ... FROM fdt WHERE c1 IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10)
SELECT ... FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100
SELECT ... FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1)
fdt est la table drive dans la clause FROM. Les lignes qui ne correspondent pas la condition de recherche de la clause WHERE
sont limines de la table fdt. Notez l'utilisation de sous-requtes scalaires en tant qu'expressions de valeurs. Comme n'importe
quelle autre requte, les sous-requtes peuvent employer des expressions de tables complexes. Notez aussi comment fdt est rfrence dans les sous-requtes. Qualifier c1 comme fdt.c1 est seulement ncessaire si c1 est aussi le nom d'une colonne dans la
table d'entre drive de la sous-requte. Mais qualifier le nom de colonne ajoute la clart mme lorsque cela n'est pas ncessaire. Cet exemple montre comment le nom de colonne d'une requte externe est tendue dans les requtes internes.

7.2.3. Clauses GROUP BY et HAVING


Aprs avoir pass le filtre WHERE, la table d'entre drive peut tre sujette un regroupement en utilisant la clause GROUP BY et
une limination de groupe de lignes avec la clause HAVING.
SELECT liste_selection
FROM ...
[WHERE ...]
GROUP BY reference_colonne_regroupement[,reference_colonne_regroupement]...
La la section intitule Clause GROUP BY est utilise pour regrouper les lignes d'une table qui ont les mmes valeurs dans
toutes les colonnes prcises. L'ordre dans lequel ces colonnes sont indiques importe peu. L'effet est de combiner chaque ensemble de lignes partageant des valeurs communes en un seul groupe de ligne reprsentant toutes les lignes du groupe. Ceci est
fait pour liminer les redondances dans la sortie et/ou pour calculer les agrgats s'appliquant ces groupes. Par exemple :
=> SELECT * FROM test1;
x | y
---+--a | 3
c | 2
b | 5
a | 1
(4 rows)
=> SELECT x FROM test1 GROUP BY x;
x
--a
b
c
(3 rows)
Dans la seconde requte, nous n'aurions pas pu crire SELECT * FROM test1 GROUP BY x parce qu'il n'existe pas une
seule valeur pour la colonne y pouvant tre associ avec chaque autre groupe. Les colonnes de regroupement peuvent tre rfrences dans la liste de slection car elles ont une valeur constante unique par groupe.
En gnral, si une table est groupe, les colonnes qui ne sont pas listes dans le GROUP BY ne peuvent pas tre rfrences sauf
dans les expressions d'agrgats. Voici un exemple d'expressions d'agrgat :
=> SELECT x, sum(y) FROM test1 GROUP BY x;
x | sum
---+----a |
4
b |
5
c |
2
(3 rows)
Ici, sum est la fonction d'agrgat qui calcule une seule valeur pour le groupe entier. La Section 9.18, Fonctions d'agrgat propose plus d'informations sur les fonctions d'agrgats disponibles.

Astuce
Le regroupement sans expressions d'agrgats calcule effectivement l'ensemble les valeurs distinctes d'une colonne.
Ceci peut aussi se faire en utilisant la clause DISTINCT (voir la Section 7.3.3, DISTINCT ).
71

Requtes

Voici un autre exemple : il calcule les ventes totales pour chaque produit (plutt que le total des ventes sur tous les produits) :
SELECT produit_id, p.nom, (sum(v.unite) * p.prix) AS ventes
FROM produits p LEFT JOIN ventes v USING (produit_id)
GROUP BY produit_id, p.nom, p.prix;
Dans cet exemple, les colonnes produit_id, p.nom et p.prix doivent tre dans la clause GROUP BY car elles sont rfrences dans la liste de slection de la requte (but see below). La colonne s.unite n'a pas besoin d'tre dans la liste GROUP BY
car elle est seulement utilise dans l'expression de l'agrgat (sum(...)) reprsentant les ventes d'un produit. Pour chaque produit, la requte renvoie une ligne de rsum sur les ventes de ce produit.
If the products table is set up so that, say, product_id is the primary key, then it would be enough to group by product_id
in the above example, since name and price would be functionally dependent on the product ID, and so there would be no ambiguity about which name and price value to return for each product ID group.
En SQL strict, GROUP BY peut seulement grouper les colonnes de la table source mais PostgreSQL tend ceci en autorisant
GROUP BY grouper aussi les colonnes de la liste de slection. Grouper par expressions de valeurs au lieu de simples noms de
colonnes est aussi permis.
Si une table a t groupe en utilisant la clause GROUP BY mais que seuls certains groupes sont intressants, la clause HAVING
peut tre utilise, comme une clause WHERE, pour liminer les groupes du rsultat. Voici la syntaxe :
SELECT liste_selection FROM ... [WHERE ...] GROUP BY ... HAVING expression_boolenne
Les expressions de la clause HAVING peuvent rfrer la fois aux expressions groupes et aux expressions non groupes (ce qui
impliquent ncessairement une fonction d'agrgat).
Exemple :
=> SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3;
x | sum
---+----a |
4
b |
5
(2 rows)
=> SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';
x | sum
---+----a |
4
b |
5
(2 rows)
De nouveau, un exemple plus raliste :
SELECT produit_id, p.nom, (sum(v.unite) * (p.prix - p.cout)) AS profit
FROM produits p LEFT JOIN ventes v USING (produit_id)
WHERE v.date > CURRENT_DATE - INTERVAL '4 weeks'
GROUP BY produit_id, p.nom, p.prix, p.cout
HAVING sum(p.prix * s.unite) > 5000;
Dans l'exemple ci-dessus, la clause WHERE slectionne les lignes par une colonne qui n'est pas groupe (l'expression est vraie
seulement pour les ventes des quatre dernires semaines) alors que la clause HAVING restreint la sortie aux groupes dont le total
des ventes dpasse 5000. Notez que les expressions d'agrgats n'ont pas besoin d'tre identiques dans toutes les parties d'une requte.
Si une requte contient des appels des fonctions d'aggrgat, mais pas de clause GROUP BY, le regroupement a toujours lieu : le
rsultat est une seule ligne de regroupement (ou peut-tre pas de ligne du tout si la ligne unique est ensuite limine par la clause
HAVING). Ceci est vrai aussi si elle comporte une clause HAVING, mme sans fonction d'aggrgat ou GROUP BY.

7.2.4. Traitement de fonctions Window


Si la requte contient une des fonctions Window (voir Section 3.5, Fonctions de fentrage , Section 9.19, Fonctions Window et Section 4.2.8, Appels de fonction de fentrage ), ces fonctions sont values aprs que soient effectus les regroupements, les aggrgations, les filtrages par HAVING. C'est--dire que si la requte comporte des aggrgat, GROUP BY ou HAVING,
alors les enregistrements vus par les fonctions window sont les lignes regroupes la place des enregistrements originaux provenant de FROM/WHERE.
Quand des fonctions Window multiples sont utilises, toutes les fonctions Window ayant des clauses PARTITION BY et ORDER
BY syntaxiquement quivalentes seront coup sr values en une seule passe sur les donnes. Par consquent, elles verront le
mme ordre de tri, mme si ORDER BY ne dtermine pas de faon unique un tri. Toutefois, aucune garantie n'est faite propos de
72

Requtes

l'valuation de fonctions ayant des spcifications de PARTITION BY ou ORDER BY diffrentes. (Dans ces cas, une tape de tri
est gnralement ncessaire entre les passes d'valuations de fonctions Window, et le tri ne garantit pas la prservation de l'ordre
des enregistrements que son ORDER BY estime comme identiques.)
l'heure actuelle, les fonctions window ncessitent toujours des donnes pr-tries, ce qui fait que la sortie de la requte sera trie
suivant l'une ou l'autre des clauses PARTITION BY/ORDER BY des fonctions Window. Il n'est toutefois pas recommand de s'en
servir. Utilisez une clause ORDER BY au plus haut niveau de la requte si vous voulez tre sr que vos rsultats soient tris d'une
certaine faon.

7.3. Listes de slection


Comme montr dans la section prcdente, l'expression de table pour la commande SELECT construit une table virtuelle intermdiaire en combinant les tables, vues, en liminant les lignes, en groupant, etc. Cette table est finalement passe la ralisation de
la liste de slection. Cette liste dtermine les colonnes de la table intermdiaire afficher.

7.3.1. lments de la liste de slection


La forme la plus simple de liste de slection est *. C'est un raccourci pour indiquer toutes les colonnes que l'expression de table
produit. Sinon, une liste de slection est une liste d'expressions de valeurs spares par des virgules (comme dfini dans la Section 4.2, Expressions de valeurs ). Par exemple, cela pourrait tre une liste des noms de colonnes :
SELECT a, b, c FROM ...
Les noms de colonnes a, b et c sont soit les noms actuels des colonnes des tables rfrences dans la clause FROM soit les alias
qui leur ont t donns (voir l'explication dans Section 7.2.1.2, Alias de table et de colonne ). L'espace de nom disponible dans
la liste de slection est le mme que dans la clause WHERE sauf si le regroupement est utilis, auquel cas c'est le mme que dans la
clause HAVING.
Si plus d'une table a une colonne du mme nom, le nom de la table doit aussi tre donn comme dans :
SELECT tbl1.a, tbl2.a, tbl1.b FROM ...
En travaillant avec plusieurs tables, il est aussi utile de demander toutes les colonnes d'une table particulire :
SELECT tbl1.*, tbl2.a FROM ...
(voir aussi la Section 7.2.2, Clause WHERE )
Si une expression de valeur arbitraire est utilise dans la liste de slection, il ajoute conceptuellement une nouvelle colonne virtuelle dans la table renvoye. L'expression de valeur est value une fois pour chaque ligne avec une substitution des valeurs de
lignes avec les rfrences de colonnes. Mais les expressions de la liste de slection n'ont pas rfrencer les colonnes dans
l'expression de la table de la clause FROM ; elles pourrait tre des expressions arithmtiques constantes, par exemple.

7.3.2. Labels de colonnes


Les entres de la liste de slection peuvent se voir affecter des noms pour la suite de l'excution, peut-tre pour rfrence dans une
clause ORDER BY ou pour affichage par l'application cliente. Par exemple :
SELECT a AS valeur, b + c AS sum FROM ...
Si aucun nom de colonne en sortie n'est spcifi en utilisant AS, le systme affecte un nom de colonne par dfaut. Pour les rfrences de colonne simple, c'est le nom de la colonne rfrence. Pour les appels de fonction, il s'agit du nom de la fonction. Pour
les expressions complexes, le systme gnrera un nom gnrique.
Le mot cl AS est optionnel, mais seulement si le nouveau nom de colonne ne correspond aucun des mots cls PostgreSQL
(voir Annexe C, Mots-cl SQL). Pour viter une correspondance accidentelle un mot cl, vous pouvez mettre le nom de colonne
entre guillemets. Par exemple, VALUE est un mot cl, ce qui fait que ceci ne fonctionne pas :
SELECT a valeur, b + c AS somme FROM ...
mais ceci fonctionne :
SELECT a "valeur", b + c AS somme FROM ...
Pour vous protger de possibles ajouts futurs de mots cls, il est recommand de toujours crire AS ou de mettre le nom de colonne de sortie entre guillemets.

Note
73

Requtes

Le nom des colonnes en sortie est diffrent ici de ce qui est fait dans la clause FROM (voir la Section 7.2.1.2,
Alias de table et de colonne ). Il est possible de renommer deux fois la mme colonne mais le nom affect dans
la liste de slection est celui qui sera pass.

7.3.3. DISTINCT
Aprs le traitement de la liste de slection, la table rsultant pourrait tre optionnellement sujet l'limination des lignes dupliques. Le mot cl DISTINCT est crit directement aprs SELECT pour spcifier ceci :
SELECT DISTINCT liste_selection ...
(au lieu de DISTINCT, le mot cl ALL peut tre utilis pour spcifier le comportement par dfaut, la rcupration de toutes les
lignes)
videmment, les deux lignes sont considres distinctes si elles diffrent dans au moins une valeur de colonne. Les valeurs NULL
sont considres gales dans cette comparaison.
Autrement, une expression arbitraire peut dterminer quelles lignes doivent tre considres distinctes :
SELECT DISTINCT ON (expression [, expression ...]) liste_selection ...
Ici, expression est une expression de valeur arbitraire, value pour toutes les lignes. Les lignes dont toutes les expressions
sont gales sont considres comme dupliques et seule la premire ligne de cet ensemble est conserve dans la sortie. Notez que
la premire ligne d'un ensemble est non prvisible sauf si la requte est trie sur assez de colonnes pour garantir un ordre
unique des colonnes arrivant dans le filtre DISTINCT (le traitement de DISTINCT ON parvient aprs le tri de ORDER BY).
La clause DISTINCT ON ne fait pas partie du standard SQL et est quelque fois considre comme tant un mauvais style cause
de la nature potentiellement indtermine de ses rsultats. Avec l'utilisation judicieuse de GROUP BY et de sous-requtes dans
FROM, la construction peut tre vite mais elle reprsente souvent l'alternative la plus agrable.

7.4. Combiner des requtes


Les rsultats de deux requtes peuvent tre combins en utilisant les oprations d'ensemble : union, intersection et diffrence. La
syntaxe est
requete1 UNION [ALL] requete2
requete1 INTERSECT [ALL] requete2
requete1 EXCEPT [ALL] requete2
requete1 et requete2 sont les requtes pouvant utiliser toutes les fonctionnalits discutes ici. Les oprations d'ensemble
peuvent aussi tre combines et chanes, par exemple
requete1 UNION requete2 UNION requete3
est excut ainsi :
(requete1 UNION requete2) UNION requete3
UNION ajoute effectivement le rsultat de requete2 au rsultat de requete1 (bien qu'il n'y ait pas de garantie qu'il s'agit de
l'ordre dans lequel les lignes sont rellement renvoyes). De plus, il limine les lignes dupliques du rsultat, de la mme faon
que DISTINCT, sauf si UNION ALL est utilise.
INTERSECT renvoie toutes les lignes qui sont la fois dans le rsultat de requete1 et dans le rsultat de requete2. Les
lignes dupliques sont limines sauf si INTERSECT ALL est utilis.
EXCEPT renvoie toutes les lignes qui sont dans le rsultat de requete1 mais pas dans le rsultat de requete2 (ceci est
quelque fois appel la diffrence entre deux requtes). De nouveau, les lignes dupliques sont limines sauf si EXCEPT ALL est
utilis.
Pour calculer l'union, l'intersection ou la diffrence de deux requtes, les deux requtes doivent tre compatibles pour une
union , ce qui signifie qu'elles doivent renvoyer le mme nombre de colonnes et que les colonnes correspondantes doivent avoir
des types de donnes compatibles, comme dcrit dans la Section 10.5, Constructions UNION, CASE et constructions relatives .

7.5. Tri des lignes


Aprs qu'une requte ait produit une table en sortie (aprs que la liste de slection ait t traite), elle peut tre optionnellement
trie. Si le tri n'a pas t choisi, les lignes sont renvoyes dans un ordre non spcifi. Dans ce cas, l'ordre rel dpendra des types
de plan de parcours et de jointure et de l'ordre sur le disque mais vous ne devez pas vous y fier. Un tri particulier en sortie peut
74

Requtes

seulement tre garantie si l'tape de tri est choisie explicitement.


La clause ORDER BY spcifie l'ordre de tri :
SELECT liste_selection
FROM expression_table
ORDER BY expression_tri1 [ASC | DESC] [NULLS { FIRST | LAST }]
[, expression_tri2 [ASC | DESC] [NULLS { FIRST | LAST }] ...]
Les expressions de tri peuvent tre toute expression qui serait valide dans la liste de slection des requtes. Voici un exemple :
SELECT a, b FROM table1 ORDER BY a + b, c;
Quand plus d'une expression est indique, les valeurs suivantes sont utilises pour trier les lignes qui sont identiques aux valeurs
prcdentes. Chaque expression pourrait tre suivie d'un ASC ou DESC optionnel pour configurer la direction du tri (ascendant ou
descendant). L'ordre ASC est la valeur par dfaut. L'ordre ascendant place les plus petites valeurs en premier o plus petit est
dfini avec l'oprateur <. De faon similaire, l'ordre descendant est dtermin avec l'oprateur >. 1
Les options NULLS FIRST et NULLS LAST sont utilises pour dterminer si les valeurs NULL apparaissent avant ou aprs les
valeurs non NULL aprs un tri. Par dfaut, les valeurs NULL sont tries comme si elles taient plus grandes que toute valeur non
NULL. Autrement dit, NULLS FIRST est la valeur par dfaut pour l'ordre descendant (DESC) et NULLS LAST est la valeur utilise sinon.
Notez que les options de tri sont considres indpendament pour chaque colonne trie. Par exemple, ORDER BY x, y DESC
signifie en fait ORDER BY x ASC, y DESC, ce qui est diffrent de ORDER BY x DESC, y DESC.
Une expression_tri peut aussi tre la place le nom ou le numro d'une colonne en sortie, par exemple :
SELECT a + b AS sum, c FROM table1 ORDER BY sum;
SELECT a, max(b) FROM table1 GROUP BY a ORDER BY 1;
les deux triant par la premire colonne en sortie. Notez qu'un nom de colonne en sortie doit tre unique, il ne doit pas tre utilis
dans une expression -- par exemple, ceci n'est pas correct :
SELECT a + b AS sum, c FROM table1 ORDER BY sum + c;

-- mauvais

Cette restriction est l pour rduire l'ambigut. Il y en a toujours si un lment ORDER BY est un simple nom qui pourrait correspondre soit un nom de colonne en sortie soit une colonne d'une expression de table. La colonne en sortie est utilise dans de
tels cas. Cela causera seulement de la confusion si vous utilisez AS pour renommer une colonne en sortie qui correspondra un
autre nom de colonne d'une table.
ORDER BY peut tre appliqu au rsultat d'une combinaison UNION, d'une combinaisonINTERSECT ou d'une combinaison EXCEPT mais, dans ce cas, il est seulement permis de trier par les noms ou numros de colonnes, pas par les expressions.

7.6. LIMIT et OFFSET


LIMIT et OFFSET vous permet de retrouver seulement une portion des lignes gnres par le reste de la requte :
SELECT liste_selection
FROM expression_table
[ ORDER BY ...]
[ LIMIT { nombre | ALL } ] [OFFSET nombre]
Si un nombre limite est donn, pas plus que ce nombre de lignes sera renvoy (mais peut-tre moins si la requte rcupre moins
de lignes). LIMIT ALL revient ne pas spcifier la clause LIMIT.
OFFSET indique de passer ce nombre de lignes avant de renvoyer les lignes restantes. OFFSET 0 revient oublier la clause
OFFSET, et LIMIT NULL revient oublier la clause LIMIT. Si la fois OFFSET et LIMIT apparaissent, alors les OFFSET
lignes sont laisses avant de commencer le renvoi des LIMIT lignes.
Lors de l'utilisation de LIMIT, il est important d'utiliser une clause ORDER BY contraignant les lignes rsultantes dans un ordre
unique. Sinon, vous obtiendrez un sous-ensemble non prvisible de lignes de la requte. Vous pourriez demander les lignes de 10
20 mais dans quel ordre ? L'ordre est inconnu si vous ne spcifiez pas ORDER BY.

En fait, PostgreSQL utilise la classe d'oprateur B-tree par dfaut pour le type de donnes de l'expression pour dterminer l'ordre de tri avec ASC et DESC. De faon conventionnelle, les types de donnes seront initialiss de faon ce que les oprateurs < et > correspondent cet ordre de tri mais un concepteur des types de donnes dfinis par l'utilisateur pourrait choisir de faire quelque chose de diffrent.

75

Requtes

L'optimiseur de requtes prend LIMIT en compte lors de la gnration des plans de requtes, de faon ce que vous obteniez diffrents plans (avec diffrents ordres de lignes) suivant ce que vous donnez LIMIT et OFFSET. Du coup, utiliser des valeurs
LIMIT/OFFSET diffrentes pour slectionner des sous-ensembles diffrents d'un rsultat de requte donnera des rsultats inconsistants sauf si vous forcez un ordre de rsultat prvisible avec ORDER BY. Ceci n'est pas un bogue ; c'est une consquence inhrente du fait que le SQL ne promette par de dlivrer les rsultats d'une requte dans un ordre particulier sauf si ORDER BY est utilis pour contraindre l'ordre.
Les lignes passes par une clause OFFSET devront toujours tre traites l'intrieur du serveur ; du coup, un OFFSET important
peut tre inefficace.

7.7. Listes VALUES


VALUES fournit une faon de gnrer une table de constantes qui peut tre utilis dans une requte sans avoir rellement
crer et peupler une table sur disque. La syntaxe est
VALUES ( expression [, ...] ) [, ...]
Chaque liste d'expressions entre parenthses gnre une ligne dans la table. Les listes doivent toutes avoir le mme nombre
d'lments (c'est--dire une liste de colonnes dans la table), et les entres correspondantes dans chaque liste doivent avoir des
types compatibles. Le type rel affect chaque colonne du rsultat est dtermin en utilisant les mmes rgles que pour UNION
(voir Section 10.5, Constructions UNION, CASE et constructions relatives ).
Voici un exemple :
VALUES (1, 'un'), (2, 'deux'), (3, 'trois');
renverra une table de deux colonnes et trois lignes. C'est quivalent :
SELECT 1 AS column1, 'un' AS column2
UNION ALL
SELECT 2, 'deux'
UNION ALL
SELECT 3, 'trois';
Par dfaut, PostgreSQL affecte les noms column1, column2, etc. aux colonnes d'une table VALUES. Les noms des colonnes
ne sont pas spcifis par le standard SQL et les diffrents SGBD le font de faon diffrente. Donc, il est gnralement mieux de
surcharger les noms par dfaut avec une liste d'alias.
Syntaxiquement, VALUES suivi par une liste d'expressions est trait de la mme faon que
SELECT liste_select FROM expression_table
et peut apparatre partout o un SELECT le peut. Par exemple, vous pouvez l'utiliser comme lment d'un UNION ou y attacher
une spcification de tri (ORDER BY, LIMIT et/ou OFFSET). VALUES est habituellement utilise comme source de
donnes dans une commande INSERT command, mais aussi dans une sous-requte.
Pour plus d'informations, voir VALUES(7).

7.8. Requtes WITH (Common Table Expressions)


WITH fournit un moyen d'crire des ordres auxiliaires pour les util ser dans des requtes plus importantes. Ces requtes, qui sont
souvent appeles Common Table Expressions ou CTE, peuvent tre vues comme des tables temporaires qui n'existent que pour
une requte. Chaque ordre auxiliaire dans une clause WITH peut tre un SELECT, INSERT, UPDATE, ou DELETE; et la
clause WITH elle mme est attache un ordre primaire qui peut lui aussi tre un SELECT, INSERT, UPDATE, ou DELETE.

7.8.1. SELECT dans WITH


L'intrt de SELECT dans WITH est de diviser des requtes complexes en parties plus simples. Un exemple est:
WITH ventes_regionales AS (
SELECT region, SUM(montant) AS ventes_totales
FROM commandes
GROUP BY region
), meilleures_regions AS (
SELECT region
FROM ventes_regionales
WHERE ventes_totales > (SELECT SUM(ventes_totales)/10 FROM ventes_regionales)
)
SELECT region,
76

Requtes

produit,
SUM(quantite) AS unites_produit,
SUM(montant) AS ventes_produit
FROM commandes
WHERE region IN (SELECT region FROM meilleures_regions)
GROUP BY region, produit;
qui affiche les totaux de ventes par produit dans seulement les rgions ayant les meilleures ventes. La clause WITH dfinit deux
ordres auxiliaires appels ventes_regionales et meilleures_regions, o la sortie de ventes_regionales est utilis dans
meilleures_regions et la sortie de meilleures_regions est utilise dans la requte SELECT primaire. Cet exemple aurait pu tre
crit sans WITH, mais aurait alors ncessit deux niveaux de sous-SELECT imbriqus. Les choses sont un peu plus faciles
suivre de cette faon.
Le modificateur optionnel RECURSIVE fait passer WITH du statut de simple aide syntaxique celui de quelque chose qu'il serait
impossible d'accomplir avec du SQL standard. Grce RECURSIVE, une requte WITH peut utiliser sa propre sortie. Un exemple
trs simple se trouve dans cette requte, qui ajoute les nombres de 1 100 :
WITH RECURSIVE t(n) AS (
VALUES (1)
UNION ALL
SELECT n+1 FROM t WHERE n < 100
)
SELECT sum(n) FROM t;
La forme gnrale d'une requte WITH est toujours un terme non-recursif, puis UNION (ou UNION ALL), puis un terme rcursif.
Seul le terme rcursif peut contenir une rfrence la sortie propre de la requte. Une requte de ce genre est excute comme
suit :
Procdure 7.1. valuation de requte rcursive

1.

valuer le terme non rcursif. Pour UNION (mais pas UNION ALL), supprimer les enregistrements en double. Inclure le
reste dans le rsultat de la requte rcursive et le mettre aussi dans une table temporaire de travail (working table.)

2.

Tant que la table de travail n'est pas vide, rpter ces tapes :
a.

valuer le terme rcursif, en substituant la rfrence rcursive le contenu courant de la table de travail. Pour UNION
(mais pas UNION ALL), supprimer les doublons, ainsi que les enregistrements en doublon des enregistrements dj obtenus. Inclure les enregistrements restants dans le rsultat de la requte rcursive, et les mettre aussi dans une table temporaire intermdiaire (intermediate table).

b.

Remplacer le contenu de la table de travail par celui de la table intermdiaire, puis supprimer la table intermdiaire.

Note
Dans son appellation stricte, ce processus est une itration, pas une rcursion, mais RECURSIVE est la terminologie choisie par le comit de standardisation de SQL.
Dans l'exemple prcdent, la table de travail a un seul enregistrement chaque tape, et il prend les valeurs de 1 100 en tapes
successives. la centime tape, il n'y a plus de sortie en raison de la clause WHERE, ce qui met fin la requte.
Les requtes rcursives sont utilises gnralement pour traiter des donnes hirarchiques ou sous forme d'arbres. Cette requte est
un exemple utile pour trouver toutes les sous-parties directes et indirectes d'un produit, si seule une table donne toutes les inclusions immdiates :
WITH RECURSIVE parties_incluses(sous_partie, partie, quantite) AS (
SELECT sous_partie, partie, quantite FROM parties WHERE partie = 'notre_produit'
UNION ALL
SELECT p.sous_partie, p.partie, p.quantite
FROM parties_incluses pr, parties p
WHERE p.partie = pr.sous_partie
)
SELECT sous_partie, SUM(quantite) as quantite_totale
FROM parties_incluses
GROUP BY sous_partie

77

Requtes

Quand on travaille avec des requtes rcursives, il est important d'tre sr que la partie rcursive de la requte finira par ne retourner aucun enregistrement, au risque sinon de voir la requte boucler indfiniment. Quelquefois, utiliser UNION la place de
UNION ALL peut rsoudre le problme en supprimant les enregistrements qui doublonnent ceux dj retourns. Toutefois, souvent, un cycle ne met pas en jeu des enregistrements de sortie qui sont totalement des doublons : il peut s'avrer ncessaire de vrifier juste un ou quelques champs, afin de s'assurer que le mme point a dj t atteint prcdemment. La mthode standard pour
grer ces situations est de calculer un tableau de valeurs dj visites. Par exemple, observez la requte suivante, qui parcourt une
table graphe en utilisant un champ lien :
WITH RECURSIVE parcourt_graphe(id, lien, donnee, profondeur) AS (
SELECT g.id, g.lien, g.donnee, 1
FROM graphe g
UNION ALL
SELECT g.id, g.lien, g.donnee, sg.profondeur + 1
FROM graphe g, parcourt_graphe sg
WHERE g.id = sg.lien
)
SELECT * FROM parcourt_graphe;
Cette requte va boucler si la liaison lien contient des boucles. Parce que nous avons besoin de la sortie profondeur , simplement remplacer UNION ALL par UNION ne rsoudra pas le problme. la place, nous avons besoin d'identifier si nous avons atteint un enregistrement que nous avons dj trait pendant notre parcours des liens. Nous ajoutons deux colonnes chemin et
boucle la requte :
WITH RECURSIVE parcourt_graphe(id, lien, donnee, profondeur, chemin, boucle) AS (
SELECT g.id, g.lien, g.donnee, 1,
ARRAY[g.id],
false
FROM graphe g
UNION ALL
SELECT g.id, g.lien, g.donnee, sg.profondeur + 1,
chemin || g.id,
g.id = ANY(chemin)
FROM graphe g, parcourt_graphe sg
WHERE g.id = sg.lien AND NOT boucle
)
SELECT * FROM parcourt_graphe;
En plus de prvenir les boucles, cette valeur de tableau est souvent pratique en elle-mme pour reprsenter le chemin pris pour
atteindre chaque enregistrement.
De faon plus gnrale, quand plus d'un champ a besoin d'tre vrifi pour identifier une boucle, utilisez un tableau
d'enregistrements. Par exemple, si nous avions besoin de comparer les champs f1 et f2 :
WITH RECURSIVE parcourt_graphe(id, lien, donnee, profondeur, chemin, boucle) AS (
SELECT g.id, g.lien, g.donnee, 1,
ARRAY[ROW(g.f1, g.f2)],
false
FROM graphe g
UNION ALL
SELECT g.id, g.lien, g.donnee, sg.profondeur + 1,
chemin || ROW(g.f1, g.f2),
ROW(g.f1, g.f2) = ANY(path)
FROM graphe g, parcourt_graphe sg
WHERE g.id = sg.link AND NOT boucle
)
SELECT * FROM parcourt_graphe;

Astuce
Omettez la syntaxe ROW() dans le cas courant o un seul champ a besoin d'tre test pour dterminer une boucle.
Ceci permet, par l'utilisation d'un tableau simple plutt que d'un tableau de type composite, de gagner en efficacit.

Astuce
78

Requtes

L'algorithme d'valuation rcursive de requte produit sa sortie en ordre de parcours en largeur (algorithme
breadth-first). Vous pouvez afficher les rsultats en ordre de parcours en profondeur (depth-first) en faisant sur la
requte externe un ORDER BY sur une colonne chemin construite de cette faon.
Si vous n'tes pas certain qu'une requte peut boucler, une astuce pratique pour la tester est d'utiliser LIMIT dans la requte parente. Par exemple, cette requte bouclerait indfiniment sans un LIMIT :
WITH RECURSIVE t(n) AS (
SELECT 1
UNION ALL
SELECT n+1 FROM t
)
SELECT n FROM t LIMIT 100;
Ceci fonctionne parce que l'implmentation de PostgreSQL n'value que le nombre d'enregistrements de la requte WITH rcuprs par la requte parente. L'utilisation de cette astuce en production est dconseille parce que d'autres systmes pourraient
fonctionner diffremment. Par ailleurs, cela ne fonctionnera pas si vous demandez la requte externe de trier les rsultats de la
requte rcursive, ou si vous les joignez une autre table, parce dans ces cas, la requte exterieure essaiera habituellement de rcuprer toute la sortie de la requte WITH de toutes faons.
Une proprit intressante des requtes WITH est qu'elles ne sont values qu'une seule fois par excution de la requte parente ou
des requtes WITH surs. Par consquent, les calculs coteux qui sont ncessaires plusieurs endroits peuvent tre placs dans
une requte WITH pour viter le travail redondant. Un autre intrt peut tre d'viter l'excution multiple d'une fonction ayant des
effets de bord. Toutefois, le revers de la mdaille est que l'optimiseur est moins capable d'extrapoler les restrictions de la requte
parente vers une requte WITH que vers une sous-requte classique. La requte WITH sera gnralement excute telle quelle,
sans suppression d'enregistrements, que la requte parente devra supprimer ensuite. (Mais, comme mentionn prcdemment,
l'valuation pourrait s'arrter rapidement si la (les) rfrence(s) la requte ne demande(nt) qu'un nombre limit
d'enregistrements).
Les exemples prcdents ne montrent que des cas d'utilisation de WITH avec SELECT, mais on peut les attacher de la mme
faon un INSERT, UPDATE, ou DELETE. Dans chaque cas, le mcanisme fournit en fait des tables temporaires auxquelles on
peut faire rfrence dans la commande principale.

7.8.2. Ordres de Modification de Donnes avec WITH


Vous pouvez utiliser des ordres de modification de donnes (INSERT, UPDATE, ou DELETE) dans WITH. Cela vous permet
d'effectuer plusieurs oprations diffrentes dans la mme requte. Par exemple:
WITH lignes_deplacees AS (
DELETE FROM produits
WHERE
"date" >= '2010-10-01' AND
"date" < '2010-11-01'
RETURNING *
)
INSERT INTO log_produits
SELECT * FROM lignes_deplacees;
Cette requte dplace les enregistrements de produits vers log_produits. Le DELETE du WITH supprime les enregistrements spcifis de produits, en retournant leurs contenus par la clause RETURNING; puis la requte primaire lit cette sortie et l'insre dans
log_produits.
Un point important noter de l'exemple prcdent est que la clause WITH est attache l'INSERT, pas au sous-SELECT de l'
INSERT. C'est ncessaire parce que les ordres de modification de donnes ne sont autoriss que dans les clauses WITH qui sont
attaches l'ordre de plus haut niveau. Toutefois, les rgles de visibilit normales de WITH s'appliquent, il est donc possible de
faire rfrence la sortie du WITH dans le sous-SELECT.
Les ordres de modification de donnes dans WITH ont habituellement des clauses RETURNING, comme dans l'exemple prcdent.
C'est la sortie de la clause RETURNING pas la table cible de l'ordre de modification de donnes, qui forme la table temporaire
laquelle on pourra faire rfrence dans le reste de la requte. Si un ordre de modification de donnes dans WITH n'a pas de clause
RETURNING, alors il ne produit pas de table temporaire et ne peut pas tre utilis dans le reste de la requte. Un ordre de ce type
sera toutefois excut. En voici un exemple (dnu d'intrt):
WITH t AS (
DELETE FROM foo
79

Requtes

)
DELETE FROM bar;
Cet exemple supprimerait tous les lments des tables foo et bar. Le nombre d'enregistrements retourn au client n'incluerait que
les enregistrements supprims de bar.
Les auto-rfrences rcursives dans les ordres de modification de donnes ne sont pas autorises. Dans certains cas, il est possible
de contourner cette limitation en faisant rfrence la sortie d'un WITH, par exemple:
WITH RECURSIVE pieces_incluses(sous_piece, piece) AS (
SELECT sous_piece, piece FROM pieces WHERE piece = 'notre_produit'
UNION ALL
SELECT p.sous_piece, p.piece
FROM pieces_incluses pr, pieces p
WHERE p.piece = pr.sous_piece
)
DELETE FROM pieces
WHERE piece IN (SELECT piece FROM pieces_incluses);
Cette requte supprimerait toutes les pices directes et indirectes d'un produit.
Les ordres de modification de donnes dans WITH sont excutes exactement une fois, et toujours jusqu' la fin, indpendamment
du fait que la requte primaire lise tout (ou mme une partie) de leur sortie. Notez que c'est diffrent de la rgle pour SELECT
dans WITH: comme prcis dans la section prcdente, l'excution d'un SELECT est n'est poursuivie que tant que la requte primaire consomme sa sortie.
Les sous-requtes du WITH sont toutes excutes simultanment et simultanment avec la requte principale. Par consquent,
quand vous utilisez un ordre de modification de donnes avec WITH, l'ordre dans lequel les mises jour sont effectues n'est pas
prvisible. Toutes les requtes sont excutes dans le mme instantan (voyez Chapitre 13, Contrle d'accs simultan), elles ne
peuvent donc pas voir les effets des autres sur les tables cibles. Ceci rend sans importance le problme de l'imprvisibilit de
l'ordre des mises jour, et signifie que RETURNING est la seule faon de communiquer les modifications entre les diffntes sousrequtes WITH et la requte principale. En voici un exemple:
WITH t AS (
UPDATE produits SET prix = prix * 1.05
RETURNING *
)
SELECT * FROM produits;
le SELECT externe retournerait les prix originaux avant l'action de UPDATE, alors que
WITH t AS (
UPDATE produits SET prix = prix * 1.05
RETURNING *
)
SELECT * FROM t;
le SELECT externe retournerait les donnes mises jour.
Essayer de mettre jour le mme enregistrement deux fois dans le mme ordre n'est pas support. Seule une des deux modifications a lieu, mais il n'est pas ais (et quelquefois pas possible) de dterminer laquelle. Ceci s'applique aussi pour la suppression
d'un enregistrement qui a dj t mis jour dans le mme ordre: seule la mise jour est effectue. Par consquent, vous devriez
viter en rgle gnrale de mettre jour le mme enregistrement deux fois en un seul ordre. En particulier, vitez d'crire des
sous-requtes qui modifieraient les mmes enregistrements que la requte principale ou une autre sous-requte. Les effets d'un
ordre de ce type seraient imprvisibles.
l'heure actuelle, les tables utilises comme cibles d'un ordre modifiant les donnes dans un WITH ne doivent avoir ni rgle
conditionnelle, ni rgle ALSO, ni une rgle INSTEAD qui gnre plusieurs ordres.

80

Chapitre 8. Types de donnes


PostgreSQL offre un large choix de types de donnes disponibles nativement. Les utilisateurs peuvent ajouter de nouveaux
types PostgreSQL en utilisant la commande CREATE TYPE(7).
Le Tableau 8.1, Types de donnes montre tous les types de donnes gnraux disponibles nativement. La plupart des types
de donnes alternatifs lists dans la colonne Alias sont les noms utiliss en interne par PostgreSQL pour des raisons historiques. Il existe galement d'autres types de donnes internes ou obsoltes, mais ils ne sont pas lists ici.
Tableau 8.1. Types de donnes

Nom

Alias

Description

bigint

int8

Entier sign sur 8 octets

bigserial

serial8

Entier sur 8 octets incrmentation automatique

bit [ (n) ]

Suite de bits de longueur fixe

bit varying [ (n) ]

varbit

Suite de bits de longueur variable

boolean

bool

Boolen (Vrai/Faux)

box

Bote rectangulaire dans le plan

bytea

Donne binaire ( tableau d'octets )

character varying [ (n) ]

varchar [ (n) ]

Chane de caractres de longueur variable

character [ (n) ]

char [ (n) ]

Chane de caractres de longueur fixe

cidr

Adresse rseau IPv4 ou IPv6

circle

Cercle dans le plan

date

Date du calendrier (anne, mois, jour)

double precision

float8

Nombre virgule flottante de double prcision (sur huit octets)

inet
integer

Adresse d'ordinateur IPv4 ou IPv6


int, int4

Entier sign sur 4 octets

interval [ champs ] [ (p) ]

Intervalle de temps

line

Droite (infinie) dans le plan

lseg

Segment de droite dans le plan

macaddr

Adresse MAC (pour Media Access Control)

money

Montant montaire

numeric [ (p, s) ]

decimal [ (p, s) ]

Nombre exact dont la prcision peut tre prcise

path

Chemin gomtrique dans le plan

point

Point gomtrique dans le plan

polygon

Chemin gomtrique ferm dans le plan

real

float4

Nombre virgule flottante de simple prcision (sur quatre octets)

smallint

int2

Entier sign sur 2 octets

serial

serial4

Entier sur 4 octets incrmentation automatique

text

Chane de caractres de longueur variable

time [ (p) ] [ without time zone ]

Heure du jour (pas du fuseau horaire)

time [ (p) ] with time zone

timetz

Heure du jour, avec fuseau horaire

timestamp [ (p) ] [ without time zone ]


timestamp [ (p) with time zone

Date et heure (pas du fuseau horaire)


timestamptz

Date et heure, avec fuseau horaire

tsquery

requte pour la recherche plein texte

tsvector

document pour la recherche plein texte

txid_snapshot

image de l'identifiant de transaction au niveau utilisateur


81

Types de donnes

Nom

Alias

Description

uuid

identifiant unique universel

xml

donnes XML

Compatibilit
Les types suivants sont conformes la norme SQL: bigint, bit, bit varying, boolean, char, character varying, character, varchar, date, double precision, integer, interval, numeric, decimal, real, smallint, time (avec et sans fuseau
horaire), timestamp (avec et sans fuseau horaire), xml, .
Chaque type de donnes a une reprsentation externe dtermine par ses fonctions d'entre et de sortie. De nombreux types de
donnes internes ont un format externe vident. Cependant, certains types sont spcifiques PostgreSQL, comme les chemins
gomtriques, ou acceptent diffrents formats, comme les types de donnes de date et d'heure. Certaines fonctions d'entre et de
sortie ne sont pas inversables : le rsultat de la fonction de sortie peut manquer de prcision compar l'entre initiale.

8.1. Types numriques


Les types numriques sont constitus d'entiers de 2, 4 ou 8 octets, de nombres virgule flottante de 4 ou 8 octets et de dcimaux
dont la prcision peut tre indique. Le Tableau 8.2, Types numriques prcise les types disponibles.
Tableau 8.2. Types numriques

Nom

Taille de stockage

Description

tendue

smallint

2 octets

entier de faible tendue

de -32768 +32767

integer

4 octets

entier habituel

de -2147483648 +2147483647

bigint

8 octets

grand entier

de
-9223372036854775808
9223372036854775807

decimal

variable

prcision indique par l'utilisateur, valeur jusqu' 131072 chiffres avant le point dexacte
cimal ; jusqu' 16383 aprs le point dcimal

numeric

variable

prcision indique par l'utilisateur, valeur jusqu' 131072 chiffres avant le point dexacte
cimal ; jusqu' 16383 aprs le point dcimal

real

4 octets

prcision variable, valeur inexacte

prcision de 6 dcimales

double precision

8 octets

prcision variable, valeur inexacte

prcision de 15 dcimales

serial

4 octets

entier incrmentation automatique

de 1 2147483647

bigserial

8 octets

entier de grande taille incrmentation de 1 9223372036854775807


automatique

La syntaxe des constantes pour les types numriques est dcrite dans la Section 4.1.2, Constantes . Les types numriques ont un
ensemble complet d'oprateurs arithmtiques et de fonctions. On peut se rfrer au Chapitre 9, Fonctions et oprateurs pour plus
d'informations. Les sections suivantes dcrivent ces types en dtail.

8.1.1. Types entiers


Les types smallint, integer et bigint stockent des nombres entiers, c'est--dire sans dcimale, de diffrentes tendues. Toute tentative d'y stocker une valeur en dehors de l'chelle produit une erreur.
Le type integer est le plus courant. Il offre un bon compromis entre capacit, espace utilis et performance. Le type smallint n'est
utilis que si l'conomie d'espace disque est le premier critre de choix. Le type bigint ne doit tre utilis que si l'chelle de valeurs
du type integer n'offre pas une tendue suffisante car le type integer est nettement plus rapide.
Sur les trs petits systmes, le type bigint peut ne pas fonctionner correctement car il repose sur la capacit du compilateur supporter les entiers de 8 octets. Sur une machine qui ne les supporte pas, bigint se comporte comme integer (mais prend bien huit octets d'espace de stockage). Cela dit, les auteurs n'ont pas connaissance de plate-forme sur laquelle il en va ainsi.
SQL ne dfinit que les types de donnes integer (ou int), smallint et bigint. Les noms de types int2, int4, et int8 sont des extensions, partages par d'autres systmes de bases de donnes SQL.
82

Types de donnes

8.1.2. Nombres prcision arbitraire


Le type numeric peut stocker des nombres contenant un trs grand nombre de chiffres et effectuer des calculs exacts. Il est spcialement recommand pour stocker les montants financiers et autres quantits pour lesquelles l'exactitude est indispensable. Nanmoins, l'arithmtique sur les valeurs numeric est trs lente compare aux types entiers ou aux types virgule flottante dcrits dans
la section suivante.
Dans ce qui suit, on utilise les termes suivants : l'chelle d'un numeric est le nombre de chiffres dcimaux de la partie fractionnaire, droite du sparateur de dcimales. La prcision d'un numeric est le nombre total de chiffres significatifs dans le nombre
complet, c'est--dire le nombre de chiffres de part et d'autre du sparateur. Donc, le nombre 23.5141 a une prcision de 6 et une
chelle de 4. On peut considrer que les entiers ont une chelle de 0.
La prcision maximale et l'chelle maximale d'une colonne numeric peuvent tre toutes deux rgles. Pour dclarer une colonne
de type numrique, il faut utiliser la syntaxe :
NUMERIC(prcision, chelle)
La prcision doit tre strictement positive, l'chelle positive ou NULL. Alternativement :
NUMERIC(prcision)
indique une chelle de 0.
NUMERIC
sans prcision ni chelle cre une colonne dans laquelle on peut stocker des valeurs de n'importe quelle prcision ou chelle, dans
la limite de la prcision implante. Une colonne de ce type n'impose aucune prcision la valeur entre, alors que les colonnes numeric ayant une chelle forcent les valeurs entres cette chelle. (Le standard SQL demande une prcision par dfaut de 0,
c'est--dire de forcer la transformation en entiers. Les auteurs trouvent cela inutile. Dans un souci de portabilit, il est prfrable
de toujours indiquer explicitement la prcision et l'chelle.)

Note
La prcision maximale autorise, si elle est explicitement spcifie dans la dclaraion du type, est de 1000. NUMERIC sans prcision est sujet aux limites dcrites dans Tableau 8.2, Types numriques .
Si l'chelle d'une valeur stocker est suprieure celle de la colonne, le systme arrondit la valeur au nombre de dcimales indiqu pour la colonne. Si le nombre de chiffres gauche du point dcimal est suprieur la diffrence entre la prcision dclare et
l'chelle dclare, une erreur est leve.
Les valeurs numriques sont stockes physiquement sans zro avant ou aprs. Du coup, la prcision dclare et l'chelle de la colonne sont des valeurs maximales, pas des allocations fixes (en ce sens, le type numrique est plus proche de varchar(n) que de
char(n)). Le besoin pour le stockage rel est de deux octets pour chaque groupe de quatre chiffres dcimaux, plus trois huit octets d'en-tte.
En plus des valeurs numriques ordinaires, le type numeric autorise la valeur spciale NaN qui signifie not-a-number (NdT :
pas un nombre). Toute opration sur NaN retourne NaN. Pour crire cette valeur comme une constante dans une requte SQL, elle
doit tre place entre guillemets. Par exemple, UPDATE table SET x = 'NaN'. En saisie, la chane NaN est reconnue
quelque soit la casse utilise.

Note
Dans la plupart des implmentations du concept not-a-number , NaN est considr diffrent de toute valeur numrique (ceci incluant NaN). Pour autoriser le tri des valeurs de type numeric et les utiliser dans des index bass sur
le tri, PostgreSQL traite les valeurs NaN comme identiques entre elles, mais toutes suprieures aux valeurs non
NaN.
Les types decimal et numeric sont quivalents. Les deux types sont dans le standard SQL.

8.1.3. Types virgule flottante


Les types de donnes real et double precision sont des types numriques inexacts de prcision variable. En pratique, ils sont gnralement conformes la norme IEEE 754 pour l'arithmtique binaire virgule flottante (respectivement simple et double prcision), dans la mesure o les processeurs, le systme d'exploitation et le compilateur les supportent.
Inexact signifie que certaines valeurs ne peuvent tre converties exactement dans le format interne. Elles sont, de ce fait, stockes
sous une forme approche. Ainsi, stocker puis rafficher ces valeurs peut faire apparatre de lgers carts. Prendre en compte ces
erreurs et la faon dont elles se propagent au cours des calculs est le sujet d'une branche entire des mathmatiques et de
83

Types de donnes

l'informatique, qui n'est pas le sujet de ce document, l'exception des points suivants :

pour un stockage et des calculs exacts, comme pour les valeurs montaires, le type numeric doit tre privilgi ;

pour des calculs compliqus avec ces types pour quoi que ce soit d'important, et particulirement pour le comportement aux limites (infini, zro), l'implantation spcifique la plate-forme doit tre tudi avec soin ;

tester l'galit de deux valeurs virgule flottante peut ne pas donner le rsultat attendu.

Sur la plupart des plates-formes, le type real a une tendue d'au moins 1E-37 1E37 avec une prcision d'au moins 6 chiffres dcimaux. Le type double precision a gnralement une tendue de 1E-307 1E+308 avec une prcision d'au moins 15 chiffres. Les
valeurs trop grandes ou trop petites produisent une erreur. Un arrondi peut avoir lieu si la prcision d'un nombre en entre est trop
grande. Les nombres trop proches de zro qui ne peuvent tre reprsents autrement que par zro produisent une erreur
(underflow).

Note
Le paramtre extra_float_digits contrle le nombre de chiffres significatifs inclus lorsqu'une valeur virgule flottante est convertie en texte. Avec la valeur par dfaut de 0, la sortie est la mme sur chaque plateforme supporte
par PostgreSQL. L'augmenter va produire une sortie reprsentant plus prcisment la valeur stocke mais il est possible que la sortie soit diffrente suivant les plateformes.
En plus des valeurs numriques ordinaires, les types virgule flottante ont plusieurs valeurs spciales :
Infinity
-Infinity
NaN
Elles reprsentent les valeurs spciales de l'IEEE 754, respectivement infinity (NdT : infini), negative infinity (NdT : infini
ngatif) et not-a-number (NdT : pas un nombre) (sur une machine dont l'arithmtique virgule flottante ne suit pas l'IEEE 754,
ces valeurs ne fonctionnent probablement pas comme espr). Lorsqu'elles sont saisies en tant que constantes dans une commande
SQL, ces valeurs doivent tre places entre guillemets. Par exemple, UPDATE table SET x = 'Infinity'. En entre, ces
valeurs sont reconnues quelque soit la casse utilise.

Note
IEEE754 spcifie que NaN ne devrait pas tre considr gale toute autre valeur en virgule flottante (ceci incluant
NaN). Pour permettre le tri des valeurs en virgule flottante et leur utilisation dans des index bass sur des arbres,
PostgreSQL traite les valeurs NaN comme identiques entre elles, mais suprieures toute valeur diffrente de
NaN.
PostgreSQL autorise aussi la notation float du standard SQL, ainsi que float(p) pour indiquer des types numriques inexacts. p
indique la prcision minimale acceptable en chiffres binaires. PostgreSQL accepte de float(1) float(24), qu'il transforme en
type real, et de float(25) float(53), qu'il transforme en type double precision. Toute valeur de p hors de la zone des valeurs possibles produit une erreur. float sans prcision est compris comme double precision.

Note
Avant PostgreSQL 7.4, la prcision d'un float(p) tait suppose indiquer une prcision en chiffres dcimaux. Cela a t corrig pour respecter le standard SQL, qui indique que la prcision est indique en chiffres binaires.
L'affirmation que les real et les double precision ont exactement 24 et 53 bits dans la mantisse est correcte pour les
implmentations des nombres virgule flottante respectant le standard IEEE. Sur les plates-formes non-IEEE, c'est
peut-tre un peu sous-estim mais, pour plus de simplicit, la gamme de valeurs pour p est utilise sur toutes les
plates-formes.

8.1.4. Types seris


Les types de donnes serial et bigserial ne sont pas de vrais types, mais plutt un raccourci de notation pour crer des colonnes
d'identifiants uniques (similaires la proprit AUTO_INCREMENT utilise par d'autres SGBD). Dans la version actuelle, indiquer :
CREATE TABLE nom_de_table (
nom_de_colonne SERIAL
84

Types de donnes

);
est quivalent crire :
CREATE SEQUENCE nom_de_table_nom_de_colonne_seq;
CREATE TABLE nom_de_table (
nom_de_colonne integer NOT NULL DEFAULT nextval('nom_de_table_nom_de_colonne_seq')
NOT NULL
);
ALTER SEQUENCE nom_de_table_nom_de_colonne_seq OWNED BY nom_de_table.nom_de_colonne;
Une colonne d'entiers a ainsi t cre dont la valeur par dfaut est assigne par un gnrateur de squence. Une contrainte NOT
NULL est ajoute pour s'assurer qu'une valeur NULL ne puisse pas tre insre. (Dans la plupart des cas, une contrainte UNIQUE
ou PRIMARY KEY peut tre ajoute pour interdire que des doublons soient crs par accident, mais ce n'est pas automatique.) Enfin, la squence est marque owned by (possde par) la colonne pour qu'elle soit supprime si la colonne ou la table est supprime.

Note
Comme smallserial, serial et bigserial sont implments en utilisant des squences, il peut y avoir des trous dans la
squence de valeurs qui apparait dans la colonne, mme si aucune ligne n'est jamais supprime. Une valeur alloue
partir de la squence est toujours utilise mme si la ligne contenant cette valeur n'est pas insre avec succs
dans la colonne de la table. Cela peut survenir si la transaction d'insertion est annule. Voir nextval() dans Section 9.15, Fonctions de manipulation de squences pour plus de dtails.

Note
Avant PostgreSQL 7.3, serial sous-entendait UNIQUE. Ce n'est plus automatique. Pour qu'une colonne de type
serial soit unique ou soit une cl primaire, il faut le prciser, comme pour les autres types.
Pour insrer la valeur suivante de la squence dans la colonne serial, il faut prciser que la valeur par dfaut de la colonne doit tre
utilise. Cela peut se faire de deux faons : soit en excluant cette colonne de la liste des colonnes de la commande INSERT soit en
utilisant le mot cl DEFAULT.
Les types serial et serial4 sont identiques : ils crent tous les deux des colonnes integer. Les types bigserial et serial8 fonctionnent
de la mme faon mais crent des colonnes bigint. bigserial doit tre utilis si plus de 231 identifiants sont prvus sur la dure de
vie de la table.
La squence cre pour une colonne serial est automatiquement supprime quand la colonne correspondante est supprime. La squence peut tre dtruite sans supprimer la colonne, mais la valeur par dfaut de la colonne est alors galement supprime.

8.2. Types montaires


Le type money stocke un montant en devise avec un nombre fixe de dcimales. Voir le Tableau 8.3, Types montaires . La prcision de la partie fractionne est dtermine par le paramtre lc_monetary de la base de donnes. L'chelle indique dans la table
suppose qu'il y a deux chiffres dans la partie fractionne. De nombreux formats sont accepts en entre, dont les entiers et les
nombres virgule flottante, ainsi que les formats classiques de devises, comme '$1,000.00'. Le format de sortie est gnralement dans le dernier format, mais dpend de la locale.
Tableau 8.3. Types montaires

Nom

Taille de stockage

Description

tendue

money

8 octets

montant montaire

-92233720368547758.08
+92233720368547758.07

Comme la sortie de type de donnes est sensible la locale, la recharge de donnes de type money dans une base de donnes pourrait ne pas fonctionner si la base a une configuration diffrente pour lc_monetary. Pour viter les problmes, avant de restaurer
une sauvegarde dans une nouvelle base de donnes, assurez-vous que lc_monetary a la mme valeur ou une valeur quivalente
celle de la base qui a t sauvegarde.
Les valeurs de types numeric, int et bigint peuvent tre converties en type money. La conversion partir du type real et double
precision peut tre fait en convertissant tout d'abord vers le type numeric. Par exemple :
SELECT '12.34'::float8::numeric::money;
85

Types de donnes

Nanmoins, ce n'est pas recommand. Les nombres virgules flottantes ne doivent pas tre utiliss pour grer de la monnaie
cause des erreurs potentielles d'arrondis.
Une valeur money peut tre convertie en numeric sans perdre de prcision. Les conversion vers d'autres types peuvent potentiellement perdre en prcision et doivent aussi de faire en deux tapes :
SELECT '52093.89'::money::numeric::float8;
Quand une valeur de type money est divise par une autre valeur de type money, le rsultat est du type double precision
(c'est--dire un nombre pur, pas une monnaie). Les units de monnaie s'annulent dans la division.

8.3. Types caractre


Tableau 8.4. Types caractre

Nom

Description

character varying(n), varchar(n)

Longueur variable avec limite

character(n), char(n)

longueur fixe, complt par des espaces

text

longueur variable illimite

Le Tableau 8.4, Types caractre prsente les types gnriques disponibles dans PostgreSQL.
SQL dfinit deux types de caractres principaux : character varying(n) et character(n) o n est un entier positif. Ces deux types
permettent de stocker des chanes de caractres de taille infrieure ou gale n (ce ne sont pas des octets). Toute tentative
d'insertion d'une chane plus longue conduit une erreur, moins que les caractres en excs ne soient tous des espaces, auquel
cas la chane est tronque la taille maximale (cette exception trange est impose par la norme SQL). Si la chane stocker est
plus petite que la taille dclare, les valeurs de type character sont compltes par des espaces, celles de type character varying
sont stockes en l'tat.
Si une valeur est explicitement transtype en character varying(n) ou en character(n), une valeur trop longue est tronque n caractres sans qu'aucune erreur ne soit leve (ce comportement est aussi impos par la norme SQL.)
Les notations varchar(n) et char(n) sont des alias de character varying(n) et character(n), respectivement. character sans indication de taille est quivalent character(1). Si character varying est utilis sans indicateur de taille, le type accepte des chanes de
toute taille. Il s'agit l d'une spcificit de PostgreSQL.
De plus, PostgreSQL propose aussi le type text, qui permet de stocker des chanes de n'importe quelle taille. Bien que le type
text ne soit pas dans le standard SQL, plusieurs autres systmes de gestion de bases de donnes SQL le proposent galement.
Les valeurs de type character sont compltes physiquement l'aide d'espaces pour atteindre la longueur n indique. Ces valeurs
sont galement stockes et affiches de cette faon. Les espaces de remplissage n'ont, toutefois, aucune signification smantique.
Les espaces finales sont ignores lors de la comparaison de deux valeurs de type character et sont supprimes lors de la conversion
d'une valeur character en un des autres types chane. Ces espaces ont une signification smantique pour les valeurs de type character varying et text, et lors de l'utilisation de la correspondance de motifs, par exemple avec LIKE ou avec les expressions rationnelles.
L'espace ncessaire pour une chane de caractres courte (jusqu' 126 octets) est de un octet, plus la taille de la chane qui inclut le
remplissage avec des espaces dans le cas du type character. Les chanes plus longues ont quatre octets d'en-tte au lieu d'un seul.
Les chanes longues sont automatiquement compresses par le systme, donc le besoin pourrait tre moindre. Les chanes vraiment trs longues sont stockes dans des tables supplmentaires, pour qu'elles n'empchent pas d'accder rapidement des valeurs
plus courtes. Dans tous les cas, la taille maximale possible pour une chane de caractres est de l'ordre de 1 Go. (La taille maximale pour n dans la dclaration de type est infrieure. Il ne sert rien de modifier ce comportement, car avec les encodages sur
plusieurs octets, les nombres de caractres et d'octets peuvent tre trs diffrents. Pour stocker de longues chanes sans limite suprieure prcise, il est prfrable d'utiliser les types text et character varying sans taille, plutt que d'indiquer une limite de taille
arbitraire.)

Astuce
Il n'y a aucune diffrence de performance parmi ces trois types, si ce n'est la place disque supplmentaire requise
pour le type remplissage et quelques cycles CPU supplmentaires pour vrifier la longueur lors du stockage dans
une colonne contrainte par la taille. Bien que character(n) ait des avantages en terme de performance sur certains
autres systmes de bases de donnes, il ne dispose pas de ce type d'avantages dans PostgreSQL ; en fait, charac86

Types de donnes

ter(n) est habituellement le plus lent des trois cause des cots de stockage supplmentaires. Dans la plupart des situations, les types text et character varying peuvent tre utiliss leur place.
On peut se rfrer la Section 4.1.2.1, Constantes de chanes pour obtenir plus d'informations sur la syntaxe des libells de
chanes, et le Chapitre 9, Fonctions et oprateurs pour des informations complmentaires sur les oprateurs et les fonctions. Le jeu
de caractres de la base de donnes dtermine celui utilis pour stocker les valeurs texte ; pour plus d'informations sur le support
des jeux de caractres, se rfrer la Section 22.3, Support des jeux de caractres .
Exemple 8.1. Utilisation des types caractre

CREATE TABLE test1 (a character(4));


INSERT INTO test1 VALUES ('ok');
SELECT a, char_length(a) FROM test1; -a
| char_length
------+------------ok
|
2
CREATE
INSERT
INSERT
INSERT
ERROR:
INSERT
SELECT

TABLE test2 (b varchar(5));


INTO test2 VALUES ('ok');
INTO test2 VALUES ('bien
');
INTO test2 VALUES ('trop long');
value too long for type character varying(5)
INTO test2 VALUES ('trop long'::varchar(5)); -- troncature explicite
b, char_length(b) FROM test2;

b
| char_length
-------+------------ok
|
2
bien |
5
trop |
5
La fonction char_length est dcrite dans la Section 9.4, Fonctions et oprateurs de chanes .
Il y a deux autres types caractre de taille fixe dans PostgreSQL. Ils sont dcrits dans le Tableau 8.5, Types caractres spciaux . Le type name existe uniquement pour le stockage des identifiants dans les catalogues systmes et n'est pas destin tre
utilis par les utilisateurs normaux. Sa taille est actuellement dfinie 64 octets (63 utilisables plus le terminateur) mais doit tre
rfrence en utilisant la constante NAMEDATALEN en code source C. La taille est dfinie la compilation (et est donc ajustable
pour des besoins particuliers). La taille maximale par dfaut peut ventuellement tre modifie dans une prochaine version. Le
type "char" (attention aux guillemets) est diffrent de char(1) car il n'utilise qu'un seul octet de stockage. Il est utilis dans les catalogues systmes comme un type d'numration simpliste.
Tableau 8.5. Types caractres spciaux

Nom

Taille de stockage

Description

"char"

1 octet

type interne d'un octet

name

64 octets

type interne pour les noms d'objets

8.4. Types de donnes binaires


Le type de donnes bytea permet de stocker des chanes binaires ; voir le Tableau 8.6, Types de donnes binaires .
Tableau 8.6. Types de donnes binaires

Nom

Espace de stockage

Description

bytea

un quatre octets plus la taille Chane binaire de longueur variable


de la chane binaire stocker

Une chane binaire est une squence d'octets. Les chanes binaires se distinguent des chanes de caractres de deux faons : tout
87

Types de donnes

d'abord, les chanes binaires permettent de stocker des octets de valeurs zro ainsi que les autres caractres non imprimables
(habituellement, les octets en dehors de l'chelle de 32 126). Les chanes de caractres interdisent les octets de valeur zro et interdisent aussi toute valeur d'octet ou squence d'octets invalide selon l'encodage slectionn pour la base de donnes. Ensuite, les
oprations sur les chanes binaires traitent rellement les octets alors que le traitement de chanes de caractres dpend de la configuration de la locale. En rsum, les chanes binaires sont appropries pour le stockage de donnes que le dveloppeur considre
comme des octets bruts alors que les chanes de caractres sont appropries pour le stockage de texte.
Le type bytea supporte deux formats externes pour l'entre et la sortie : le format d'chappement ( escape ) historique de PostgreSQL et le format hexadcimal ( hex ). Les deux sont accepts en entre. Le format de sortie dpend du paramtre de configuration bytea_output ; ce dernier slectionne par dfaut le format hexadcimal. (Notez que le format hexadcimal est disponible
depuis PostgreSQL 9.0 ; les versions antrieures et certains outils ne le comprennent pas.)
Le standard SQL dfinit un type de chane binaire diffrent, appel BLOB ou BINARY LARGE OBJECT. Le format en entre est
diffrent du bytea, mais les fonctions et oprateurs fournis sont pratiquement les mmes.

8.4.1. Le format hexadcimal bytea


Le format hex code les donnes binaires sous la forme de deux chiffres hexadcimaux par octet, le plus significatif en premier.
La chane complte est prcde par la squence \x (pour la distinguer du format d'chappement). Dans la majorit des cas
(exactement les mmes pour lesquelles les antislashs sont doubls dans le format d'chappement), l'antislash initial peut avoir besoin d'tre chapp par un doublage du caractre ; les dtails sont disponibles plus bas. Les chiffres hexadcimaux peuvent tre
soit en majuscule, soit en minuscule, et les espaces blancs sont permis entre les paires de chiffres (mais pas l'intrieur d'une paire
ni dans la squence \x de dbut). Le format hexadcimal est compatible avec une grande varit d'applications et de protocoles
externes, et il a tendance tre plus rapide convertir que le format d'chappement. Son utilisation est donc prfre.
Exemple :
SELECT E'\\xDEADBEEF';

8.4.2. Le format d'chappement bytea


Le format d'chappement ( escape ) est le format traditionnel de PostgreSQL pour le type bytea. Son approche est de reprsenter une chane binaire comme un squence de caractres ASCII et de convertir les donnes qui ne peuvent pas tre reprsents
en ASCII en une squence spciale d'chappement. Si, du point de vue de l'application, reprsenter les octets sous la forme de caractres revet un sens, alors cette reprsentation est intressante. En pratique, c'est gnralement source de confusion car cela diminue la distinction entre chanes binaires et chanes textuelles. De plus le mcanisme particulier de l'chappement qui a t choisi
est quelque peu unwieldy. Donc ce format devrait probablement tre vit pour la plupart des nouvelles applications.
Lors de la saisie de valeurs bytea dans le format d'chappement, les octets de certaines valeurs doivent tre chapps alors que les
autres valeurs d'octet peuvent tre chapps. En gnral, pour chapper un octet, il suffit de le convertir dans sa valeur octal compose de trois chiffres et de la faire prcder d'un antislash (ou de deux antislashs s'il faut utiliser la syntaxe d'chappement de
chanes). L'antislash lui-mme (octet 92) peut alternativement tre reprsent par un double antislashs. Le Tableau 8.7, Octets
littraux bytea chapper affiche les caractres qui doivent tre chapps, et donne les squences d'chappement possibles.
Tableau 8.7. Octets littraux bytea chapper

Valeur
l'octet

dcimale

de Description

Reprsentation chap- Exemple


pe en entre

Reprsentation en sortie

octet zro

E'\\000'

SELECT
\000
E'\\000'::bytea;

39

apostrophe

'''' or E'\\047'

SELECT
E'\''::bytea;

'

92

antislash

E'\\\\'
E'\\134'

or SELECT
E'\\\\'::bytea;

\\

de 0 31 et de 127 255 octets


chables

non

affi- E'\\xxx' (octal va- SELECT


\001
lue)
E'\\001'::bytea;

La ncessit d'chapper les octets non affichables dpend des paramtrages de la locale. Il est parfois possible de s'en sortir sans
chappement. Le rsultat de chacun des exemples du Tableau 8.7, Octets littraux bytea chapper fait exactement un octet,
mme si la reprsentation en sortie fait plus d'un caractre.
S'il faut crire tant d'antislashs, comme indiqu dans le Tableau 8.7, Octets littraux bytea chapper , c'est qu'une chane bi88

Types de donnes

naire doit passer travers deux phases d'analyse dans le serveur PostgreSQL. Le premier antislash de chaque paire est vu
comme un caractre d'chappement par l'analyseur de chane (en supposant que la syntaxe d'chappement des chanes soit utilise)
et est donc consomm, laissant le second antislash de la paire. (Les chanes guillemets dollar peuvent tre utilises pour viter ce
niveau d'chappement.) L'antislash restant est compris par la fonction d'entre de PostgreSQL comme le dbut d'une valeur octale sur trois caractres ou comme l'chappement d'un autre antislash. Par exemple, une chane littrale passe au serveur comme
E'\\001' devient \001 aprs tre passe au travers de l'analyseur d'chappement de chane. Le \001 est envoy la fonction
d'entre de bytea, qui le convertit en un octet simple ayant une valeur dcimale de 1. Le guillemet simple n'est pas trait spcialement par bytea et suit les rgles normales des chanes littrales de chane. Voir aussi la Section 4.1.2.1, Constantes de chanes .
Les octets de bytea sont galement chapps en sortie. En gnral, tout octet non-imprimable est converti en son quivalent
octal sur trois caractres et prcd d'un antislash. La plupart des caractres imprimables sont affichs avec leur reprsentation
standard dans le jeu de caractres du client. Les octets de valeur dcimale 92 (antislash) sont doubls. Les dtails sont dans le Tableau 8.8, Octets chapps en sortie pour bytea .
Tableau 8.8. Octets chapps en sortie pour bytea

Valeur
l'octet

dcimale

de Description

Reprsentation de sor- Exemple


tie chappe

92

antislash

0 31 et 127 255

octets non affichables \xxx (valeur octale)

32 126

octets affichables

\\

Rsultat en sortie

SELECT
\\
E'\\134'::bytea;
SELECT
\001
E'\\001'::bytea;

Reprsentation dans le SELECT


~
jeu de caractres du E'\\176'::bytea;
client

En fonction de l'interface utilise pour accder PostgreSQL, un travail supplmentaire d'chappement/de dschappement
des chanes bytea peut tre ncessaire. Il faut galement chapper les sauts de lignes et retours la ligne si l'interface les traduit
automatiquement, par exemple.

8.5. Types date/heure


PostgreSQL supporte l'ensemble des types date et heure du SQL. Ces types sont prsents dans le Tableau 8.9, Types date et
heure . Les oprations disponibles sur ces types de donnes sont dcrites dans la Section 9.9, Fonctions et oprateurs sur date/
heure .
Tableau 8.9. Types date et heure

Nom

Taille de stockage

Description

Valeur minimale

Valeur maximale

Rsolution

timestamp [ (p) ] [ 8 octets


without time zone ]

date et heure (sans 4713 avant JC


fuseau horaire)

294276 aprs JC

1 microseconde / 14
chiffres

timestamp [ (p) ] 8 octets


with time zone

date et heure, avec 4713 avant JC


fuseau horaire

294276 aprs JC

1 microseconde / 14
chiffres

date

date seule
d'heure)

5874897 aprs JC

1 jour

4 octets

(pas 4713 avant JC

time [ (p) ] [ wi- 8 octets


thout time zone ]

heure seule (pas de 00:00:00.00


date)

24:00:00

1 microseconde / 14
chiffres

time [ (p) ] with 12 octets


time zone

heure seule, avec fu- 00:00:00+1459


seau horaire

24:00:00-1459

1 microseconde / 14
chiffres

interval [ champs ] 16 octets


[ (p) ]

intervalles de temps -178000000 annes 178000000 annes

1 microseconde / 14
chiffres

Note
Le standard SQL impose que timestamp soit un quivalent de timestamp without time zone. PostgreSQL force ce
comportement partir de la version 7.3. Les versions antrieures traitaient ce type de donnes comme le type timestamp with time zone.) timestamptz est accept comme abrviation pour timestamp with time zone ; c'est une
89

Types de donnes

extension PostgreSQL.
time, timestamp, et interval acceptent une prcision optionnelle p, qui indique le nombre de dcimales pour les secondes. Il n'y a
pas, par dfaut, de limite explicite cette prcision. Les valeurs acceptes pour p s'tendent de 0 6 pour les types timestamp et
interval.

Note
Quand des valeurs de type timestamp sont stockes sur des entiers de 8 octets (ce qui est la valeur par dfaut actuelle), la prcision la microseconde prs est disponible sur tout le spectre des valeurs. Quand les timestamp sont
stocks en nombres virgule flottante double prcision la place (une option de compilation obsolte), la limite effective de prcision peut tre infrieure 6. Les valeurs de type timestamp sont stockes en secondes avant ou
aprs le 01/01/2000 minuit. Quand les valeurs timestamp sont implmentes avec des nombres virgule flottante,
la prcision la microseconde n'est obtenue que sur les quelques annes autour du 01/01/2000, et dcrot pour les
dates plus loignes. Notez qu'utiliser des types date virgule flottante permet d'avoir une plus grande tendue de
timestamp : de 4713 av. J.-C. 5874897 ap. J.-C., la diffrence de ce qui est crit plus haut.
La mme option de compilation dtermine aussi si les valeurs de type time et interval sont stockes en tant que
nombres virgule flottante ou entiers de 8 octets. Dans le cas de la virgule flottante, la prcision des valeurs de
type interval se dgradent avec leur accroissement.
Pour les types time, l'intervalle accept pour p s'tend de 0 6 pour les entiers sur 8 octets et de 0 10 pour les nombres virgule
flottante.
Le type interval a une option supplmentaire, qui permet de restreindre le jeu de champs stocks en crivant une de ces expressions :
YEAR
MONTH
DAY
HOUR
MINUTE
SECOND
YEAR TO MONTH
DAY TO HOUR
DAY TO MINUTE
DAY TO SECOND
HOUR TO MINUTE
HOUR TO SECOND
MINUTE TO SECOND
Notez que si champs et p sont tous les deux indiqus, champs doit inclure SECOND, puisque la prcision s'applique uniquement
aux secondes.
Le type time with time zone est dfini dans le standard SQL mais sa dfinition lui prte des proprits qui font douter de son utilit. Dans la plupart des cas, une combinaison de date, time, timestamp without time zone et timestamp with time zone devrait permettre de rsoudre toutes les fonctionnalits de date et heure ncessaires une application.
Les types abstime et reltime sont des types de prcision moindre, utiliss en interne. Il n'est pas recommand de les utiliser dans de
nouvelles applications car ils pourraient disparatre dans une prochaine version.

8.5.1. Saisie des dates et heures


La saisie de dates et heures peut se faire dans la plupart des formats raisonnables, dont ISO8601, tout format compatible avec
SQL, le format POSTGRES traditionnel ou autres. Pour certains formats, l'ordre des jours, mois et annes en entre est ambigu.
Il est alors possible de prciser l'ordre attendu pour ces champs. Le paramtre datestyle peut tre positionn MDY pour choisir
une interprtation mois-jour-anne, DMY pour jour-mois-anne ou YMD pour anne-mois-jour.
PostgreSQL est plus flexible que la norme SQL ne l'exige pour la manipulation des dates et des heures. Voir l'Annexe B, Support de date/heure pour connatre les rgles exactes de reconnaissance des dates et heures et les formats reconnus pour les champs
texte comme les mois, les jours de la semaine et les fuseaux horaires.
Tout libell de date ou heure saisi doit tre plac entre apostrophes, comme les chanes de caractres. La Section 4.1.2.7,
Constantes d'autres types peut tre consulte pour plus d'information. SQL requiert la syntaxe suivante :
type [ (p) ] 'valeur'
90

Types de donnes

o p, prcision optionnelle, est un entier correspondant au nombre de dcimales du champ secondes. La prcision peut tre prcise pour les types time, timestamp, et interval. Les valeurs admissibles sont mentionnes plus haut. Si aucune prcision n'est indique dans une dclaration de constante, celle de la valeur littrale est utilise.

8.5.1.1. Dates
Le Tableau 8.10, Saisie de date regroupe les formats de date possibles pour la saisie de valeurs de type date.
Tableau 8.10. Saisie de date

Exemple

Description

1999-01-08

ISO-8601 ; 8 janvier, quel que soit le mode (format recommand)

January 8, 1999

sans ambigut quel que soit le style de date (datestyle)

1/8/1999

8 janvier en mode MDY ; 1er aot en mode DMY

1/18/1999

18 janvier en mode MDY ; rejet dans les autres modes

01/02/03

2 janvier 2003 en mode MDY ; 1er fvrier 2003 en mode DMY ; 3 fvrier 2001 en mode YMD

1999-Jan-08

8 janvier dans tous les modes

Jan-08-1999

8 janvier dans tous les modes

08-Jan-1999

8 janvier dans tous les modes

99-Jan-08

8 janvier en mode YMD, erreur sinon

08-Jan-99

8 janvier, sauf en mode YMD : erreur

Jan-08-99

8 janvier, sauf en mode YMD : erreur

19990108

ISO-8601 ; 8 janvier 1999 dans tous les modes

990108

ISO-8601 ; 8 janvier 1999 dans tous les modes

1999.008

Anne et jour de l'anne

J2451187

Jour du calendrier Julien

January 8, 99 BC

anne 99 avant Jsus Christ

8.5.1.2. Heures
Les types heure-du-jour sont time [ (p) ] without time zone et time [ (p) ] with time zone. time est quivalent time without time
zone.
Les saisies valides pour ces types sont constitues d'une heure suivie ventuellement d'un fuseau horaire (voir le Tableau 8.11,
Saisie d'heure et le Tableau 8.12, Saisie des fuseaux horaires ). Si un fuseau est prcis pour le type time without time zone,
il est ignor sans message d'erreur. Si une date est indique, elle est ignore sauf si un fuseau horaire impliquant une rgle de
changement d'heure (heure d't/heure d'hiver) est prcis, America/New_York par exemple. Dans ce cas, la date est ncessaire pour pouvoir dterminer la rgle de calcul de l'heure qui s'applique. Le dcalage appropri du fuseau horaire est enregistr
dans la valeur de time with time zone.
Tableau 8.11. Saisie d'heure

Exemple

Description

04:05:06.789

ISO 8601

04:05:06

ISO 8601

04:05

ISO 8601

040506

ISO 8601

04:05 AM

Identique 04:05 ; AM n'affecte pas la valeur

04:05 PM

Identique 16:05 ; l'heure doit tre <= 12

04:05:06.789-8

ISO 8601

04:05:06-08:00

ISO 8601

04:05-08:00

ISO 8601

040506-08

ISO 8601
91

Types de donnes

Exemple

Description

04:05:06 PST

fuseau horaire abrg

2003-04-12
fuseau horaire en nom complet
04:05:06
America/New_York

Tableau 8.12. Saisie des fuseaux horaires

Exemple

Description

PST

Abrviation pour l'heure standard du Pacifique (Pacific Standard Time)

America/New_York Nom complet du fuseau horaire


PST8PDT

Nommage POSIX du fuseau horaire

-8:00

Dcalage ISO-8601 pour la zone PST

-800

Dcalage ISO-8601 pour la zone PST

-8

Dcalage ISO-8601 pour la zone PST

zulu

Abrviation militaire de GMT

Version courte de zulu

L'Section 8.5.3, Fuseaux horaires apporte des prcisions quant la faon d'indiquer les fuseaux horaires.

8.5.1.3. Horodatage
Les saisies valides sont constitues de la concatnation d'une date et d'une heure, ventuellement suivie d'un fuseau horaire et d'un
qualificatif AD (aprs Jsus Christ) ou BC (avant Jsus Christ). (AD/BC peut aussi apparatre avant le fuseau horaire mais ce n'est
pas l'ordre prfr.) Ainsi :
1999-01-08 04:05:06
et :
1999-01-08 04:05:06 -8:00
sont des valeurs valides, qui suivent le standard ISO 8601. Le format trs courant :
January 8 04:05:06 1999 PST
est galement support.
Le standard SQL diffrencie les liblls timestamp without time zone et timestamp with time zone par la prsence d'un symbole
+ ou d'un - et le dclage du fuseau horaire aprs l'indication du temps. De ce fait, d'aprs le standard,
TIMESTAMP '2004-10-19 10:23:54'
est du type timestamp without time zone alors que
TIMESTAMP '2004-10-19 10:23:54+02'
est du type timestamp with time zone. PostgreSQL n'examine jamais le contenu d'un libell avant de dterminer son type. Du
coup, il traite les deux ci-dessus comme des valeurs de type timestamp without time zone. Pour s'assurer qu'un littral est trait
comme une valeur de type timestamp with time zone, il faut prciser explicitement le bon type :
TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'
Dans un libell de type timestamp without time zone, PostgreSQL ignore silencieusement toute indication de fuseau horaire.
C'est--dire que la valeur rsultante est drive des champs date/heure de la valeur saisie et n'est pas corrige par le fuseau horaire.
Pour timestamp with time zone, la valeur stocke en interne est toujours en UTC (Universal Coordinated Time ou Temps Universel Coordonn), aussi connu sous le nom de GMT (Greenwich Mean Time). Les valeurs saisies avec un fuseau horaire explicite
sont converties en UTC l'aide du dcalage appropri. Si aucun fuseau horaire n'est prcis, alors le systme considre que la date
est dans le fuseau horaire indiqu par le paramtre systme timezone, et la convertit en UTC en utilisant le dcalage de la zone
timezone.
Quand une valeur timestamp with time zone est affiche, elle est toujours convertie de l'UTC vers le fuseau horaire courant
(variable timezone), et affiche comme une heure locale. Pour voir l'heure dans un autre fuseau horaire, il faut, soit changer la
valeur de timezone, soit utiliser la construction AT TIME ZONE (voir la Section 9.9.3, AT TIME ZONE ).
92

Types de donnes

Les conversions entre timestamp without time zone et timestamp with time zone considrent normalement que la valeur timestamp without time zone utilise le fuseau horaire timezone. Un fuseau diffrent peut tre choisi en utilisant AT TIME ZONE.

8.5.1.4. Valeurs spciales


PostgreSQL supporte plusieurs valeurs de dates spciales, dans un souci de simplification. Ces valeurs sont prsentes dans le
Tableau 8.13, Saisie de dates/heures spciales . Les valeurs infinity et -infinity ont une reprsentation spciale dans le
systme et sont affiches ainsi ; les autres ne sont que des raccourcies de notation convertis en dates/heures ordinaires lorsqu'ils
sont lus. (En particulier, now et les chanes relatives sont converties en une valeur de temps spcifique leur lecture). Toutes ces
valeurs doivent tre crites entre simples quotes lorsqu'elles sont utilises comme des constantes dans les commandes SQL.
Tableau 8.13. Saisie de dates/heures spciales

Saisie

Types valides

epoch

date, timestamp

infinity

date, timestamp

-infinity

date, timestamp

now

date, time, timestamp

today

date, timestamp

tomorrow

date, timestamp

yesterday

date, timestamp

allballs

time

Les fonctions suivantes, compatibles avec le standard SQL, peuvent aussi tre utilises pour obtenir l'heure courante pour le type
de donnes correspondant : CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME, LOCALTIMESTAMP.
Les quatre derniers acceptent une indication optionnelle de prcision en dessous de la seconde (voir la Section 9.9.4, Date/Heure
courante ). Ce sont l des fonctions SQL qui ne sont pas reconnues comme chanes de saisie de donnes.

8.5.2. Affichage des dates et heures


Le format de sortie des types date/heure peut tre positionn l'un des quatre formats de date suivants : ISO 8601, SQL (Ingres),
traditionnel POSTGRES (date au format Unix date) ou German (germanique). Le format par dfaut est le format ISO. (Le standard SQL impose l'utilisation du format ISO 8601. Le nom du format d'affichage SQL est mal choisi, un accident historique.)
Le Tableau 8.14, Styles d'affichage de date/heure prsente des exemples de chaque format d'affichage. La sortie d'un type date
ou time n'est videmment compose que de la partie date ou heure, comme montr dans les exemples.
Tableau 8.14. Styles d'affichage de date/heure

Spcification de style

Description

Exemple

ISO

standard ISO 8601/SQL

1997-12-17 07:37:16-08

SQL

style traditionnel

12/17/1997 07:37:16.00 PST

POSTGRES

style original

Wed Dec 17 07:37:16 1997 PST

German

style rgional

17.12.1997 07:37:16.00 PST

Dans les styles SQL et POSTGRES, les jours apparaissent avant le mois si l'ordre des champs DMY a t prcis, sinon les mois
apparaissent avant les jours (voir la Section 8.5.1, Saisie des dates et heures pour savoir comment ce paramtre affecte
l'interprtation des valeurs en entre). Le Tableau 8.15, Convention de prsentation des dates prsente un exemple.
Tableau 8.15. Convention de prsentation des dates

Valeur de datestyle (style de date)

Ordre de saisie

Exemple d'affichage

SQL, DMY

jour/mois/anne

17/12/1997 15:37:16.00 CET

SQL, MDY

mois/jour/anne

12/17/1997 07:37:16.00 PST

Postgres, DMY

jour/mois/anne

Wed 17 Dec 07:37:16 1997 PST

93

Types de donnes

Les styles de date/heure peuvent tre slectionns l'aide de la commande SET datestyle, du paramtre datestyle du fichier de
configuration postgresql.conf ou par la variable d'environnement PGDATESTYLE sur le serveur ou le client. La fonction de
formatage to_char (voir Section 9.8, Fonctions de formatage des types de donnes ) permet de formater les affichages de
date/heure de manire plus flexible.

8.5.3. Fuseaux horaires


Les fuseaux horaires et les conventions lies sont influences par des dcisions politiques, pas uniquement par la gomtrie de la
terre. Les fuseaux horaires se sont quelque peu standardiss au cours du vingtime sicle mais continuent tre soumis des changements arbitraires, particulirement en respect des rgles de changement d'heure (heure d't/heure d'hiver). PostgreSQL utilise la trs rpandue base de donnes de fuseaux horaires zoneinfo pour grer les informations sur les rgles de fuseau horaire
historiques. Pour les dates se situant dans le futur, PostgreSQL part de l'assomption que les dernires rgles connues pour un fuseau continueront s'appliquer dans le futur.
PostgreSQL se veut compatible avec les dfinitions standard SQL pour un usage typique. Nanmoins, le standard SQL possde
un mlange trange de types de date/heure et de possibilits. Deux problmes vidents sont :

bien que le type date ne peut pas se voir associer un fuseau horaire, le type heure peut en avoir un. Les fuseaux horaires, dans
le monde rel, ne peuvent avoir de sens qu'associs une date et une heure, vu que l'cart peut varier avec l'heure d't ;

le fuseau horaire par dfaut est prcis comme un cart numrique constant avec l'UTC. Il n'est, de ce fait, pas possible de
s'adapter l'heure d't ou d'hiver lorsque l'on fait des calculs arithmtiques qui passent les limites de l'heure d't et de l'heure
d'hiver.

Pour viter ces difficults, il est recommand d'utiliser des types date/heure qui contiennent la fois une date et une heure lorsque
les fuseaux horaires sont utiliss. Il est galement prfrable de ne pas utiliser le type time with time zone. (Ce type est nanmoins
propos par PostgreSQL pour les applications existantes et pour assurer la compatibilit avec le standard SQL.) PostgreSQL
utilise le fuseau horaire local pour tous les types qui ne contiennent qu'une date ou une heure.
Toutes les dates et heures lies un fuseau horaire sont stockes en interne en UTC. Elles sont converties en heure locale dans le
fuseau indiqu par le paramtre de configuration timezone avant d'tre affich sur le client.
PostgreSQL permet d'indiquer les fuseaux horaires de trois faons diffrentes :

un nom complet de fuseau horaire, par exemple America/New_York. Les noms reconnus de fuseau horaire sont lists dans
la vue pg_timezone_names (voir Section 45.67, pg_timezone_names ). PostgreSQL utilise les donnes zoneinfo
pour cela, les mmes noms sont donc reconnus par de nombreux autres logiciels ;

une abrviation de fuseau horaire, par exemple PST. Une telle indication ne dfinit qu'un dcalage particulier partir d'UTC,
en contraste avec les noms complets de fuseau horaire qui peuvent aussi impliquer un ensemble de dates pour le changement
d'heure. Les abrviations reconnues sont listes dans la vue pg_timezone_abbrevs (voir Section 45.66,
pg_timezone_abbrevs ). Les paramtres de configuration timezone et log_timezone ne peuvent pas tre configurs l'aide
d'une abrviation de fuseau horaire, mais ces abrviations peuvent tre utilises dnas les saisies de date/heure et avec
l'oprateur AT TIME ZONE ;

une spcification POSIX de fuseau sous la forme STDdcalage ou STDdcalageDST avec STD une abrviation de fuseau et dcalage un dcalage numrique en nombre d'heures l'ouest d'UTC et DST une abrviation optionnelle de changement d'heure, interprter comme une heure avant le dcalage donn. Par exemple si EST5EDT n'est pas dj reconnu comme
fuseau horaire, il est accept et est fonctionnellement quivalent l'heure du fuseau de la cte est des USA. Si un nom de
changement d'heure est prsent, il est interprt selon les rgles rgissant les changements d'heure utilises dans l'entre posixrules de la base de donnes des fuseaux horaires, zoneinfo. Dans une installation PostgreSQL standard, posixrules est identique US/Eastern, pour que les spcifications POSIX des fuseaux horaires correspondent aux rgles de
changements d'heure aux tats-Unis. Ce comportement peut, au besoin, tre ajust en remplaant le fichier posixrules.

En rsum, il y a une diffrence entre les abrviations et les noms complets : les abrviations reprsentent toujours un dcalage
fixe par rapport UTC alors que la plupart des noms complets impliquent une rgle de changement d'heure et donc deux dcalages possibles.
La fonctionnalit des fuseaux horaires POSIX peut accepter silencieusement des saisies errones car il n'y a pas de vrification des
abrviations de fuseaux horaires. Par exemple, SET TIMEZONE TO FOOBAR0 fonctionne mais conduit le systme utiliser en
ralit une abrviation trs particulire d'UTC. Un autre problme conserver en tte est que, pour les noms des fuseaux horaires
POSIX, les dcalages positifs sont utiliss pour les emplacements situs l'ouest de Greenwich. Partout ailleurs, PostgreSQL
suit la convention ISO-8601 pour qui les dcalages positifs de fuseaux horaires concernent l'est de Greenwich.
Dans tous les cas, les noms des fuseaux horaires sont insensibles la casse. (C'est un changement par rapport aux versions de
PostgreSQL antrieures la 8.2 qui taient sensibles la casse dans certains cas et pas dans d'autres.)
94

Types de donnes

Ni les noms complets ni les abrviations ne sont cods en dur dans le serveur ; ils sont obtenus partir des fichiers de configuration stocks sous .../share/timezone/ et .../share/timezonesets/ du rpertoire d'installation (voir Section B.3,
Fichiers de configuration date/heure ).
Le paramtre de configuration timezone peut tre fix dans le fichier postgresql.conf ou par tout autre moyen standard dcrit dans le Chapitre 18, Configuration du serveur. Il existe aussi quelques manires spciales de le configurer :

si timezone n'est prcis ni dans postgresql.conf ni comme une option en ligne de commande du serveur, le serveur
tente d'utiliser la valeur de la variable d'environnement TZ comme fuseau horaire par dfaut. Si TZ n'est pas dfinie ou ne fait
pas partie des noms de fuseau horaire connus par PostgreSQL, le serveur tente de dterminer le fuseau horaire par dfaut du
systme d'exploitation en vrifiant le comportement de la fonction localtime() de la bibliothque C. Le fuseau horaire par
dfaut est slectionn comme la correspondance la plus proche parmi les fuseaux horaires connus par PostgreSQL ; (Ces
rgles sont aussi utilises pour choisir la valeur par dfaut de log_timezone, si elle n'est pas prcise.)

la commande SQL SET TIME ZONE configure le fuseau horaire pour une session. C'est une autre faon d'indiquer SET TIMEZONE TO avec une syntaxe plus compatible avec les spcifications SQL ;

la variable d'environnement PGTZ est utilise par les applications clientes fondes sur libpq pour envoyer une commande SET
TIME ZONE au serveur lors de la connexion.

8.5.4. Saisie d'intervalle


Les valeurs de type interval peuvent tre saisies en utilisant la syntaxe verbeuse suivante :
[@] quantit
unit [quantit
unit...]
[direction]
o quantit est un nombre (ventuellement sign) ; unit est microsecond millisecond, second, minute, hour,
day, week, month, year, decade, century, millennium, ou des abrviations ou pluriels de ces units ; direction
peut tre ago (pour indiquer un intervalle ngatif) ou vide. Le signe @ est du bruit optionnel. Les quantits de chaque unit diffrente sont implicitement ajoutes, avec prise en compte approprie des signes (+ et -). ago inverse tous les champs. Cette syntaxe
est aussi utilise pour les sorties d'intervalles, si IntervalStyle est positionn postgres_verbose.
Les quantits de jours, heures, minutes et secondes peuvent tre spcifies sans notations explicites d'units. Par exemple '1
12:59:10' est comprise comme '1 day 12 hours 59 min 10 sec'. Par ailleurs, une combinaison d'annes et de
mois peut tre spcifie avec un tiret ; par exemple, '200-10' est compris comme '200 years 10 months'. (Ces formes
raccourcies sont en fait les seules autorises par le standard SQL, et sont utilises pour la sortie quand la variable IntervalStyle est positionne sql_standard.)
Les valeurs d'intervalles peuvent aussi tre crites en tant qu'intervalles de temps ISO 8601, en utilisant soit le format avec dsignateurs de la section 4.4.3.2 ou le format alternatif de la section 4.4.3.3. Le format avec dsignateurs ressemble ceci :
P quantit unit [ quantit unit ...] [ T [ quantit unit ...]]
La chane doit commencer avec un P, et peut inclure un T qui introduit les units de ce type. Les abrviations d'unit disponibles
sont donnes dans Tableau 8.16, Abrviations d'units d'intervalle ISO 8601 . Des units peuvent tre omises, et peuvent tre
spcifies dans n'importe quel ordre, mais les units infrieures 1 jour doivent apparatre aprs T. En particulier, la signification
de M dpend de son emplacement, c'est--dire avant ou aprs T.
Tableau 8.16. Abrviations d'units d'intervalle ISO 8601

Abrviation

Signification

Annes

Mois (dans la zone de date)

Semaines

Jours

Heures

Minutes (dans la zone de temps)

Secondes

95

Types de donnes

Dans le format alternatif :


P [ annes-mois-jours ] [ T heures:minutes:secondes ]
la chane doit commencer par P, et un T spare la zone de date et la zone de temps de l'intervalle. Les valeurs sont donnes comme
des nombres, de faon similaire aux dates ISO 8601.
Lors de l'criture d'une constante d'intervalle avec une spcification de champs, ou lors de l'assignation d'une chane une colonne d'intervalle qui a t dfinie avec une spcification de champs, l'interprtation de quantit sans unit dpend des champs.
Par exemple, INTERVAL '1' YEAR est interprt comme 1 an, alors que INTERVAL '1' est interprt comme 1 seconde. De
plus, les valeurs du champ droite du champ le moins significatif autoris par la spcification de champs sont annules de
faon silencieuse. Par exemple, crire INTERVAL '1 day 2:03:04' HOUR TO MINUTE implique la suppression du
champ des secondes, mais pas celui des journes.
D'aprs le standard SQL toutes les valeurs de tous les champs d'un intervalle doivent avoir le mme signe, ce qui entrane qu'un
signe ngatif initial s'applique tous les champs ; par exemple, le signe ngatif dans l'expression d'intervalle '-1 2:03:04'
s'applique la fois aux jours et aux heures/minutes/secondes. PostgreSQL permet que les champs aient des signes diffrents, et
traditionnellement traite chaque champ de la reprsentation textuelle comme indpendamment sign, ce qui fait que la partie
heure/minute/seconde est considre comme positive dans l'exemple. Si IntervalStyle est positionn sql_standard,
alors un signe initial est considr comme s'appliquant tous les champs (mais seulement si aucun autre signe n'apparat). Sinon,
l'interprtation traditionnnelle de PostgreSQL est utilise. Pour viter les ambiguts, il est recommand d'attacher un signe explicite chaque partie, si au moins un champ est ngatif.
De faon interne, les valeurs de type interval sont stockes comme mois, jours et secondes. C'est ainsi parce que le nombre de
jours d'un mois varie, et un jour peut avoir 23 ou 25 heures si des changements d'heures sont impliqus. Les champs mois et jours
sont des entiers, alors que le champ secondes peut stocker des nombres dcimaux. Les intervalles tant habituellement crs partir de chanes constantes ou de soustractions de timestamps, cette mthode fonctionne bien dans la plupart des cas. Les fonctions
justify_days et justify_hours sont disponibles pour ajuster les jours et heures qui dpassent leurs portes habituelles.
Dans le format verbeux de saisie, et dans certains champs des formats plus compacts, les valeurs de champs peuvent avoir des parties dcimales ; par exemple, '1.5 week' ou '01:02:03.45'. Ces entres sont converties en un nombre appropri de mois,
jours et secondes pour tre stockes. Quand ceci entranerait le stockage d'une valeur dcimale pour les mois ou les jours, la partie
dcimale est ajoute aux champs d'ordre infrieur en utilisant les facteurs de conversion suivants : 1 mois = 30 jours,
1 jour = 24heures. Par exemple, '1.5 month' devient 1 mois et 15 jours. Seules les secondes pourront apparatre comme dcimales en sortie.
Tableau 8.17, Saisie d'intervalle prsente des exemples de saisies d'interval valides.
Tableau 8.17. Saisie d'intervalle

Exemple

Description

1-2

Format SQL standard : 1 an 2 mois

3 4:05:06

Format SQL standard : 3 jours 4 heures 5 minutes 6 secondes

1 year 2 months 3 days 4 hours 5 minutes 6 seconds

Format PostgreSQL traditionnel : 1 an 2 mois 3 jours 4 heures 5


minutes 6 secondes

P1Y2M3DT4H5M6S

format avec dsignateurs ISO 8601 : signification identique


ci-dessus

P0001-02-03T04:05:06

format alternatif ISO 8601 : signification identique cidessus

8.5.5. Affichage d'intervalles


Le format de sortie du type interval peut tre positionn une de ces quatre valeurs : sql_standard, postgres,
postgres_verbose ou iso_8601, en utilisant la commande SET intervalstyle. La valeur par dfaut est le format
postgres. Tableau 8.18, Exemples de styles d'affichage d'intervalles donne des exemples de chaque style de format de sortie.
Le style sql_standard produit une sortie qui se conforme la spcification du standard SQL pour les chanes littrales
d'intervalle, si la valeur de l'intervalle reste dans les restrictions du standard (soit anne-mois seul, ou jour-temps seul, et sans mlanger les composants positifs et ngatifs). Sinon, la sortie ressemble au standard littral anne-mois suivi par une chane jourtemps littrale, avec des signes explicites ajouts pour dsambiguer les intervalles dont les signes seraient mlangs.
La sortie du style postgres correspond la sortie des versions de PostgreSQL prcdant la 8.4, si le paramtre datestyle tait
96

Types de donnes

positionn ISO.
La sortie du style postgres_verbose correspond la sortie des versions de PostgreSQL prcdant la 8.4, si le paramtre
datestyle tait positionn autre chose que ISO.
La sortie du style iso_8601 correspond au format avec designateurs dcrit dans la section 4.4.3.2 du standard ISO 8601.
Tableau 8.18. Exemples de styles d'affichage d'intervalles

Spcification de style

Intervalle anne-mois

Intervalle date-temps

Interval Mixte

sql_standard

1-2

3 4:05:06

-1-2 +3 -4:05:06

postgres

1 year 2 mons

3 days 04:05:06

-1 year -2 mons +3 days 04:05:06

postgres_verbose

@ 1 year 2 mons

@ 3 days 4 hours 5 mins 6 secs @ 1 year 2 mons -3 days 4


hours 5 mins 6 secs ago

iso_8601

P1Y2M

P3DT4H5M6S

P-1Y-2M3DT-4H-5M-6S

8.5.6. Types internes


PostgreSQL utilise les dates du calendrier Julien pour tous les calculs de date/heure. Elles ont la proprit intressante de permettre le calcul de toute date depuis 4713 avant Jsus Christ jusque loin dans le futur, avec pour seule hypothse que l'anne dure
365,2425 jours.
Les conventions pour les dates antrieures au 19me sicle sont d'une lecture intressante mais ne sont pas assez cohrentes pour
tre codes dans un gestionnaire de dates.

8.6. Type boolen


PostgreSQL fournit le type boolean du standard SQL ; voir Tableau 8.19, Type de donnes boolen . Ce type dispose de plusieurs tats : true (vrai), false (faux) et un troisime tat, unknown (inconnu), qui est reprsent par la valeur SQL
NULL.
Tableau 8.19. Type de donnes boolen

Nom

Taille du stockage

Description

boolean

1 octet

tat vrai ou faux

Les libells valides pour l'tat vrai sont :


TRUE
't'
'true'
'y'
'yes'
'on'
'1'
Pour l'tat faux , il s'agit de :
FALSE
'f'
'false'
'n'
'no'
'off'
'0'
Les espaces avant ou aprs, ainsi que la casse, sont ignors. Il est recommand d'utiliser TRUE et FALSE (qui sont compatibles
avec la norme SQL).
L'Exemple 8.2, Utilisation du type boolean. montre que les valeurs boolennes sont affiches avec les lettres t et f.
Exemple 8.2. Utilisation du type boolean.

97

Types de donnes

CREATE TABLE test1 (a boolean, b text);


INSERT INTO test1 VALUES (TRUE, 'sic est');
INSERT INTO test1 VALUES (FALSE, 'non est');
SELECT * FROM test1;
a |
b
---+--------t | sic est
f | non est
SELECT * FROM test1 WHERE a;
a |
b
---+--------t | sic est

8.7. Types numration


Les types numrs (enum) sont des types de donnes qui comprennent un ensemble statique, prdfini de valeurs dans un ordre
spcifique. Ils sont quivalents aux types enum dans de nombreux langages de programmation. Les jours de la semaine ou un ensemble de valeurs de statut pour un type de donnes sont de bons exemples de type enum.

8.7.1. Dclaration de types numrs


Les types enum sont crs en utilisant la commande CREATE TYPE(7). Par exemple :
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
Une fois cr, le type enum peut tre utilis dans des dfinitions de table et de fonction, comme tous les autres types :
CREATE TYPE humeur AS ENUM ('triste', 'ok', 'heureux');
CREATE TABLE personne (
nom text,
humeur_actuelle humeur
);
INSERT INTO personne VALUES ('Moe', 'heureux');
SELECT * FROM personne WHERE humeur_actuelle = 'heureux';
name | humeur_actuelle
------+----------------Moe | heureux
(1 row)

8.7.2. Tri
L'ordre des valeurs dans un type enum correspond l'ordre dans lequel les valeurs sont cres lors de la dclaration du type. Tous
les oprateurs de comparaison et les fonctions d'agrgats relatives peuvent tre utiliss avec des types enum. Par exemple :
INSERT INTO personne VALUES ('Larry', 'triste');
INSERT INTO personne VALUES ('Curly', 'heureux');
SELECT * FROM personne WHERE humeur_actuelle > 'triste';
nom
| humeur_actuelle
-------+----------------Moe
| happy
Curly | ok
(2 rows)
SELECT * FROM personne WHERE humeur_actuelle > 'triste' ORDER BY humeur_actuelle;
nom
| humeur_actuelle
-------+-------------Curly | ok
Moe
| happy
(2 rows)
SELECT nom
FROM personne
WHERE humeur_actuelle = (SELECT MIN(humeur_actuelle) FROM personne);
98

Types de donnes

nom
------Larry
(1 row)

8.7.3. Surt du type


Chaque type de donnes numr est spar et ne peut pas tre compar aux autres types numrs. Par exemple :
CREATE TYPE niveau_de_joie AS ENUM ('heureux', 'trs heureux', 'ecstatique');
CREATE TABLE vacances (
nombre_de_semaines integer,
niveau_de_joie niveau_de_joie
);
INSERT INTO vacances(nombre_de_semaines,niveau_de_joie) VALUES (4, 'heureux');
INSERT INTO vacances(nombre_de_semaines,niveau_de_joie) VALUES (6, 'trs heureux');
INSERT INTO vacances(nombre_de_semaines,niveau_de_joie) VALUES (8, 'ecstatique');
INSERT INTO vacances(nombre_de_semaines,niveau_de_joie) VALUES (2, 'triste');
ERROR: invalid input value for enum niveau_de_joie: "triste"
SELECT personne.nom, vacances.nombre_de_semaines FROM personne, vacances
WHERE personne.humeur_actuelle = vacances.niveau_de_joie;
ERROR: operator does not exist: humeur = niveau_de_joie
Si vous avez vraiment besoin de ce type de conversion, vous pouvez soit crire un oprateur personnalis soit ajouter des conversions explicites dans votre requte :
SELECT personne.nom, vacances.nombre_de_semaines FROM personne, vacances
WHERE personne.humeur_actuelle::text = vacances.niveau_de_joie::text;
nom | nombre_de_semaines
------+-------------------Moe |
4
(1 row)

8.7.4. Dtails d'implmentation


Une valeur enum occupe quatre octets sur disque. La longueur du label texte d'une valeur enum est limit au paramtre NAMEDATALEN cod en dur dans PostgreSQL ; dans les constructions standards, cela signifie un maximum de 63 octets.
Les labels enum sont sensibles la casse, donc 'heureux' n'est pas identique 'HEUREUX'. Les espaces blancs sont significatifs
dans les labels.
Les traductions des valeurs enum internes vers des labels texte sont gardes dans le catalogue systme pg_enum. Interroger ce catalogue directement peut s'avrer utile.

8.8. Types gomtriques


Les types de donnes gomtriques reprsentent des objets deux dimensions. Le Tableau 8.20, Types gomtriques liste les
types disponibles dans PostgreSQL. Le type le plus fondamental, le point, est la base de tous les autres types.
Tableau 8.20. Types gomtriques

Nom

Taille de stockage

Reprsentation

Description

point

16 octets

Point du plan

(x,y)

line

32 octets

Ligne infinie (pas entirement implant) ((x1,y1),(x2,y2))

lseg

32 octets

Segment de droite fini

((x1,y1),(x2,y2))

box

32 octets

Bote rectangulaire

((x1,y1),(x2,y2))

path

16+16n octets

Chemin ferm (similaire un polygone) ((x1,y1),...)

path

16+16n octets

Chemin ouvert

[(x1,y1),...]

polygon

40+16n octets

Polygone (similaire un chemin ferm)

((x1,y1),...)

circle

24 octets

Cercle

<(x,y),r> (point central et rayon)


99

Types de donnes

Un large ensemble de fonctions et d'oprateurs permettent d'effectuer diffrentes oprations gomtriques, comme l'chelonnage,
la translation, la rotation, la dtermination des intersections. Elles sont expliques dans la Section 9.11, Fonctions et oprateurs
gomtriques .

8.8.1. Points
Les points sont les briques fondamentales des types gomtriques. Les valeurs de type point sont indiques l'aide d'une des syntaxes suivantes :
( x , y )
x , y
o x et y sont les coordonnes respectives sous forme de nombre virgule flottante.
Les points sont affichs en utilisant la premire syntaxe.

8.8.2. Segments de droite


Les segments de droite (lseg) sont reprsents sous la forme de paires de points l'aide d'une des syntaxes suivantes :
[ ( x1
( ( x1
( x1
x1

,
,
,
,

y1 ) , ( x2
y1 ) , ( x2
y1 ) , ( x2
y1
,
x2

,
,
,
,

y2 ) ]
y2 ) )
y2 )
y2

o (x1,y1) et (x2,y2) sont les points aux extrmits du segment.


Les segments de ligne sont affichs en utilisant la premire syntaxe.

8.8.3. Botes
Les botes (rectangles) sont reprsentes par les paires de points des coins opposs de la bote selon une des syntaxes suivantes :
( ( x1 , y1 ) , ( x2 , y2 ) )
( x1 , y1 ) , ( x2 , y2 )
x1 , y1
,
x2 , y2
o (x1,y1) et (x2,y2) sont les coins opposs du rectangle.
Les rectangles sont affichs selon la deuxime syntaxe.
Les deux coins opposs peuvent tre fournis en entre mais les valeurs seront r-ordonns pour stocker les coins en haut droite et
en bas gauche, dans cet ordre.

8.8.4. Chemins
Les chemins ( type path ) sont reprsents par des listes de points connects. Ils peuvent tre ouverts, si le premier et le dernier
point ne sont pas considrs connects, ou ferms, si le premier et le dernier point sont considrs connects.
Les valeurs de type path sont saisies selon une des syntaxes suivantes :
[ ( x1
( ( x1
( x1
( x1
x1

,
,
,
,
,

y1 ) , ... , ( xn , yn
y1 ) , ... , ( xn , yn
y1 ) , ... , ( xn , yn
y1
, ... ,
xn , yn
y1
, ... ,
xn , yn

) ]
) )
)
)

o les points sont les extrmits des segments de droite qui forment le chemin. Les crochets ([]) indiquent un chemin ouvert alors
que les parenthses (()) indiquent un chemin ferm. Quand les parenthses externes sont omises, comme dans les syntaxes trois
cinq, un chemin ferm est utilis.
Les chemins sont affichs selon la premire ou la seconde syntaxe approprie.

8.8.5. Polygones
Les polygones ( type polygon) sont reprsents par des listes de points (les vertex du polygone). Ils sont trs similaires des chemins ferms, mais ils sont stocks diffremment et disposent de leurs propres routines de manipulation.
Les valeurs de type polygon sont saisies selon une des syntaxes suivantes :
( ( x1 , y1 ) , ... , ( xn , yn ) )
100

Types de donnes

( x1 , y1 ) , ... , ( xn , yn )
( x1 , y1
, ... ,
xn , yn )
x1 , y1
, ... ,
xn , yn
o les points sont les extrmits des segments de droite qui forment les limites du polygone.
Les polygones sont affichs selon la premire syntaxe.

8.8.6. Cercles
Les cercles (type circle) sont reprsents par un point central et un rayon. Les valeurs de type circle sont saisies selon une des syntaxes suivantes :
< ( x
( ( x
( x
x

,
,
,
,

y ) , r >
y ) , r )
y ) , r
y
, r

o (x,y) est le point central et r le rayon du cercle.


Les cercles sont affichs selon la premire syntaxe.

8.9. Types adresses rseau


PostgreSQL propose des types de donnes pour stocker des adresses IPv4, IPv6 et MAC. Ceux-ci sont dcrits dans le Tableau 8.21, Types d'adresses rseau . Il est prfrable d'utiliser ces types plutt que des types texte standard pour stocker les
adresses rseau car ils offrent un contrle de syntaxe lors de la saisie et plusieurs oprateurs et fonctions spcialises (voir la Section 9.12, Fonctions et oprateurs sur les adresses rseau ).
Tableau 8.21. Types d'adresses rseau

Nom

Taille de stockage

Description

cidr

7 ou 19 octets

rseaux IPv4 et IPv6

inet

7 ou 19 octets

htes et rseaux IPv4 et IPv6

macaddr

6 octets

adresses MAC

Lors du tri de donnes de types inet ou cidr, les adresses IPv4 apparaissent toujours avant les adresses IPv6, y compris les adresses
IPv4 encapsules, comme ::10.2.3.4 ou ::ffff:10.4.3.2.

8.9.1. inet
Le type inet stocke une adresse d'hte IPv4 ou IPv6 et, optionnellement, son sous-rseau, le tout dans un seul champ. Le sous-rseau est reprsente par le nombre de bits de l'adresse hte constituent l'adresse rseau (le masque rseau ). Si le masque rseau
est 32 et l'adresse de type IPv4, alors la valeur n'indique pas un sous-rseau, juste un hte. En IPv6, la longueur de l'adresse est de
128 bits, si bien que 128 bits dfinissent une adresse rseau unique. Pour n'accepter que des adresses rseau, il est prfrable
d'utiliser le type cidr plutt que le type inet.
Le format de saisie pour ce type est adresse/y o adresse est une adresse IPv4 ou IPv6 et y est le nombre de bits du masque
rseau. Si y est omis, alors le masque vaut 32 pour IPv4 et 128 pour IPv6, et la valeur reprsente un hte unique. l'affichage, la
portion /y est supprime si le masque rseau indique un hte unique.

8.9.2. cidr
Le type cidr stocke une dfinition de rseau IPv4 ou IPv6. La saisie et l'affichage suivent les conventions Classless Internet Domain Routing. Le format de saisie d'un rseau est address/y o address est le rseau reprsent sous forme d'une adresse
IPv4 ou IPv6 et y est le nombre de bits du masque rseau. Si y est omis, il calcul en utilisant les rgles de l'ancien systme de
classes d'adresses, ceci prs qu'il est au moins assez grand pour inclure tous les octets saisis. Saisir une adresse rseau avec des
bits positionns droite du masque indiqu est une erreur.
Tableau 8.22, Exemples de saisie de types cidr prsente quelques exemples.
Tableau 8.22. Exemples de saisie de types cidr

Saisie cidr

Affichage cidr

abbrev(cidr)

192.168.100.128/25

192.168.100.128/25

192.168.100.128/25

101

Types de donnes

Saisie cidr

Affichage cidr

abbrev(cidr)

192.168/24

192.168.0.0/24

192.168.0/24

192.168/25

192.168.0.0/25

192.168.0.0/25

192.168.1

192.168.1.0/24

192.168.1/24

192.168

192.168.0.0/24

192.168.0/24

128.1

128.1.0.0/16

128.1/16

128

128.0.0.0/16

128.0/16

128.1.2

128.1.2.0/24

128.1.2/24

10.1.2

10.1.2.0/24

10.1.2/24

10.1

10.1.0.0/16

10.1/16

10

10.0.0.0/8

10/8

10.1.2.3/32

10.1.2.3/32

10.1.2.3/32

2001:4f8:3:ba::/64

2001:4f8:3:ba::/64

2001:4f8:3:ba::/64

2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128

2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128

2001:4f8:3:ba:2e0:81ff:fe22:d1f1

::ffff:1.2.3.0/120

::ffff:1.2.3.0/120

::ffff:1.2.3/120

::ffff:1.2.3.0/128

::ffff:1.2.3.0/128

::ffff:1.2.3.0/128

8.9.3. inet vs cidr


La diffrence principale entre les types de donnes inet et cidr rside dans le fait que inet accepte des valeurs avec des bits non
nuls droite du masque de rseau, alors que cidr ne l'accepte pas.

Astuce
Les fonctions host, text et abbrev permettent de modifier le format d'affichage des valeurs inet et cidr.

8.9.4. macaddr
Le type macaddr stocke des adresses MAC, connues par exemple partir des adresses de cartes rseau Ethernet (mais les adresses
MAC sont aussi utilises dans d'autres cas). Les saisies sont acceptes dans les formats suivants :
'08:00:2b:01:02:03'
'08-00-2b-01-02-03'
'08002b:010203'
'08002b-010203'
'0800.2b01.0203'
'08002b010203'
Ces exemples indiquent tous la mme adresse. Les majuscules et les minuscules sont acceptes pour les chiffres a f. L'affichage
se fait toujours selon le premier des formats ci-dessus.
Le standard IEEE 802-2001 spcifie la seconde forme affiche (avec les tirets) comme forme canonique pour les adresses MAC,
et que la premire forme (avec les :) est la notation bits retourns, ce qui donne l'quivalence 08-00-2b-01-02-03 =
01:00:4D:08:04:0C. Cette convention est largement ignore aujourd'hui, et n'a de sens que pour des protocoles rseaux obsoltes
(comme Token Ring). PostgreSQL ne tient pas compte des bits retourns, et tous les formats accepts utilisent l'ordre canonique
LSB.
Les quatre derniers formats ne font partie d'aucun standard.

8.10. Type chane de bits


Les chanes de bits sont des chanes de 0 et de 1. Elles peuvent tre utilises pour stocker ou visualiser des masques de bits. Il y a
deux types bits en SQL : bit(n) et bit varying(n), avec n un entier positif.
Les donnes de type bit doivent avoir une longueur de n bits exactement. Essayer de lui affecter une chane de bits plus longue ou
plus courte dclenche une erreur. Les donnes de type bit varying ont une longueur variable, d'au maximum n bits ; les chanes
plus longues sont rejetes. crire bit sans longueur est quivalent bit(1), alors que bit varying sans longueur indique une taille
illimite.
102

Types de donnes

Note
Lors du transtypage explicite (cast) d'une chane de bits en champ de type bit(n), la chane obtenue est complte
avec des zros ou bien tronque pour obtenir une taille de n bits exactement, sans que cela produise une erreur. De
la mme faon, si une chane de bits est explicitement transtype en un champ de type bit varying(n), elle est tronque si sa longueur dpasse n bits.
Voir la Section 4.1.2.5, Constantes de chanes de bits pour plus d'information sur la syntaxe des constantes en chane de bits.
Les oprateurs logiques et les fonctions de manipulation de chanes sont dcrits dans la Section 9.6, Fonctions et oprateurs sur
les chanes de bits .
Exemple 8.3. Utiliser les types de chanes de bits

CREATE TABLE test (a BIT(3), b BIT VARYING(5));


INSERT INTO test VALUES (B'101', B'00');
INSERT INTO test VALUES (B'10', B'101');
ERROR:

bit string length 2 does not match type bit(3)

INSERT INTO test VALUES (B'10'::bit(3), B'101');


SELECT * FROM test;
a | b
-----+----101 | 00
100 | 101
Une valeur pour une chane de bit ncessite un octet pour chaque groupe de huit bits, plus cinq ou huit octets d'en-tte suivant la
longueur de la chane (les valeurs longues peuvent tre compresses ou dplaces, comme expliqu dans Section 8.3, Types caractre pour les chanes de caractres).

8.11. Types de recherche plein texte


PostgreSQL fournit deux types de donnes conus pour supporter la recherche plein texte qui est l'activit de recherche via une
collection de documents en langage naturel pour situer ceux qui correspondent le mieux une requte. Le type tsvector reprsente
un document dans une forme optimise pour la recherche plein texte alors que le type tsquery reprsente de faon similaire une requte. Chapitre 12, Recherche plein texte fournit une explication dtaille de cette capacit et Section 9.13, Fonctions et oprateurs de la recherche plein texte rsum les fonctions et oprateurs en relation.

8.11.1. tsvector
Une valeur tsvector est une liste trie de lexemes distincts, qui sont des mots qui ont t normaliss pour fusionner diffrentes variantes du mme mot apparaissent (voir Chapitre 12, Recherche plein texte pour plus de dtails). Trier et liminer les duplicats se
font automatiquement lors des entres, comme indiqu dans cet exemple :
SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector;
tsvector
---------------------------------------------------'a' 'and' 'ate' 'cat' 'fat' 'mat' 'on' 'rat' 'sat'
Pour reprsenter des lexemes contenant des espaces blancs ou des signes de ponctuation, entourez-les avec des guillemets
simples :
SELECT $$the lexeme '
' contains spaces$$::tsvector;
tsvector
------------------------------------------'
' 'contains' 'lexeme' 'spaces' 'the'
(Nous utilisons les valeurs litrales entre guillemets simples dans cet exemple et dans le prochain pour viter une confusion en
ayant doubler les guillemets l'intrieur des valeurs litrales.) Les guillemets imbriqus et les antislashs doivent tre doubls :
SELECT $$the lexeme 'Joe''s' contains a quote$$::tsvector;
tsvector
103

Types de donnes

-----------------------------------------------'Joe''s' 'a' 'contains' 'lexeme' 'quote' 'the'


En option, les positions peuvent tre attaches aux lexemes :
SELECT 'a:1 fat:2 cat:3 sat:4 on:5 a:6 mat:7 and:8 ate:9 a:10 fat:11 rat:12'::tsvector;
tsvector
------------------------------------------------------------------------------'a':1,6,10 'and':8 'ate':9 'cat':3 'fat':2,11 'mat':7 'on':5 'rat':12 'sat':4
Une position indique normalement l'emplacement du mot source dans le document. Les informations de position sont utilisables
pour avoir un score de proximit. Les valeurs des positions peuvent aller de 1 16383 ; les grands nombres sont limits silencieusement 16383. Les positions duplique du mme lexeme sont rejetes.
Les lexemes qui ont des positions peuvent aussi avoir un label d'un certain poids. Les labels possibles sont A, B, C ou D. D est la
valeur par dfaut et n'est du coup pas affich en sortie :
SELECT 'a:1A fat:2B,4C cat:5D'::tsvector;
tsvector
---------------------------'a':1A 'cat':5 'fat':2B,4C
Les poids sont typiquement utiliss pour reflter la structure du document en marquant les mots du titre de faon diffrente des
mots du corps. Les fonctions de score de la recherche plein texte peuvent assigner des priorits diffrentes aux marqueurs de poids
diffrents.
Il est important de comprendre que le type tsvector lui-mme ne ralise aucune normalisation ; il suppose que les mots qui lui sont
fournis sont normaliss correctement pour l'application. Par exemple,
select 'The Fat Rats'::tsvector;
tsvector
-------------------'Fat' 'Rats' 'The'
Pour la plupart des applications de recherche en anglais, les mots ci-dessus seraient considrs comme non normaliss mais tsvector n'y prte pas attention. Le texte des documents bruts doit habituellement passer via to_tsvector pour normaliser les mots
de faon approprie pour la recherche :
SELECT to_tsvector('english', 'The Fat Rats');
to_tsvector
----------------'fat':2 'rat':3
De nouveau, voir Chapitre 12, Recherche plein texte pour plus de dtails.

8.11.2. tsquery
Une valeur tsquery enregistre les lexemes qui doivent tre recherchs et les combine en utilisant les oprateurs boolens & (AND),
| (OR) et ! (NOT). Les parenthses peuvent tre utilises pour forcer le regroupement des oprateurs :
SELECT 'fat & rat'::tsquery;
tsquery
--------------'fat' & 'rat'
SELECT 'fat & (rat | cat)'::tsquery;
tsquery
--------------------------'fat' & ( 'rat' | 'cat' )
SELECT 'fat & rat & ! cat'::tsquery;
tsquery
-----------------------'fat' & 'rat' & !'cat'
En l'absence de ces parenthses, ! (NOT) est li plus fortement, et & (AND) est li plus fortement que | (OR).
En option, les lexemes dans une tsquery peuvent tre labeliss avec une lettre de poids ou plus, ce qui les restreint une corres104

Types de donnes

pondance avec les seuls lexemes tsvector pour un de ces poids :


SELECT 'fat:ab & cat'::tsquery;
tsquery
-----------------'fat':AB & 'cat'
Par ailleurs, les lexemes d'une tsquery peuvent tre marqus avec * pour spcifier une correspondance de prfixe :
SELECT 'super:*'::tsquery;
tsquery
----------'super':*
Cette requte fera ressortir tout mot dans un tsvector qui commence par super . Notez que les prfixes sont traits en premier
par les configurations de la recherche plein texte, ce qui signifie que cette comparaison renvoie true :
SELECT to_tsvector( 'postgraduate' ) @@ to_tsquery( 'postgres:*' );
?column?
---------t
(1 row)
car postgres devient postgr :
SELECT to_tsquery('postgres:*');
to_tsquery
-----------'postgr':*
(1 row)
qui ensuite correspond postgraduate.
Les rgles de guillemets pour les lexemes sont identiques celles dcrites ci-dessus pour les lexemes de tsvector ; et, comme avec
tsvector, toute normalisation requise des mots doit se faire avant de les placer dans le type tsquery. La fonction to_tsquery est
convenable pour raliser une telle normalisation :
SELECT to_tsquery('Fat:ab & Cats');
to_tsquery
-----------------'fat':AB & 'cat'

8.12. Type UUID


Le type de donnes uuid stocke des identifiants universels uniques (UUID, acronyme de Universally Unique Identifiers) dcrits
dans les standards RFC 4122, ISO/IEC 9834-8:2005, et d'autres encore. (Certains systmes font rfrence ce type de donnes en
tant qu'identifiant unique global (ou GUID ).) Un identifiant de ce type est une quantit sur 128 bits gnr par un algorithme adquat qui a peu de chances d'tre reproduit par quelqu'un d'autre utilisant le mme algorithme. Du coup, pour les systmes distribus, ces identifiants fournissent une meilleure garantie d'unicit que ce que pourrait fournir une squence, dont la valeur est
unique seulement au sein d'une base de donnes.
Un UUID est crit comme une squence de chiffres hexadcimaux en minuscule, rpartis en diffrents groupes spars par un tiret. Plus prcisment, il s'agit d'un groupe de huit chiffres suivis de trois groupes de quatre chiffres termins par un groupe de
douze chiffres, ce qui fait un total de 32 chiffres reprsentant les 128 bits. Voici un exemple d'UUID dans sa forme standard :
a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
PostgreSQL accepte aussi d'autres formes en entre : utilisation des majuscules, de crochets englobant le nombre, suppression
d'une partie ou de tous les tirets, ajout d'un tiret aprs n'importe quel groupe de quatre chiffres. Voici quelques exemples :
A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
a0eebc999c0b4ef8bb6d6bb9bd380a11
a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
105

Types de donnes

{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}
L'affichage est toujours dans la forme standard.
Pour gnrer des UUID, le module uuid-ossp fournit des fonctions qui implmentent les algorithmes standards. Sinon, les UUID
peuvent tre gnrs par des applications clientes ou par d'autres bibliothques appeles par une fonction serveur.

8.13. Type XML


Le type de donnes xml est utilis pour stocker des donnes au format XML. Son avantage sur un champ de type text est qu'il vrifie que les valeurs sont bien formes. De plus, il existe de nombreuses fonctions pour raliser des oprations de vrification
partir de ce type ; voir la Section 9.14, Fonctions XML . L'utilisation de ce type de donnes requiert que l'tape de compilation
a utilis l'option --with-libxml.
Le type xml peut stocker des documents bien forms, suivant la dfinition du standard XML, ainsi que des fragments de contenu ( content ), qui sont dfinis par XMLDecl? content du standard XML. Cela signifie que les fragments de contenu
peuvent avoir plus d'un lment racine ou nud caractre. L'expression valeurxml IS DOCUMENT permet d'valuer si une
valeur xml particulire est un document complet ou seulement un fragment de contenu.

8.13.1. Crer des valeurs XML


Pour produire une valeur de type xml partir d'une donne de type caractre, utilisez la fonction xmlparse :
XMLPARSE ( { DOCUMENT | CONTENT } valeur)
Quelques exemples :
XMLPARSE (DOCUMENT '<?xml
version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')
Bien que cela soit la seule faon de convertir des chanes de caractre en valeurs XML d'aprs le standard XML, voici des syntaxes spcifiques PostgreSQL :
xml '<foo>bar</foo>'
'<foo>bar</foo>'::xml
Le type xml ne valide pas les valeurs en entre par rapport une dclaration de type de document (DTD), mme quand la valeur
en entre indique une DTD. Il n'existe pas encore de support pour la validation avec d'autres langages de schma XML, comme
XML Schema.
L'opration inverse, produisant une chane de caractres partir d'une valeur au type xml, utilise la fonction xmlserialize:
XMLSERIALIZE ( { DOCUMENT | CONTENT } value AS type )
type peut tre character, character varying ou text (ou un alias de ces derniers). Encore une fois, d'aprs le standard SQL, c'est le
seul moyen de convertir le type xml vers les types caractre mais PostgreSQL autorise aussi la conversion simple de la valeur.
Lorsque les valeurs des chanes de caractre sont converties vers ou partir du type xml sans passer par XMLPARSE ou XMLSERIALIZE, respectivement, le choix de DOCUMENT ou de CONTENT est dtermin par un paramtre de configuration niveau session, XML OPTION , qui peut tre configur par la commande habituelle :
SET XML OPTION { DOCUMENT | CONTENT };
ou la syntaxe PostgreSQL :
SET xmloption TO { DOCUMENT | CONTENT };
La valeur par dfaut est CONTENT, donc toutes les formes de donnes XML sont autorises.

Note
Avec le paramtrage par dfaut des options XML, vous ne pouvez pas convertir directement des chanes de caractres dans le type xml si elles contiennent une dclaration du type de document car la dfinition du fragment de
contenu XML ne les accepte pas. Si vous avez besoin de changer cela, soit vous utilisez XMLPARSE soit vous
106

Types de donnes

changez l'option XML.

8.13.2. Gestion de l'encodage


Une grande attention doit prvaloir lors de la gestion de plusieurs encodages sur le client, le serveur ou dans les donnes XML qui
passent entre eux. Lors de l'utilisation du mode texte pour passer les requtes au serveur et pour renvoyer les rsultats au client
(qui se trouve dans le mode normal), PostgreSQL convertit toutes les donnes de type caractre passes entre le client et le serveur
et vice-versa suivant l'encodage spcifique du bout final ; voir la Section 22.3, Support des jeux de caractres . Ceci inclut les
reprsentations textuelles des valeurs XML, comme dans les exemples ci-dessus. Ceci signifie que les dclarations d'encodage
contenues dans les donnes XML pourraient devenir invalide lorsque les donnes sont converties vers un autre encodage lors du
transfert entre le client et le serveur, alors que la dclaration de l'encodage n'est pas modifie. Pour s'en sortir, une dclaration
d'encodage contenue dans une chane de caractres prsente en entre du type xml est ignore, et le contenu est toujours suppos
tre de l'encodage du serveur. En consquence, pour un traitement correct, ces chanes de caractres de donnes XML doivent tre
envoyes du client dans le bon encodage. C'est de la responsabilit du client de soit convertir le document avec le bon encodage
client avant de l'envoyer au serveur soit d'ajuster l'encodage client de faon approprie. En sortie, les valeurs du type xml n'auront
pas une dclaration d'encodage et les clients devront supposer que les donnes sont dans l'encodage du client.
Lors de l'utilisation du mode binaire pour le passage des paramtres de la requte au serveur et des rsultats au client, aucune
conversion de jeu de caractres n'est ralise, donc la situation est diffrente. Dans ce cas, une dclaration d'encodage dans les
donnes XML sera observe et, si elle est absente, les donnes seront supposes tre en UTF-8 (comme requis par le standard
XML ; notez que PostgreSQL ne supporte pas du tout UTF-16). En sortie, les donnes auront une dclaration d'encodage spcifiant l'encodage client sauf si l'encodage client est UTF-8, auquel case elle sera omise.
Le traitement des donnes XML avec PostgreSQL sera moins complexe et plus efficace si l'encodage des donnes, l'encodage
client et serveur sont identiques. Comme les donnes XML sont traites en interne en UTF-8, les traitements seront plus efficaces
si l'encodage serveur est aussi en UTF-8.

Attention
Certaines fonctions relatives XML pourraient ne pas fonctionner du tout sur des donnes non ASCII quand
l'encodage du serveur n'est pas UTF-8. C'est un problme connu pour xpath() en particulier.

8.13.3. Accder aux valeurs XML


Le type de donnes xml est inhabituel dans le sens o il ne dispose pas d'oprateurs de comparaison. Ceci est d au fait qu'il
n'existe pas d'algorithme de comparaison bien dfini et utile pour des donnes XML. Une consquence de ceci est que vous ne
pouvez pas rcuprer des lignes en comparant une colonne xml avec une valeur de recherche. Les valeurs XML doivent du coup
tre typiquement accompagnes par un champ cl spar comme un identifiant. Une autre solution pour la comparaison de valeurs
XML est de les convertir en des chanes de caractres, mais notez que la comparaison de chanes n'a que peu voir avec une mthode de comparaison XML utile.
Comme il n'y a pas d'oprateurs de comparaison pour le type de donnes xml, il n'est pas possible de crer un index directement
sur une colonne de ce type. Si une recherche rapide est souhaite dans des donnes XML, il est toujours possible de convertir
l'expression en une chane de caractres et d'indexer cette conversion. Il est aussi possible d'indexer une expression XPath. La
vraie requte devra bien sr tre ajuste une recherche sur l'expression indexe.
La fonctionnalit de recherche plein texte peut aussi tre utilise pour acclrer les recherches dans des donnes XML. Le support
du pr-traitement ncessaire n'est cependant pas disponible dans la distribution PostgreSQL.

8.14. Tableaux
PostgreSQL permet de dfinir des colonnes de table comme des tableaux multidimensionnels de longueur variable. Il est possible de crer des tableaux de n'importe quel type utilisateur : de base, compos, enum. Toutefois, les tableaux de domaines ne
sont pas encore supports.

8.14.1. Dclaration des types tableaux


La cration de la table suivante permet d'illustrer l'utilisation des types tableaux :
CREATE TABLE sal_emp
nom
paye_par_semaine
planning
);

(
text,
integer[],
text[][]
107

Types de donnes

Comme indiqu ci-dessus, un type de donnes tableau est nomm en ajoutant des crochets ([]) au type de donnes des lments
du tableau. La commande ci-dessus cre une table nomme sal_emp avec une colonne de type text (nom), un tableau une dimension de type integer (paye_par_semaine), reprsentant le salaire d'un employ par semaine et un tableau deux dimensions
de type text (planning), reprsentant le planning hebdomadaire de l'employ.
La syntaxe de CREATE TABLE permet de prciser la taille exacte des tableaux, par exemple :
CREATE TABLE tictactoe (
carres
integer[3][3]
);
Nanmoins, l'implantation actuelle ignore toute limite fournie pour la taille du tableau, c'est--dire que le comportement est identique celui des tableaux dont la longueur n'est pas prcise.
De plus, l'implantation actuelle n'oblige pas non plus dclarer le nombre de dimensions. Les tableaux d'un type d'lment particulier sont tous considrs comme tant du mme type, quels que soient leur taille ou le nombre de dimensions. Dclarer la taille
du tableau ou le nombre de dimensions dans CREATE TABLE n'a qu'un but documentaire. Le comportement de l'application
n'en est pas affect.
Une autre syntaxe, conforme au standard SQL via l'utilisation du mot cl ARRAY, peut tre employe pour les tableaux une dimension. paye_par_semaine peut tre dfini ainsi :
paye_par_semaine

integer ARRAY[4],

ou si aucune taille du tableau n'est spcifie :


paye_par_semaine

integer ARRAY,

Nanmoins, comme indiqu prcdemment, PostgreSQL n'impose aucune restriction sur la taille dans tous les cas.

8.14.2. Saisie de valeurs de type tableau


Pour crire une valeur de type tableau comme une constante littrale, on encadre les valeurs des lments par des accolades et on
les spare par des virgules (ce n'est pas diffrent de la syntaxe C utilise pour initialiser les structures). Des guillemets doubles
peuvent tre positionns autour des valeurs des lments. C'est d'ailleurs obligatoire si elles contiennent des virgules ou des accolades (plus de dtails ci-dessous). Le format gnral d'une constante de type tableau est donc le suivant :
'{ val1 delim val2 delim ... }'
o delim est le caractre de dlimitation pour ce type, tel qu'il est enregistr dans son entre pg_type. Parmi les types de donnes standard fournis par la distribution PostgreSQL, tous utilisent une virgule (,), sauf pour le type box qui utilise un pointvirgule (;). Chaque val est soit une constante du type des lments du tableau soit un sous-tableau.
Exemple de constante tableau :
'{{1,2,3},{4,5,6},{7,8,9}}'
Cette constante a deux dimensions, un tableau 3 par 3 consistant en trois sous-tableaux d'entiers.
Pour initialiser un lment d'un tableau NULL, on crit NULL pour la valeur de cet lment. (Toute variante majuscule et/ou minuscule de NULL est accepte.) Si NULL doit tre utilis comme valeur de chane, on place des guillemets doubles autour.
Ces types de constantes tableau sont en fait un cas particulier des constantes de type gnrique abordes dans la Section 4.1.2.7,
Constantes d'autres types . La constante est traite initialement comme une chane et passe la routine de conversion d'entres
de tableau. Une spcification explicite du type peut tre ncessaire.
Quelques instructions INSERT :
INSERT INTO sal_emp
VALUES ('Bill',
'{10000, 10000, 10000, 10000}',
'{{"rendez-vous", "repas"}, {"entrainement", "prsentation"}}');
INSERT INTO sal_emp
VALUES ('Carol',
'{20000, 25000, 25000, 25000}',
'{{"petit-djeuner", "consultation"}, {"rendez-vous", "repas"}}');
Le rsultat des deux insertions prcdentes ressemble :
SELECT * FROM sal_emp;
nom
|
paye_par_semaine

planning
108

Types de donnes

-------+---------------------------+-------------------Bill
| {10000,10000,10000,10000} | {{rendez-vous,repas},{entrainement,prsentation}}
Carol | {20000,25000,25000,25000} |
{{petit-djeuner,consultation},{rendez-vous,repas}}
(2 rows)
Les tableaux multi-dimensionnels doivent avoir des chelles correspondantes pour chaque dimension. Une diffrence cause la leve d'une erreur. Par exemple :
INSERT INTO sal_emp
VALUES ('Bill',
'{10000, 10000, 10000, 10000}',
'{{"rendez-vous", "repas"}, {"rendez-vous"}}');
ERROR: multidimensional arrays must have array expressions with matching dimensions
La syntaxe du constructeur ARRAY peut aussi tre utilise :
INSERT INTO sal_emp
VALUES ('Bill',
ARRAY[10000, 10000, 10000, 10000],
ARRAY[['rendez-vous', 'repas'], ['entrainement','prsentation']]);
INSERT INTO sal_emp
VALUES ('Carol',
ARRAY[20000, 25000, 25000, 25000],
ARRAY[['petit-djeuner', 'consultation'], ['rendez-vous', 'repas']]);
Les lments du tableau sont des constantes SQL ordinaires ou des expressions ; par exemple, les chanes de caractres littrales
sont encadres par des guillemets simples au lieu de guillemets doubles comme cela est le cas dans un tableau littral. La syntaxe
du constructeur ARRAY est discute plus en profondeur dans la Section 4.2.12, Constructeurs de tableaux .

8.14.3. Accs aux tableaux


Quelques requtes lances sur la table permettent d'clairer le propos prcdent. Tout d'abord, l'accs un seul lment du tableau.
Cette requte retrouve le nom des employs dont la paye a chang au cours de la deuxime semaine :
SELECT nom FROM sal_emp WHERE paye_par_semaine[1] <> paye_par_semaine[2];
nom
------Carol
(1 row)
Les indices du tableau sont crits entre crochets. Par dfaut, PostgreSQL utilise la convention des indices commenant 1 pour
les tableaux, c'est--dire un tableau n lments commence avec array[1] et finit avec array[n].
Rcuprer la paye de la troisime semaine de tous les employs :
SELECT paye_par_semaine[3] FROM sal_emp;
paye_par_semaine
-----------------10000
25000
(2 rows)
Il est galement possible d'accder des parties rectangulaires arbitraires ou des sous-tableaux. Une partie de tableau est indique par l'criture extrmit basse:extrmit haute sur n'importe quelle dimension. Ainsi, la requte suivante retourne le premier lment du planning de Bill pour les deux premiers jours de la semaine :
SELECT planning[1:2][1:1] FROM sal_emp WHERE nom = 'Bill';
planning
-------------------{{rendez-vous},{entrainement}}
(1 row)
Si l'une des dimensions est crite comme une partie, c'est--dire si elle contient le caractre deux-points, alors toutes les dimensions sont traites comme des parties. Toute dimension qui n'a qu'un numro (pas de deux-points), est traite comme allant de 1 au
109

Types de donnes

nombre indiqu. Par exemple, [2] est traite comme [1:2], comme le montre cet exemple :
SELECT planning[1:2][2] FROM sal_emp WHERE nom = 'Bill';
planning
--------------------------{{rendez-vous,repas},{entrainement,prsentation}}
(1 row)
Pour viter la confusion avec le cas sans indice, il est meilleur d'utiliser la syntaxe avec indice pour toutes les dimensions,
c'est--dire [1:2][1:1] et non pas [2][1:1].
Une expression indice de tableau retourne NULL si le tableau ou une des expressions est NULL. De plus, NULL est renvoy si
un indice se trouve en dehors de la plage du tableau (ce cas n'amne pas d'erreur). Par exemple, si planning a les dimensions
[1:3][1:2], faire rfrence planning[3][3] donne un rsultat NULL. De la mme faon, une rfrence sur un tableau
avec une valeur d'indices incorrecte retourne une valeur NULL plutt qu'une erreur.
Une expression de dcoupage d'un tableau est aussi NULL si, soit le tableau, soit une des expressions indices est NULL. Nanmoins, dans certains cas particuliers comme la slection d'une partie d'un tableau compltement en dehors de la plage de ce dernier, l'expression de cette partie est un tableau vide (zro dimension) et non pas un tableau NULL. (Ceci ne correspond pas au
comportement sans indice, et est fait pour des raisons historiques.) Si la partie demande surcharge partiellement les limites du tableau, alors elle est rduite silencieusement la partie surcharge au lieu de renvoyer NULL.
Les dimensions actuelles de toute valeur de type tableau sont disponibles avec la fonction array_dims :
SELECT array_dims(planning) FROM sal_emp WHERE nom = 'Carol';
array_dims
-----------[1:2][1:2]
(1 row)
array_dims donne un rsultat de type text, ce qui est pratique lire mais peut s'avrer plus difficile interprter par les programmes. Les dimensions sont aussi rcuprables avec array_upper et array_lower, qui renvoient respectivement la limite
haute et et la limite basse du tableau prcis :
SELECT array_upper(planning, 1) FROM sal_emp WHERE nom = 'Carol';
array_upper
------------2
(1 row)
array_length renverra la longueur de la dimension indique pour le tableau :
SELECT array_length(planning, 1) FROM sal_emp WHERE nom = 'Carol';
array_length
-------------2
(1 row)

8.14.4. Modification de tableaux


La valeur d'un tableau peut tre compltement remplace :
UPDATE sal_emp SET paye_par_semaine = '{25000,25000,27000,27000}'
WHERE nom = 'Carol';
ou en utilisant la syntaxe de l'expression ARRAY :
UPDATE sal_emp SET paye_par_semaine = ARRAY[25000,25000,27000,27000]
WHERE nom = 'Carol';
On peut aussi mettre jour un seul lment d'un tableau :
UPDATE sal_emp SET paye_par_semaine[4] = 15000
WHERE nom = 'Bill';
ou faire une mise jour par tranche :
UPDATE sal_emp SET paye_par_semaine[1:2] = '{27000,27000}'
110

Types de donnes

WHERE nom = 'Carol';


Un tableau peut tre agrandi en y stockant des lments qui n'y sont pas dj prsents. Toute position entre ceux dj prsents et
les nouveaux lments est remplie avec la valeur NULL. Par exemple, si le tableau mon_tableau a actuellement quatre lments, il en aura six aprs une mise jour qui affecte mon_tableau[6] car mon_tableau[5] est alors rempli avec une valeur NULL. Actuellement, l'agrandissement de cette faon n'est autoris que pour les tableaux une dimension, pas pour les tableaux multidimensionnels.
L'affectation par parties d'un tableau permet la cration de tableaux dont l'indice de dpart n'est pas 1. On peut ainsi affecter, par
exemple, mon_tableau[-2:7] pour crer un tableau avec des valeurs d'indices allant de -2 7.
Les valeurs de nouveaux tableaux peuvent aussi tre construites en utilisant l'oprateur de concatnation, || :
SELECT ARRAY[1,2] || ARRAY[3,4];
?column?
--------------{1,2,3,4}
(1 row)
SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]];
?column?
--------------------{{5,6},{1,2},{3,4}}
(1 row)
L'oprateur de concatnation autorise un lment tre plac au dbut ou la fin d'un tableau une dimension. Il accepte aussi
deux tableaux N dimensions, ou un tableau N dimensions et un N+1 dimensions.
Quand un lment seul est pouss soit au dbut soit la fin d'un tableau une dimension, le rsultat est un tableau avec le mme
indice bas que l'oprande du tableau. Par exemple :
SELECT array_dims(1 || '[0:1]={2,3}'::int[]);
array_dims
-----------[0:2]
(1 row)
SELECT array_dims(ARRAY[1,2] || 3);
array_dims
-----------[1:3]
(1 row)
Lorsque deux tableaux ayant un mme nombre de dimensions sont concatns, le rsultat conserve la limite infrieure de
l'oprande gauche. Le rsultat est un tableau comprenant chaque lment de l'oprande gauche suivi de chaque lment de
l'oprande droit. Par exemple :
SELECT array_dims(ARRAY[1,2] || ARRAY[3,4,5]);
array_dims
-----------[1:5]
(1 row)
SELECT array_dims(ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]);
array_dims
-----------[1:5][1:2]
(1 row)
Lorsqu'un tableau N dimensions est plac au dbut ou la fin d'un tableau N+1 dimensions, le rsultat est analogue au cas cidessus. Chaque sous-tableau de dimension N est en quelque sorte un lment de la dimension externe d'un tableau N+1 dimensions. Par exemple :
SELECT array_dims(ARRAY[1,2] || ARRAY[[3,4],[5,6]]);
array_dims
-----------[1:3][1:2]
(1 row)

111

Types de donnes

Un tableau peut aussi tre construit en utilisant les fonctions array_prepend, array_append ou array_cat. Les deux
premires ne supportent que les tableaux une dimension alors que array_cat supporte les tableaux multidimensionnels.
L'oprateur de concatnation vu plus haut est prfrable l'utilisation directe de ces fonctions. En fait, les fonctions existent principalement pour l'implantation de l'oprateur de concatnation. Nanmoins, elles peuvent tre directement utiles dans la cration
d'agrgats utilisateur. Quelques exemples :
SELECT array_prepend(1, ARRAY[2,3]);
array_prepend
--------------{1,2,3}
(1 row)
SELECT array_append(ARRAY[1,2], 3);
array_append
-------------{1,2,3}
(1 row)
SELECT array_cat(ARRAY[1,2], ARRAY[3,4]);
array_cat
--------------{1,2,3,4}
(1 row)
SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[5,6]);
array_cat
--------------------{{1,2},{3,4},{5,6}}
(1 row)
SELECT array_cat(ARRAY[5,6], ARRAY[[1,2],[3,4]]);
array_cat
--------------------{{5,6},{1,2},{3,4}}

8.14.5. Recherche dans les tableaux


Pour rechercher une valeur dans un tableau, il faut vrifier chaque valeur dans le tableau. Ceci peut se faire la main lorque la
taille du tableau est connue. Par exemple :
SELECT * FROM sal_emp WHERE paye_par_semaine[1]
paye_par_semaine[2]
paye_par_semaine[3]
paye_par_semaine[4]

=
=
=
=

10000 OR
10000 OR
10000 OR
10000;

Ceci devient toutefois rapidement fastidieux pour les gros tableaux et n'est pas trs utile si la taille du tableau n'est pas connue.
Une autre mthode est dcrite dans la Section 9.21, Comparaisons de lignes et de tableaux . La requte ci-dessus est remplaable par :
SELECT * FROM sal_emp WHERE 10000 = ANY (paye_par_semaine);
De la mme faon, on trouve les lignes o le tableau n'a que des valeurs gales 10000 avec :
SELECT * FROM sal_emp WHERE 10000 = ALL (paye_par_semaine);
Sinon, la fonction generate_subscripts peut tre utilise. Par exemple :
SELECT * FROM
(SELECT paye_par_semaine,
generate_subscripts(paye_par_semaine, 1) AS s
FROM sal_emp) AS foo
WHERE paye_par_semaine[s] = 10000;
Cette fonction est dcrite dans Tableau 9.46, Fonctions de gnration d'indices .

Astuce
Les tableaux ne sont pas des ensembles ; rechercher des lments spcifiques dans un tableau peut tre un signe
112

Types de donnes

d'une mauvaise conception de la base de donnes. On utilise plutt une table spare avec une ligne pour chaque
lment faisant parti du tableau. Cela simplifie la recherche et fonctionne mieux dans le cas d'un grand nombre
d'lments.

8.14.6. Syntaxe d'entre et de sortie des tableaux


La reprsentation externe du type texte d'une valeur de type tableau consiste en des lments interprts suivant les rgles de
conversion d'entres/sorties pour le type de l'lment du tableau, plus des dcorations indiquant la structure du tableau. L'affichage
est constitu d'accolades ({ et }) autour des valeurs du tableau et de caractres de dlimitation entre lments adjacents. Le caractre dlimiteur est habituellement une virgule (,) mais peut diffrer : il est dtermin par le paramtre typdelim du type de
l'lment tableau. Parmi les types de donnes standard supports par l'implantation de PostgreSQL, seul le type box utilise un
point-virgule (;), tous les autres utilisant la virgule. Dans un tableau multidimensionnel, chaque dimension (row, plane, cube, etc.)
utilise son propre niveau d'accolades et les dlimiteurs doivent tre utiliss entre des entits adjacentes au sein d'accolades de
mme niveau.
La routine de sortie du tableau place des guillemets doubles autour des valeurs des lments si ce sont des chanes vides, si elles
contiennent des accolades, des caractres dlimiteurs, des guillemets doubles, des antislashs ou des espaces ou si elles correspondent NULL. Les guillemets doubles et les antislashs intgrs aux valeurs des lments sont chapps l'aide d'un antislash.
Pour les types de donnes numriques, on peut supposer sans risque que les doubles guillemets n'apparaissent jamais, mais pour
les types de donnes texte, il faut tre prpar grer la prsence et l'absence de guillemets.
Par dfaut, la valeur de la limite basse d'un tableau est initialise 1. Pour reprsenter des tableaux avec des limites basses diffrentes, les indices du tableau doivent tre indiqus explicitement avant d'crire le contenu du tableau. Cet affichage est consititu
de crochets ([]) autour de chaque limite basse et haute d'une dimension avec un dlimiteur deux-points (:) entre les deux.
L'affichage des dimensions du tableau est suivie par un signe d'galit (=). Par exemple :
SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss;
e1 | e2
----+---1 | 6
(1 row)
La routine de sortie du tableau inclut les dimensions explicites dans le resultat uniquement lorsqu'au moins une limite basse est
diffrente de 1.
Si la valeur crite pour un lment est NULL (toute variante), l'lment est considr NULL. La prsence de guillemets ou
d'antislashs dsactive ce fonctionnement et autorise la saisie de la valeur litrale de la chane NULL . De plus, pour une compatibilit ascendante avec les versions antrieures la version 8.2 de PostgreSQL, le paramtre de configuration array_nulls doit
tre dsactiv (off) pour supprimer la reconnaissance de NULL comme un NULL.
Comme indiqu prcdemment, lors de l'criture d'une valeur de tableau, des guillemets doubles peuvent tre utiliss autour de
chaque lment individuel du tableau. Il faut le faire si leur absence autour d'un lment induit en erreur l'analyseur de tableau. Par
exemple, les lments contenant des crochets, virgules (ou tout type de donnes pour le caractre dlimiteur correspondant),
guillemets doubles, antislashs ou espace (en dbut comme en fin) doivent avoir des guillemets doubles. Les chanes vides et les
chanes NULL doivent aussi tre entre guillemets. Pour placer un guillemet double ou un antislash dans une valeur d'lment d'un
tableau, on utilise la syntaxe d'chappement des chanes en le prcdant d'un antislash. Alternativement, il est possible de se passer
de guillemets et d'utiliser l'chappement par antislash pour protger tous les caractres de donnes qui seraient autrement interprts en tant que caractres de syntaxe de tableau.
Des espaces peuvent tre ajoutes avant un crochet gauche ou aprs un crochet droit. Comme avant tout lment individuel. Dans
tous ces cas-l, les espaces sont ignores. En revanche, les espaces l'intrieur des lments entre guillemets doubles ou entoures
de caractres autres que des espaces ne sont pas ignores.

Note
Toute ce qui est crit dans une commande SQL est d'abord interprt en tant que chane littrale puis en tant que tableau. Ceci double le nombre d'antislash ncessaire. Par exemple, pour insrer une valeur de tableau de type text
contenant un antislash et un guillemet double, il faut crire :
INSERT ... VALUES (E'{"\\\\","\\""}');
Le processeur de la chane d'chappement supprime un niveau d'antislash, donc l'analyseur de tableau reoit
{"\\","\""}. En consquence, les chanes remplissant l'entre du type de donnes text deviennent respective113

Types de donnes

ment \ et ". (Si la routine d'entre du type de donnes utilis traite aussi les antislash de manire spciale, bytea
par exemple, il peut tre ncessaire d'avoir jusqu' huit antislash dans la commande pour en obtenir un dans
l'lment stock.) Les guillemets dollar (voir Section 4.1.2.4, Constantes de chanes avec guillemet dollar )
peuvent tre utiliss pour viter de doubler les antislash.

Astuce
La syntaxe du constructeur ARRAY (voir Section 4.2.12, Constructeurs de tableaux ) est souvent plus facile
utiliser que la syntaxe de tableau littral lors de l'criture des valeurs du tableau en commandes SQL. Avec ARRAY,
les valeurs de l'lment individuel sont crites comme elles le seraient si elles ne faisaient pas partie d'un tableau.

8.15. Types composites


Un type composite reprsente la structure d'une ligne ou d'un enregistrement ; il est en essence une simple liste de noms de champs
et de leur types de donnes. PostgreSQL autorise l'utilisation de types composite identiques de plusieurs faons l'utilisation
des types simples. Par exemple, une colonne d'une table peut tre dclare comme tant de type composite.

8.15.1. Dclaration de types composite


Voici deux exemples simples de dfinition de types composite :
CREATE TYPE complexe AS (
r
double precision,
i
double precision
);
CREATE TYPE element_inventaire AS (
nom
text,
id_fournisseur integer,
prix
numeric
);
La syntaxe est comparable CREATE TABLE sauf que seuls les noms de champs et leur types peuvent tre spcifis ; aucune
contrainte (telle que NOT NULL) ne peut tre inclus actuellement. Notez que le mot cl AS est essentiel ; sans lui, le systme penserait un autre genre de commande CREATE TYPE et vous obtiendriez d'tranges erreurs de syntaxe.
Aprs avoir dfini les types, nous pouvons les utiliser pour crer des tables :
CREATE TABLE disponible (
element
element_inventaire,
nombre
integer
);
INSERT INTO disponible VALUES (ROW('fuzzy dice', 42, 1.99), 1000);
ou des fonctions :
CREATE FUNCTION prix_extension(element_inventaire, integer) RETURNS numeric
AS 'SELECT $1.prix * $2' LANGUAGE SQL;
SELECT prix_extension(element, 10) FROM disponible;
Quand vous crez une table, un type composite est automatiquement cr, avec le mme nom que la table, pour reprsenter le type
de ligne de la table. Par exemple, si nous avions dit :
CREATE TABLE element_inventaire (
nom
text,
id_fournisseur integer REFERENCES fournisseur,
prix
numeric CHECK (prix > 0)
);
alors le mme type composite element_inventaire montr ci-dessus aurait t cr et pourrait tre utilis comme ci-dessus.
Nanmoins, notez une restriction importante de l'implmentation actuelle : comme aucune contrainte n'est associe avec un type
composite, les contraintes indiques dans la dfinition de la table ne sont pas appliques aux valeurs du type composite en dehors
de la table. (Un contournement partiel est d'utiliser les types de domaine comme membres de types composites.)

8.15.2. Entre d'une valeur composite


114

Types de donnes

Pour crire une valeur composite comme une constante littrale, englobez les valeurs du champ dans des parenthses et sparezles par des virgules. Vous pouvez placer des guillemets doubles autour de chaque valeur de champ et vous devez le faire si elle
contient des virgules ou des parenthses (plus de dtails ci-dessous). Donc, le format gnral d'une constante composite est le suivant :
'( val1 , val2 , ... )'
Voici un exemple :
'("fuzzy dice",42,1.99)'
qui serait une valeur valide du type element_inventaire dfini ci-dessus. Pour rendre un champ NULL, n'crivez aucun caractre dans sa position dans la liste. Par exemple, cette constante spcifie un troisime champ NULL :
'("fuzzy dice",42,)'
Si vous voulez un champ vide au lieu d'une valeur NULL, saisissez deux guillemets :
'("",42,)'
Ici, le premier champ est une chane vide non NULL alors que le troisime est NULL.
(Ces constantes sont rellement seulement un cas spcial de constantes gnriques de type discutes dans la Section 4.1.2.7,
Constantes d'autres types . La constante est initialement traite comme une chane et passe la routine de conversion de
l'entre de type composite. Une spcification explicite de type pourrait tre ncessaire.)
La syntaxe d'expression ROW pourrait aussi tre utilise pour construire des valeurs composites. Dans la plupart des cas, ceci est
considrablement plus simple utiliser que la syntaxe de chane littrale car vous n'avez pas vous inquiter des multiples
couches de guillemets. Nous avons dj utilis cette mthode ci-dessus :
ROW('fuzzy dice', 42, 1.99)
ROW('', 42, NULL)
Le mot cl ROW est optionnel si vous avez plus d'un champ dans l'expression, donc ceci peut tre simplifi avec
('fuzzy dice', 42, 1.99)
('', 42, NULL)
La syntaxe de l'expression ROW est discute avec plus de dtails dans la Section 4.2.13, Constructeurs de lignes .

8.15.3. Accder aux types composite


Pour accder un champ d'une colonne composite, vous pouvez crire un point et le nom du champ, un peu comme la slection
d'un champ partir d'un nom de table. En fait, c'est tellement similaire que vous pouvez souvent utiliser des parenthses pour viter une confusion de l'analyseur. Par exemple, vous pouvez essayer de slectionner des sous-champs partir de notre exemple de
table, disponible, avec quelque chose comme :
SELECT element.nom FROM disponible WHERE element.prix > 9.99;
Ceci ne fonctionnera pas car le nom element est pris pour le nom d'une table, et non pas d'une colonne de disponible, suivant les rgles de la syntaxe SQL. Vous devez l'crire ainsi :
SELECT (element).nom FROM disponible WHERE (element).prix > 9.99;
ou si vous avez aussi besoin d'utiliser le nom de la table (par exemple dans une requte multi-table), de cette faon :
SELECT (disponible.element).nom FROM disponible WHERE (disponible.element).prix > 9.99;
Maintenant, l'objet entre parenthses est correctement interprt comme une rfrence la colonne element, puis le sous-champ
peut tre slectionn partir de lui.
Des problmes syntaxiques similaires s'appliquent quand vous slectionnez un champ partir d'une valeur composite. En fait,
pour slectionner un seul champ partir du rsultat d'une fonction renvoyant une valeur composite, vous aurez besoin d'crire
quelque chose comme :
SELECT (ma_fonction(...)).champ FROM ...
Sans les parenthses supplmentaires, ceci provoquera une erreur.

8.15.4. Modifier les types composite


Voici quelques exemples de la bonne syntaxe pour insrer et mettre jour des colonnes composites. Tout d'abord pour insrer ou
modifier une colonne entire :
INSERT INTO matab (col_complexe) VALUES((1.1,2.2));
115

Types de donnes

UPDATE matab SET col_complexe = ROW(1.1,2.2) WHERE ...;


Le premier exemple omet ROW, le deuxime l'utilise ; nous pouvons le faire des deux faons.
Nous pouvons mettre jour un sous-champ individuel d'une colonne composite :
UPDATE matab SET col_complexe.r = (col_complexe).r + 1 WHERE ...;
Notez ici que nous n'avons pas besoin de (et, en fait, ne pouvons pas) placer des parenthses autour des noms de colonnes apparaissant juste aprs SET, mais nous avons besoin de parenthses lors de la rfrence la mme colonne dans l'expression droite
du signe d'galit.
Et nous pouvons aussi spcifier des sous-champs comme cibles de la commande INSERT :
INSERT INTO matab (col_complexe.r, col_complexe.i) VALUES(1.1, 2.2);
Si tous les sous-champs d'une colonne ne sont pas spcifis, ils sont remplis avec une valeur NULL.

8.15.5. Syntaxe en entre et sortie d'un type composite


La reprsentation texte externe d'une valeur composite consiste en des lments qui sont interprts suivant les rgles de conversion d'entres/sorties pour les types de champs individuels, plus des dcorations indiquant la structure composite. Cette dcoration
consiste en des parenthses (( et )) autour de la valeur entire ainsi que des virgules (,) entre les lments adjacents. Des espace
blancs en dehors des parenthses sont ignors mais l'intrieur des parenthses, ils sont considrs comme faisant partie de la valeur du champ et pourrait ou non tre significatif suivant les rgles de conversion de l'entre pour le type de donnes du champ.
Par exemple, dans :
'(

42)'

l'espace blanc sera ignor si le type du champ est un entier, mais pas s'il s'agit d'un champ de type texte.
Comme indiqu prcdemment, lors de l'criture d'une valeur composite, vous pouvez utiliser des guillemets doubles autour de
chaque valeur de champ individuel. Vous devez le faire si la valeur du champ pourrait sinon gner l'analyseur de la valeur du
champ composite. En particulier, les champs contenant des parenthses, des virgules, des guillemets doubles ou des antislashs
doivent tre entre guillemets doubles. Pour placer un guillemet double ou un antislash dans la valeur d'un champ composite entre
guillemets, faites-le prcder d'un antislash. (De plus, une paire de guillemets doubles l'intrieur d'une valeur de champ guillemets doubles est pris pour reprsenter un caractre guillemet double, en analogie aux rgles des guillemets simples dans les
chanes SQL littrales.) Autrement, vous pouvez viter les guillemets et utiliser l'chappement par antislash pour protger tous les
caractres de donnes qui auraient t pris pour une syntaxe composite.
Une valeur de champ composite vide (aucun caractre entre les virgules ou parenthses) reprsente une valeur NULL. Pour crire
une valeur qui est une chane vide plutt qu'une valeur NULL, crivez "".
La routine de sortie composite placera des guillemets doubles autour des valeurs de champs s'ils sont des chanes vides ou s'ils
contiennent des parenthses, virgules, guillemets doubles, antislash ou espaces blancs. (Faire ainsi pour les espaces blancs n'est
pas essentiel mais aide la lecture.) Les guillemets doubles et antislashs dans les valeurs des champs seront doubls.

Note
Rappelez-vous que ce que vous allez saisir dans une commande SQL sera tout d'abord interprt comme une chane
littrale, puis comme un composite. Ceci double le nombre d'antislash dont vous avez besoin (en supposant que la
syntaxe d'chappement des chanes est utilise). Par exemple, pour insrer un champ text contenant un guillemet
double et un antislash dans une valeur composite, vous devez crire :
INSERT ... VALUES (E'("\\"\\\\")');
Le processeur des chanes littrales supprime un niveau d'antislash de faon ce qui arrive l'analyseur de valeurs
composites ressemble ("\"\\"). son tour, la chane remplie par la routine d'entre du type de donnes text
devient "\. (Si nous tions en train de travailler avec un type de donnes dont la routine d'entre traite aussi les antislashs spcialement, bytea par exemple, nous pourrions avoir besoin d'au plus huit antislashs dans la commande
pour obtenir un antislash dans le champ composite stock.) Le guillemet dollar (voir Section 4.1.2.4, Constantes
de chanes avec guillemet dollar ) pourrait tre utilis pour viter le besoin des antislashs doubls.

Astuce
La syntaxe du constructeur ROW est habituellement plus simple utiliser que la syntaxe du littrale composite lors
de l'criture de valeurs composites dans des commandes SQL. Dans ROW, les valeurs individuelles d'un champ sont
116

Types de donnes

crits de la mme faon qu'ils l'auraient t en tant pas membres du composite.

8.16. Types identifiant d'objet


Les identifiants d'objets (OID) sont utiliss en interne par PostgreSQL comme cls primaires de diffrentes tables systme. Les
OID ne sont pas ajouts aux tables utilisateur moins que WITH OIDS ne soit indiqu lors de la cration de la table ou que la variable de configuration default_with_oids ne soit active. Le type oid reprsente un identifiant d'objet. Il existe galement diffrents types alias du type oid : regproc, regprocedure, regoper, regoperator, regclass, regtype, regconfig et regdictionary. Le Tableau 8.23, Types identifiant d'objet en donne un aperu.
Le type oid est ce jour un entier non-sign sur quatre octets. Il n'est, de ce fait, pas suffisamment large pour garantir l'unicit au
sein d'une base de donnes volumineuse, voire mme au sein d'une trs grosse table. Il est donc dconseill d'utiliser une colonne
OID comme cl primaire d'une table utilisateur. Les OID sont avant-tout destins stocker des rfrences vers les tables systme.
Le type oid lui-mme dispose de peu d'oprations en dehors de la comparaison. Il peut toutefois tre converti en entier (integer) et
manipul par les oprateurs habituels des entiers (attention aux possibles confusions entre les entiers signs et non signs dans ce
cas).
Les types alias d'OID ne disposent pas d'oprations propres l'exception des routines spcialises de saisie et d'affichage. Ces routines acceptent et affichent les noms symboliques des objets systmes, plutt que la valeur numrique brute que le type oid utilise.
Les types alias permettent de simplifier la recherche des valeurs OID des objets. Par exemple, pour examiner les lignes
pg_attribute en relation avec une table ma_table, on peut crire :
SELECT * FROM pg_attribute WHERE attrelid = 'ma_table'::regclass;
plutt que :
SELECT * FROM pg_attribute
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'ma_table');
Bien que cela semble une bonne solution, c'est un peu trop simplifi. Un sous-select bien plus compliqu peut tre ncessaire pour
slectionner le bon OID s'il existe plusieurs tables nommes ma_table dans diffrents schmas. Le convertisseur de saisie regclass gre la recherche de la table en fonction du paramtrage du parcours des schmas et effectue donc la bonne recherche automatiquement. De faon similaire, la conversion d'un OID de table en regclass pour l'affichage d'un OID numrique est aise.
Tableau 8.23. Types identifiant d'objet

Nom

Rfrence

Description

Exemple

oid

tous

identifiant d'objet numrique

564182

regproc

pg_proc

nom de fonction

sum

regprocedure

pg_proc

fonction avec types d'arguments

sum(int4)

regoper

pg_operator

nom d'oprateur

regoperator

pg_operator

oprateur avec types d'arguments

*(integer,integer)
(NONE,integer)

regclass

pg_class

nom de relation

pg_type

regtype

pg_type

nom de type de donnes

integer

regconfig

pg_ts_config

configuration de la recherche plein texte english

regdictionary

pg_ts_dict

dictionnaire de la recherche plein texte

ou

simple

Tous les types alias d'OID acceptent des noms qualifis par le schma, et affichent des noms prfixs par un schma si l'objet ne
peut tre trouv dans le chemin de recherche courant sans tre qualifi. Les types alias regproc et regoper n'acceptent que des
noms uniques en entre (sans surcharge), si bien qu'ils sont d'un usage limit ; dans la plupart des cas, regprocedure et regoperator
sont plus appropris. Pour regoperator, les oprateurs unaires sont identifis en crivant NONE pour les oprandes non utiliss.
Une proprit supplmentaire des types alias d'OID est la cration de dpendances. Si une constante d'un de ces types apparat
dans une expression stocke (telle que l'expression par dfaut d'une colonne ou une vue), elle cre une dpendance sur l'objet rfrenc. Par exemple, si une colonne a une expression par dfaut nextval('ma_seq'::regclass), PostgreSQL comprend
que l'expression par dfaut dpend de la squence ma_seq ; le systme ne permet alors pas la suppression de la squence si
l'expression par dfaut n'est pas elle-mme supprime au pralable.
Un autre type d'identifiant utilis par le systme est xid, ou identifiant de transaction (abrge xact). C'est le type de donnes des
colonnes systme xmin et xmax. Les identifiants de transactions sont stocks sur 32 bits.
117

Types de donnes

Un troisime type d'identifiant utilis par le systme est cid, ou identifiant de commande. C'est le type de donnes des colonnes
systmes cmin et cmax. Les identifiants de commandes sont aussi stocks sur 32 bits.
Le dernier type d'identifiant utilis par le systme est tid, ou identifiant de ligne (tuple). C'est le type de donnes des colonnes systme ctid. Un identifiant de tuple est une paire (numro de bloc, index de tuple dans le bloc) qui identifie l'emplacement physique de la ligne dans sa table.
Les colonnes systmes sont expliques plus en dtail dans la Section 5.4, Colonnes systme .

8.17. Pseudo-Types
Le systme de types de PostgreSQL contient un certain nombre de types usage spcial qui sont collectivement appels des
pseudo-types. Un pseudo-type ne peut tre utilis comme type d'une colonne de table, mais peut l'tre pour dclarer un argument
de fonction ou un type de rsultat. Tous les pseudo-types disponibles sont utiles dans des situations o une fonction ne se contente
pas d'accepter et retourner des valeurs d'un type de donnes SQL particulier. Le Tableau 8.24, Pseudo-Types liste les diffrents
pseudo-types.
Tableau 8.24. Pseudo-Types

Nom

Description

any

Indique qu'une fonction accepte tout type de donnes, quel qu'il soit.

anyarray

Indique qu'une fonction accepte tout type tableau (voir la Section 35.2.5, Types et fonctions
polymorphes ).

anyelement

Indique qu'une fonction accepte tout type de donnes (voir la Section 35.2.5, Types et fonctions polymorphes ).

anyenum

Indique que la fonction accepte tout type de donnes enum (voir Section 35.2.5, Types et fonctions polymorphes et Section 8.7, Types numration ).

anynonarray

Indique que la fonction accepte tout type de donnes non-array (voir Section 35.2.5, Types et fonctions polymorphes ).

cstring

Indique qu'une fonction accepte ou retourne une chane de caractres C (termine par un NULL).

internal

Indique qu'une fonction accepte ou retourne un type de donnes interne du serveur de bases de donnes.

language_handler Une fonction d'appel de langage procdural est dclare retourner un language_handler.
fdw_handler

Une fonction de gestion pour le wrapper de donnes distantes est dclare retourner un fdw_handler.

record

Identifie une fonction qui retourne un type de ligne non spcifi.

trigger

Une fonction dclencheur est dclare comme retournant un type trigger.

void

Indique qu'une fonction ne retourne aucune valeur.

opaque

Un type de donnes obsolte qui servait prcdemment tous les usages cits ci-dessus.

Les fonctions codes en C (incluses ou charges dynamiquement) peuvent tre dclares comme acceptant ou retournant tout
pseudo-type. Il est de la responsabilit de l'auteur de la fonction de s'assurer du bon comportement de la fonction lorsqu'un pseudo-type est utilis comme type d'argument.
Les fonctions codes en langage procdural ne peuvent utiliser les pseudo-types que dans les limites imposes par l'implantation
du langage. ce jour, tous les langages procduraux interdisent l'usage d'un pseudo-type comme argument et n'autorisent que
void et record comme type de retours (plus trigger lorsque la fonction est utilise comme dclencheur). Certains supportent galement les fonctions polymorphes qui utilisent les types anyarray, anyelement, anyenum, anynonarray.
Le pseudo-type internal sert dclarer des fonctions qui ne sont appeles que par le systme en interne, et non pas directement par
une requte SQL. Si une fonction accepte au minimum un argument de type internal, alors elle ne peut tre appele depuis SQL.
Pour prserver la scurit du type de cette restriction, il est important de suivre la rgle de codage suivante : ne jamais crer de
fonction qui retourne un internal si elle n'accepte pas au moins un argument de type internal.

118

Chapitre 9. Fonctions et oprateurs


PostgreSQL fournit un grand nombre de fonctions et d'oprateurs pour les types de donnes intgrs. Les utilisateurs peuvent
aussi dfinir leurs propres fonctions et oprateurs comme dcrit dans la Partie V, Programmation serveur .
Les commandes \df et \do de psql sont utilises pour afficher respectivement la liste des fonctions et des oprateurs.
Du point de vue de la portabilit, il faut savoir que la plupart des fonctions et oprateurs dcrits dans ce chapitre, l'exception
des oprateurs arithmtiques et logiques les plus triviaux et de quelques fonctions spcifiquement indiques, ne font pas partie
du standard SQL. Quelques fonctionnalits tendues sont prsentes dans d'autres systmes de gestion de bases de donnes SQL
et dans la plupart des cas, ces fonctionnalits sont compatibles et cohrentes de nombreuses implantations. Ce chapitre n'est
pas exhaustif ; des fonctions supplmentaires apparaissent dans les sections adquates du manuel.

9.1. Oprateurs logiques


Oprateurs logiques habituels :
AND
OR
NOT
SQL utilise une logique boolenne trois valeurs avec true, false et null qui reprsente unknown (inconnu). Les tables de
vrit considrer sont les suivantes :
a

a AND b

a OR b

TRUE

TRUE

TRUE

TRUE

TRUE

FALSE

FALSE

TRUE

TRUE

NULL

NULL

TRUE

FALSE

FALSE

FALSE

FALSE

FALSE

NULL

FALSE

NULL

NULL

NULL

NULL

NULL

NOT a

TRUE

FALSE

FALSE

TRUE

NULL

NULL

Les oprateurs AND et OR sont commutatifs, la permutation des oprandes gauche et droit n'affecte pas le rsultat. Voir la Section 4.2.14, Rgles d'valuation des expressions pour plus d'informations sur l'ordre d'valuation des sous-expressions.

9.2. Oprateurs de comparaison


Les oprateurs de comparaison habituels sont disponibles, comme l'indique le Tableau 9.1, Oprateurs de comparaison .
Tableau 9.1. Oprateurs de comparaison

Oprateur

Description

<

infrieur

>

suprieur

<=

infrieur ou gal

>=

suprieur ou gal

gal

<> ou !=

diffrent de

119

Fonctions et oprateurs

Note
L'oprateur != est converti en <> au moment de l'analyse. Il n'est pas possible d'implanter des oprateurs != et <>
ralisant des oprations diffrentes.
Les oprateurs de comparaison sont disponibles pour tous les types de donnes pour lesquels cela a du sens. Tous les oprateurs de
comparaison sont des oprateurs binaires renvoyant des valeurs du type boolean ; des expressions comme 1 < 2 < 3 ne sont
pas valides (car il n'existe pas d'oprateur < de comparaison d'une valeur boolenne avec 3).
En plus des oprateurs de comparaison, on trouve la construction spciale BETWEEN.
a BETWEEN x AND y
est quivalent
a >= x AND a <= y
Notez que BETWEEN traite le point final comme inclut dans l'chelle des valeurs. NOT BETWEEN fait la comparaison inverse :
a NOT BETWEEN x AND y
est quivalent
a < x OR a > y
BETWEEN SYMMETRIC est identique BETWEEN sauf qu'il n'est pas ncessaire que l'argument gauche de AND soit plus petit
ou gal l'argument droite. SI ce n'est pas le cas, ces deux arguments sont automatiquement inverss, pour qu'une chelle non
vide soit toujours suppose.
Pour vrifier si une valeur est NULL ou non, on utilise les constructions
expression IS NULL
expression IS NOT NULL
ou la construction quivalente, non standard,
expression ISNULL
expression NOTNULL
On ne peut pas crire expression = NULL parce que NULL n'est pas gal NULL. (La valeur NULL reprsente une valeur inconnue et il est impossible de dire si deux valeurs inconnues sont gales.) Ce comportement est conforme au standard SQL.

Astuce
Il se peut que des applications s'attendent voir expression = NULL value vrai (true) si expression
s'value comme la valeur NULL. Il est chaudement recommand que ces applications soient modifies pour se
conformer au standard SQL. Nanmoins, si cela n'est pas possible, le paramtre de configuration transform_null_equals peut tre utilis. S'il est activ, PostgreSQL convertit les clauses x = NULL en x IS NULL.

Note
Si l'expression est une valeur de ligne, alors IS NULL est vrai quand l'expression mme de la ligne est NULL
ou quand tous les champs de la ligne sont NULL alors que IS NOT NULL est vrai quand l'expression mme de la
ligne est non NULL et que tous les champs de la ligne sont non NULL. cause de ce comportement, IS NULL et
IS NOT NULL ne renvoient pas toujours des rsultats inverss pour les expressions de lignes, c'est--dire une expression de ligne qui contient la fois des valeurs NULL et des valeurs non NULL retournera faux pour les deux
tests. Cette dfinition, conforme au standard SQL, est une modification du comportement incohrent des versions
de PostgreSQL antrieures la 8.2.
L'oprateur standard de comparaison renvoie NULL (ce qui signifie inconnu ) si l'une des entres est NULL, ni true ni false,
c'est--dire 7 = NULL renvoie NULL. Quand ce comportement n'est pas convenable, utilisez la syntaxe IS [NOT] DISTINCT FROM :
expression IS DISTINCT FROM expression
expression IS NOT DISTINCT FROM expression
Pour des entres non NULL, IS DISTINCT FROM est identique l'oprateur <>. Cependant, si les deux entres sont NULL,
alors cela retourne faux et si une des deux entres est NULL, alors cela retourne vrai. De la mme faon, IS NOT DISTINCT
120

Fonctions et oprateurs

FROM est identique = pour les entres non NULL mais il renvoie true si les deux entres sont NULL et false quand une seule est
NULL. Dans ces constructions, NULL n'est plus considr comme un tat inconnu mais comme une valeur.
Les valeurs boolennes peuvent aussi tre testes en utilisant les constructions
expression
expression
expression
expression
expression
expression

IS
IS
IS
IS
IS
IS

TRUE
NOT TRUE
FALSE
NOT FALSE
UNKNOWN
NOT UNKNOWN

Elles retournent toujours true ou false, jamais une valeur NULL, mme si l'oprande est NULL. Une entre NULL est traite
comme la valeur logique inconnue . IS UNKNOWN et IS NOT UNKNOWN sont rellement identiques IS NULL et IS NOT
NULL, respectivement, sauf que l'expression en entre doit tre de type boolen.

9.3. Fonctions et oprateurs mathmatiques


Des oprateurs mathmatiques sont fournis pour un grand nombre de types PostgreSQL. Pour les types sans conventions mathmatiques standards (les types dates/time, par exemple), le comportement rel est dcrit dans les sections appropries.
Le Tableau 9.2, Oprateurs mathmatiques affiche les oprateurs mathmatiques disponibles.
Tableau 9.2. Oprateurs mathmatiques

Oprateur

Description

Exemple

Rsultat

addition

2 + 3

soustraction

2 - 3

-1

multiplication

2 * 3

division (la division entire tronque les rsultats)

4 / 2

modulo (reste)

5 % 4

exposant

2.0 ^ 3.0

|/

racine carre

|/ 25.0

||/

racine cubique

||/ 27.0

factoriel

5 !

120

!!

factoriel (oprateur prfixe)

!! 5

120

valeur absolue

@ -5.0

&

AND bit bit

91 & 15

11

OR bit bit

32 | 3

35

XOR bit bit

17 # 5

20

NOT bit bit

~1

-2

<<

dcalage gauche

1 << 4

16

>>

dcalage droit

8 >> 2

Les oprateurs bit bit ne fonctionnent que sur les types de donnes entiers alors que les autres sont disponibles pour tous les
types de donnes numriques. Les oprateurs bit bit sont aussi disponibles pour les types de chanes de bits bit et bit varying
comme le montre le Tableau 9.10, Oprateurs sur les chanes de bits .
Le Tableau 9.3, Fonctions mathmatiques affiche les fonctions mathmatiques disponibles. Dans ce tableau, dp signifie
double precision. Beaucoup de ces fonctions sont fournies dans de nombreuses formes avec diffrents types d'argument. Sauf prcision contraire, toute forme donne d'une fonction renvoie le mme type de donnes que son argument. Les fonctions utilisant des
donnes de type double precision sont pour la plupart implantes avec la bibliothque C du systme hte ; la prcision et le comportement dans les cas particuliers peuvent varier en fonction du systme hte.
Tableau 9.3. Fonctions mathmatiques

Fonction

Type renvoy

Description

Exemple

Rsultat

abs(x)

(identique l'entre)

valeur absolue

abs(-17.4)

17.4

121

Fonctions et oprateurs

Fonction

Type renvoy

Description

Exemple

Rsultat

cbrt(dp)

dp

racine cubique

cbrt(27.0)

ceil(dp
ou (identique l'argument) plus petit entier suprieur ceil(-42.8)
numeric)
l'argument

-42

ceiling(dp (identique l'argument) plus petit entier suprieur ceiling(-95.3)


ou numeric)
l'argument (alias de ceil)

-95

degrees(dp) dp

radians vers degrs

degrees(0.5)

28.6478897565412

div(y nume- numeric


ric, x numeric)

quotient entier de y/x

div(9,4)

exp(1.0)

2.71828182845905

exp(dp
ou (identique l'argument) exponentiel
numeric)

floor(dp ou (identique l'argument) plus grand entier infrieur floor(-42.8)


numeric)
l'argument

-43

ln(dp
ou (identique l'argument) logarithme
numeric)

ln(2.0)

0.69314718055994
5

log(dp
ou (identique l'argument) logarithme base 10
numeric)

log(100.0)

log(b nume- numeric


ric, x numeric)

log(2.0, 64.0)

6.0000000000

logarithme en base b

mod(y, x)

(identique au type des reste de y/x


arguments)

mod(9,4)

pi()

dp

constante pi

pi()

3.14159265358979

power(a dp, dp
b dp)

a lev la puissance b

power(9.0, 3.0)

729

power(a nu- numeric


meric,
b
numeric)

a lev la puissance b

power(9.0, 3.0)

729

radians(dp) dp

degrs vers radians

radians(45.0)

0.78539816339744
8

random()

dp

valeur au hasard entre 0.0 random()


(compris) et 1.0 (non compris)

round(dp ou (identique l'argument) arrondi l'entier le plus proche


numeric)

round(42.4)

42

round(v nu- numeric


meric,
s
int)

arrondi pour s dcimales

round(42.4382,
2)

42.44

setseed(dp) void

initialise les appels ran- setseed(0.54823)


dom() suivre (valeur entre 1.0 et 1.0, inclusif)

sign(dp
ou (identique l'argument) signe de l'argument (-1, 0, +1)
numeric)

sign(-8.4)

-1

sqrt(dp
ou (identique l'argument) racine carr
numeric)

sqrt(2.0)

1.4142135623731

trunc(dp ou (identique l'argument) tronque vers zro


numeric)

trunc(42.8)

42

trunc(v nu- numeric


meric,
s
int)

tronque sur s dcimales

trunc(42.4382,
2)

42.43

width_bucke int
t(oprande
numeric, b1
numeric, b2

renvoie le compartiment auquel width_bucket(5.3 3


l'oprande est affect dans un 5, 0.024, 10.06,
histogramme d'quidistance 5)
nombre compartiments, les va122

Fonctions et oprateurs

Fonction

Type renvoy

Description

Exemple

Rsultat

leurs allant de b1 b2

numeric,
nombre int)

Pour finir, le Tableau 9.4, Fonctions trigonomtriques affiche les fonctions trigonomtriques disponibles. Toutes les fonctions
trigonomtriques prennent des arguments et renvoient des valeurs de type double precision. Les arguments des fonctions trigonomtriques sont exprims en radian. Voir les fonctions de transformation d'unit radians() et degrees() ci-dessus.
Tableau 9.4. Fonctions trigonomtriques

Fonction

Description

acos(x)

arccosinus

asin(x)

arcsinus

atan(x)

arctangente

atan2(y, x)

arctangente de y/x

cos(x)

cosinus

cot(x)

cotangente

sin(x)

sinus

tan(x)

tangente

9.4. Fonctions et oprateurs de chanes


Cette section dcrit les fonctions et oprateurs d'examen et de manipulation des valeurs de type chane de caractres. Dans ce
contexte, les chanes incluent les valeurs des types character, character varying et text. Sauf lorsque cela est prcis diffremment,
toutes les fonctions listes ci-dessous fonctionnent sur tous ces types, mais une attention particulire doit tre porte aux effets potentiels du remplissage automatique lors de l'utilisation du type character. Quelques fonctions existent aussi nativement pour le
type chane bit bit.
SQL dfinit quelques fonctions de type chane qui utilisent des mots cls, la place de la virgule, pour sparer les arguments. Des
dtails sont disponibles dans le Tableau 9.5, Fonctions et oprateurs SQL pour le type chane . PostgreSQL fournit aussi des
versions de ces fonctions qui utilisent la syntaxe standard d'appel des fonctions (voir le Tableau 9.6, Autres fonctions de
chane ).

Note
Avant PostgreSQL 8.3, ces fonctions acceptent silencieusement des valeurs de types de donnes diffrents de
chanes de caractres. Cela parce qu'existent des transtypages implicites de ces types en text. Ces forages ont t
supprims parce que leur comportement est souvent surprenant. Nanmoins, l'oprateur de concatnation de chane
(||) accepte toujours des lments qui ne sont pas du type chane de caractres, ds lors qu'au moins un des lments est de type chane, comme montr dans Tableau 9.5, Fonctions et oprateurs SQL pour le type chane .
Dans tous les autres cas, il faut insrer un transtypage explicite en text pour mimer le comportement prcdent.
Tableau 9.5. Fonctions et oprateurs SQL pour le type chane

Fonction

Type
Description
renvoy

Exemple

Rsultat

chane || chane

text

'Post' || 'greSQL'

PostgreSQL

chane
||
autre- text
que-chane ou autreque-chane || chane
bit_length(chane)

int

char_length(chane) ou int
cha
character_length(ne)
lower(chane)

text

Concatnation de chanes

Concatnation de chanes avec 'Value: ' || 42


un argument non-chane

Value: 42

Nombre de bits de la chane

32

bit_length('jose')

Nombre de caractres de la char_length('jose')


chane

Convertit une chane en minus- lower('TOM')

tom

123

Fonctions et oprateurs

Fonction

Type
Description
renvoy

octet_length(chane)

int

Exemple

Rsultat

cule
overlay(chane
pla- text
cing chane from int
[for int])

Nombre d'octets de la chane

octet_length('jose') 4

Remplace la sous-chane

overlay('Txxxxas'
Thomas
placing 'hom' from 2
for 4)

position(sous-chane
in chane)

int

Emplacement de la sous-chane position('om'


indique
'Thomas')

substring(chane
[from int] [for int])

text

Extrait une sous-chane

substring(chane
modele)

from text

in 3

substring('Thomas'
from 2 for 3)

hom

Extrait la sous-chane correspon- substring('Thomas'


dant l'expression rationnelle from '...$')
POSIX. Voir Section 9.7,
Correspondance de motif
pour plus d'informations sur la
correspondance de modles.

mas

substring(chane from text


modele for echappement)

Extrait la sous-chane correspon- substring('Thomas'


oma
dant l'expression rationnelle from '%#"o_a#"_' for
SQL.
Voir
Section
9.7, '#')
Correspondance de motif
pour plus d'informations sur la
correspondance de modles.

trim([leading | trai- text


ling | both] [caractres] from chane)

Supprime la plus grande chane trim(both


qui ne contient que les carac- 'xTomxx')
tres (une espace par dfaut)
partir du dbut, de la fin ou des
deux extrmits (respectivement
leading, trailing, both) de la
chane.

upper(chane)

text

'x'

from Tom

Convertit une chane en majus- upper('tom')


cule

TOM

D'autres fonctions de manipulation de chanes sont disponibles et listes dans le Tableau 9.6, Autres fonctions de chane . Certaines d'entre elles sont utilises en interne pour implanter les fonctions de chane rpondant au standard SQL listes dans le Tableau 9.5, Fonctions et oprateurs SQL pour le type chane .
Tableau 9.6. Autres fonctions de chane

Fonction

Type
Description
renvoy

ascii(chane)

int

btrim(chane text
caracteres text])

chr(int)

[, text

text

Exemple

Rsultat

Code ASCII du premier octet de ascii('x')


l'argument. Pour UTF8, renvoie
le code Unicode du caractre.
Pour les autres codages multioctets, l'argument doit imprativement tre un caractre ASCII.

120

Supprime la chane la plus btrim('xyxtrimyyx',


longue constitue uniquement de 'xy')
caractres issus de caractres (une espace par dfaut)
partir du dbut et de la fin de
chane.

trim

Caractre correspondant au code chr(65)


donn. Pour UTF8, l'argument
est trait comme un code Unicode. Pour les autres codages

124

Fonctions et oprateurs

Fonction

Type
Description
renvoy

Exemple

Rsultat

multi-octets, l'argument doit imprativement dsigner un caractre ASCII. Le caractre NULL


(0) n'est pas autoris car les
types de donnes texte ne
peuvent pas stocker ce type
d'octets.
concat(chane
"any" text
[, chane "any" [,
...] ])

Concatne tous les arguments. concat('abcde',


Les arguments NULL sont igno- NULL, 22)
rs.

concat_ws(sparateur
text
text, chane "any" [,
chane "any" [, ...]
])

Concatne tous les arguments concat_ws(',',


abcde,2,22
avec des sparateurs, sauf le pre- 'abcde',
2,
NULL,
mier utilis comme sparateur. 22)
Les arguments NULL sont ignors.

convert(chane bytea, bytea


encodage_source name,
encodage_destination
name)

Convertit la chane en encodage convert(


encodage_destination. 'texte_en_utf8',
L'encodage d'origine est indiqu 'UTF8', 'LATIN1')
par encodage_source. La
chane doit tre valide pour
cet encodage. Les conversions
peuvent tre dfinies avec
CREATE CONVERSION. De
plus, il existe quelques conversions pr-dfinies. Voir Tableau 9.7, Conversions intgres pour les conversions disponibles.

texte_en_utf8
reprsent dans le
codage LATIN1

convert_from(chane
text
bytea,
encodage_source nom)

Convertit la chane dans convert_from(


l'encodage
de
la
base. 'texte_en_utf8',
L'encodage original est indiqu 'UTF8')
par encodage_source. La
chane doit tre valide pour
cet encodage.

texte_en_utf8
reprsent dans le
codage de la base
en cours

convert_to(chane
bytea
text,
encodage_destination nom)

Convertit une chane en enco- convert_to(


dage
enco- texte', 'UTF8')
dage_destination.

decode(chane
format text)

encode(donnes
format text)

text, bytea

bytea, text

chaine_formata
text
format(ge
text
[,
chane "any" [, ...]
])

2, abcde222

'un un texte reprsent


dans
l'encodage UTF8

Dcode les donnes binaires decode('MTIzAAE=',


partir d'une rpresentation tex- 'base64')
tuelle disponible dans chane,
code pralablement avec encode. Les options disponibles
pour le format sont les mmes
que pour la fonction encode.

\x3132330001

Code les donnes binaires en encode(


une reprsentation textuelle. Les E'123\\000\\001',
formats supports sont : 'base64')
base64, hex, escape. escape convertit les octets nuls et
les octets dont le bit de poids
fort est 1, en squence octal
(\nnn) et des antislashs
doubles.

MTIzAAE=

Formate une chane de carac- format('Hello


tres. Cette fonction est similaire %1$s', 'World')
la fonction C sprintf mais
seules les spcifications de
125

%s, Hello
World

World,

Fonctions et oprateurs

Fonction

Type
Description
renvoy

Exemple

Rsultat

conversions suivantes sont acceptes : %s utilise l'argument


correspondant
comme
une
chane de caractres ; %I ralise
un chappement de son argument en supposant que ce dernier est un identifiant SQL ; %L
ralise un chappement de son
argument en supposant que ce
dernier est un littral SQL ; %%
affiche un % littral. Une
conversion peut rfrencer un
paramtre de position explicite
en prcdant le marqueur de
conversion avec n$, o n est la
position de l'argument. Voir aussi Exemple 39.1, Mettre entre
guillemets des valeurs dans des
requtes dynamiques .
initcap(chane)

left(chane
int)

text,

text

Convertit la premire lettre de initcap('bonjour


chaque mot en majuscule et le THOMAS')
reste en minuscule. Les mots
sont des squences de caractres
alphanumriques spars par des
caractres non alphanumriques.

Bonjour
mas

n text

Renvoie les n premiers carac- left('abcde', 2)


tres dans la chane. Quand n est
ngatif, renvoie tous sauf les n
derniers caractres.

ab

Nombre
chane

de length('jose')

Nombre de caractres de length('jose',


chane dans l'encodage 'UTF8')
donn. La chane doit tre valide dans cet encodage.

Complte chane lon- lpad('hi', 5, 'xy')


gueur en ajoutant les caractres remplissage en dbut
de chane (une espace par dfaut). Si chane a une taille suprieure longueur, alors elle
est tronque (sur la droite).

xyxhi

Supprime la chane la plus ltrim('zzzytrim',


longue constitue uniquement de 'xyz')
caractres issus de caractres (une espace par dfaut)
partir du dbut de la chane.

trim

900150983cd24
fb0
d6963f7d28e17
f72

length(chane)

int

length(chane
encodage nom )

bytea, int

lpad(chane
text, text
longueur int [, remplissage text])

ltrim(chane text
caracteres text])

[, text

de

caractres

md5(chane)

text

Calcule la cl MD5 de chane md5('abc')


et retourne le rsultat en hexadcimal.

pg_client_encoding()

name

Nom de l'encodage client cou- pg_client_encoding() SQL_ASCII


rant.

quote_ident(chane
text)

text

Renvoie la chane correctement quote_ident('Foo


place entre guillemets pour uti- bar')
lisation comme identifiant dans
une chane d'instruction SQL.
126

"Foo bar"

Tho-

Fonctions et oprateurs

Fonction

Type
Description
renvoy

Exemple

Rsultat

Les guillemets ne sont ajouts


que s'ils sont ncessaires
(c'est--dire si la chane contient
des caractres autres que ceux
de l'identifiant ou qu'il peut y
avoir un problme de casse). Les
guillemets compris dans la
chane sont correctement doubls. Voir aussi Exemple 39.1,
Mettre entre guillemets des valeurs dans des requtes dynamiques .
quote_literal(chane
text)

text

Renvoie la chane correctement quote_literal(


place entre guillemets pour tre E'O\'Reilly')
utilise comme libell dans un
chane d'instruction SQL. Les
guillemets simples compris dans
la chane et les antislash sont
correctement doubls. Notez que
quote_literal
renvoie
NULL si son argument est
NULL ; si l'argument peut tre
NULL,
la
fonction
quote_nullable convient
mieux. Voir aussi Exemple 39.1,
Mettre entre guillemets des valeurs dans des requtes dynamiques .

'O''Reilly'

quote_literal(valeur
anyelement)

text

Convertit la valeur donne en quote_literal(42.5)


texte, puis la place entre guillemets suivant la mthode approprie pour une valeur littrale.
Les guillemets simples et antislashs faisant partie de cette valeur sont doubls proprement.

'42.5'

quote_nullable(chane
text)

text

Renvoie la chane donne quote_nullable(NULL) NULL


convenablement mise entre
guillemets pour tre utilise
comme une chane littrale dans
une instruction SQL ; or si
l'argument est NULL, elle renvoie NULL. Les guillemets
simples et antislashs dans la
chane sont doubls correctement. Voir aussi Exemple 39.1,
Mettre entre guillemets des valeurs dans des requtes dynamiques .

quote_nullable(valeur
anyelement)

text

Renvoie la valeur donne en quote_nullable(42.5) '42.5'


texte, puis la met entre guillemets comme un littral ; or, si
l'argument est NULL, elle renvoie
NULL.Les
guillemets
simples et antislashs dans la
chane sont doubls correctement.

regexp_matches(chane setof
text, modle text [, text[]
drapeaux text])

Renvoie toutes les sous-chanes re{bar,beque}


captures rsultant d'une corres- gexp_matches('foobar
pondance entre l'expression ra- bequebaz',
127

Fonctions et oprateurs

Fonction

Type
Description
renvoy

Exemple

Rsultat

tionnelle POSIX et chane. '(bar)(beque)')


Voir
Section
9.7.3,
Expressions rationnelles POSIX pour plus d'informations.
regexp_replace(chane text
text,
modle
text,
remplacement text [,
drapeaux text])

Remplace la sous-chane corres- reThM


pondant l'expression ration- gexp_replace('Thomas
nelle POSIX. Voir Section 9.7.3, ', '.[mN]a.', 'M')
Expressions rationnelles POSIX pour plus d'informations.

retext[]
c
h
a

n
gexp_split_to_array(e
text, modle text [,
drapeaux text ])

Divise une chane en utilisant


une expression rationnelle POSIX en tant que dlimiteur. Voir
Section 9.7.3, Expressions rationnelles POSIX pour plus
d'informations.

re{hello,world}
gexp_split_to_array(
'hello
world',
E'\\s+')

resetof text
c
h
a

n
gexp_split_to_table(e
text, modle text [,
drapeaux text])

Divise la chane en utilisant


une expression rationnelle POSIX comme dlimiteur. Voir
Section 9.7.3, Expressions rationnelles POSIX pour plus
d'informations.

rehello
gexp_split_to_table(
'hello
world', world
(2 rows)
E'\\s+')

text, text

repeat(chane
nombre int)

replace(chane
text, text
partirde text, vers
text)
text

reverse(chane)
right(chane
int)

text,

n text

rpad(chane
text, text
longueur int [, remplissage text])

rtrim(chane text
caracteres text])

[, text

split_part(chane
text
text,
dlimiteur
text, champ int)
strpos(chane,

sous- int

Rpte le texte
nombre fois

chane repeat('Pg', 4)

PgPgPgPg

Remplace dans chane toutes replace( 'abcdefabc- abXXefabXXef


les occurrences de la sous- def', 'cd', 'XX')
chane partirde par la souschane vers.
Renvoie une chane renverse.

reverse('abcde')

edcba

Renvoie les n derniers carac- right('abcde', 2)


tres dans la chane de caractres. Quand n est ngatif, renvoie tout sauf les n derniers caractres.

de

Complte chane lon- rpad('hi', 5, 'xy')


gueur caractres en ajoutant
les caractres remplissage
la fin (une espace par dfaut). Si
la chane a une taille suprieure longueur, elle est
tronque.

hixyx

Supprime la chane la plus rtrim('trimxxxx',


longue contenant uniquement les 'x')
caractres provenant de caractres (une espace par dfaut) depuis la fin de chane.

trim

Divise chane par rapport au split_part(


dlimiteur et renvoie le 'abc~@~def~@~ghi',
champ donn (en comptant '~@~', 2)
partir de 1).

def

Emplacement de la sous-chane strpos('high', 'ig') 2


128

Fonctions et oprateurs

Fonction

Type
Description
renvoy

Exemple

Rsultat

chane)

indique (identique position(sous-chane


in
sous-chane), mais avec les
arguments en ordre inverse).

substr(chane,
par- text
tirde [, nombre])

Extrait la sous-chane (identique substr('alphabet',

substring(chane 3, 2)
from
partirde
for
nombre))

ph

to_ascii(chane
text text
[, encodage text])

Convertit la chane en ASCII to_ascii('Karel')


partir de n'importe quelle autre
encodage (ne supporte que les
conversions partir de LATIN1,
LATIN2,
LATIN9
et
WIN1250).

Karel

ou text

Convertit nombre dans sa re- to_hex(2147483647)


prsentation hexadcimale quivalente.

7fffffff

translate(chane
text
text, partirde text,
vers text)

Tout caractre de chane qui translate('12345',


correspond un caractre de '143', 'ax')
l'ensemble partirde est
remplac par le caractre correspondant de l'ensemble vers. Si
partirde est plus long que
vers, les occurrences des caractres supplmentaires dans
partirde sont supprimes.

a2x5

to_hex(number
bigint)

int

Voir aussi la fonction d'agrgat string_agg dans Section 9.18, Fonctions d'agrgat .
Tableau 9.7. Conversions intgres

Nom de la conversion a

Codage source

Codage destination

ascii_to_mic

SQL_ASCII

MULE_INTERNAL

ascii_to_utf8

SQL_ASCII

UTF8

big5_to_euc_tw

BIG5

EUC_TW

big5_to_mic

BIG5

MULE_INTERNAL

big5_to_utf8

BIG5

UTF8

euc_cn_to_mic

EUC_CN

MULE_INTERNAL

euc_cn_to_utf8

EUC_CN

UTF8

euc_jp_to_mic

EUC_JP

MULE_INTERNAL

euc_jp_to_sjis

EUC_JP

SJIS

euc_jp_to_utf8

EUC_JP

UTF8

euc_kr_to_mic

EUC_KR

MULE_INTERNAL

euc_kr_to_utf8

EUC_KR

UTF8

euc_tw_to_big5

EUC_TW

BIG5

euc_tw_to_mic

EUC_TW

MULE_INTERNAL

euc_tw_to_utf8

EUC_TW

UTF8

gb18030_to_utf8

GB18030

UTF8

gbk_to_utf8

GBK

UTF8

iso_8859_10_to_utf8

LATIN6

UTF8

iso_8859_13_to_utf8

LATIN7

UTF8

129

Fonctions et oprateurs

Nom de la conversion a

Codage source

Codage destination

iso_8859_14_to_utf8

LATIN8

UTF8

iso_8859_15_to_utf8

LATIN9

UTF8

iso_8859_16_to_utf8

LATIN10

UTF8

iso_8859_1_to_mic

LATIN1

MULE_INTERNAL

iso_8859_1_to_utf8

LATIN1

UTF8

iso_8859_2_to_mic

LATIN2

MULE_INTERNAL

iso_8859_2_to_utf8

LATIN2

UTF8

iso_8859_2_to_windows_1250

LATIN2

WIN1250

iso_8859_3_to_mic

LATIN3

MULE_INTERNAL

iso_8859_3_to_utf8

LATIN3

UTF8

iso_8859_4_to_mic

LATIN4

MULE_INTERNAL

iso_8859_4_to_utf8

LATIN4

UTF8

iso_8859_5_to_koi8_r

ISO_8859_5

KOI8R

iso_8859_5_to_mic

ISO_8859_5

MULE_INTERNAL

iso_8859_5_to_utf8

ISO_8859_5

UTF8

iso_8859_5_to_windows_1251

ISO_8859_5

WIN1251

iso_8859_5_to_windows_866

ISO_8859_5

WIN866

iso_8859_6_to_utf8

ISO_8859_6

UTF8

iso_8859_7_to_utf8

ISO_8859_7

UTF8

iso_8859_8_to_utf8

ISO_8859_8

UTF8

iso_8859_9_to_utf8

LATIN5

UTF8

johab_to_utf8

JOHAB

UTF8

koi8_r_to_iso_8859_5

KOI8R

ISO_8859_5

koi8_r_to_mic

KOI8R

MULE_INTERNAL

koi8_r_to_utf8

KOI8R

UTF8

koi8_r_to_windows_1251

KOI8R

WIN1251

koi8_r_to_windows_866

KOI8R

WIN866

koi8_u_to_utf8

KOI8U

UTF8

mic_to_ascii

MULE_INTERNAL

SQL_ASCII

mic_to_big5

MULE_INTERNAL

BIG5

mic_to_euc_cn

MULE_INTERNAL

EUC_CN

mic_to_euc_jp

MULE_INTERNAL

EUC_JP

mic_to_euc_kr

MULE_INTERNAL

EUC_KR

mic_to_euc_tw

MULE_INTERNAL

EUC_TW

mic_to_iso_8859_1

MULE_INTERNAL

LATIN1

mic_to_iso_8859_2

MULE_INTERNAL

LATIN2

mic_to_iso_8859_3

MULE_INTERNAL

LATIN3

mic_to_iso_8859_4

MULE_INTERNAL

LATIN4

mic_to_iso_8859_5

MULE_INTERNAL

ISO_8859_5

mic_to_koi8_r

MULE_INTERNAL

KOI8R

mic_to_sjis

MULE_INTERNAL

SJIS

mic_to_windows_1250

MULE_INTERNAL

WIN1250

mic_to_windows_1251

MULE_INTERNAL

WIN1251

mic_to_windows_866

MULE_INTERNAL

WIN866

130

Fonctions et oprateurs

Nom de la conversion a

Codage source

Codage destination

sjis_to_euc_jp

SJIS

EUC_JP

sjis_to_mic

SJIS

MULE_INTERNAL

sjis_to_utf8

SJIS

UTF8

tcvn_to_utf8

WIN1258

UTF8

uhc_to_utf8

UHC

UTF8

utf8_to_ascii

UTF8

SQL_ASCII

utf8_to_big5

UTF8

BIG5

utf8_to_euc_cn

UTF8

EUC_CN

utf8_to_euc_jp

UTF8

EUC_JP

utf8_to_euc_kr

UTF8

EUC_KR

utf8_to_euc_tw

UTF8

EUC_TW

utf8_to_gb18030

UTF8

GB18030

utf8_to_gbk

UTF8

GBK

utf8_to_iso_8859_1

UTF8

LATIN1

utf8_to_iso_8859_10

UTF8

LATIN6

utf8_to_iso_8859_13

UTF8

LATIN7

utf8_to_iso_8859_14

UTF8

LATIN8

utf8_to_iso_8859_15

UTF8

LATIN9

utf8_to_iso_8859_16

UTF8

LATIN10

utf8_to_iso_8859_2

UTF8

LATIN2

utf8_to_iso_8859_3

UTF8

LATIN3

utf8_to_iso_8859_4

UTF8

LATIN4

utf8_to_iso_8859_5

UTF8

ISO_8859_5

utf8_to_iso_8859_6

UTF8

ISO_8859_6

utf8_to_iso_8859_7

UTF8

ISO_8859_7

utf8_to_iso_8859_8

UTF8

ISO_8859_8

utf8_to_iso_8859_9

UTF8

LATIN5

utf8_to_johab

UTF8

JOHAB

utf8_to_koi8_r

UTF8

KOI8R

utf8_to_koi8_u

UTF8

KOI8U

utf8_to_sjis

UTF8

SJIS

utf8_to_tcvn

UTF8

WIN1258

utf8_to_uhc

UTF8

UHC

utf8_to_windows_1250

UTF8

WIN1250

utf8_to_windows_1251

UTF8

WIN1251

utf8_to_windows_1252

UTF8

WIN1252

utf8_to_windows_1253

UTF8

WIN1253

utf8_to_windows_1254

UTF8

WIN1254

utf8_to_windows_1255

UTF8

WIN1255

utf8_to_windows_1256

UTF8

WIN1256

utf8_to_windows_1257

UTF8

WIN1257

utf8_to_windows_866

UTF8

WIN866

utf8_to_windows_874

UTF8

WIN874

windows_1250_to_iso_8859_2

WIN1250

LATIN2

131

Fonctions et oprateurs

Nom de la conversion a

Codage source

Codage destination

windows_1250_to_mic

WIN1250

MULE_INTERNAL

windows_1250_to_utf8

WIN1250

UTF8

windows_1251_to_iso_8859_5

WIN1251

ISO_8859_5

windows_1251_to_koi8_r

WIN1251

KOI8R

windows_1251_to_mic

WIN1251

MULE_INTERNAL

windows_1251_to_utf8

WIN1251

UTF8

windows_1251_to_windows_866

WIN1251

WIN866

windows_1252_to_utf8

WIN1252

UTF8

windows_1256_to_utf8

WIN1256

UTF8

windows_866_to_iso_8859_5

WIN866

ISO_8859_5

windows_866_to_koi8_r

WIN866

KOI8R

windows_866_to_mic

WIN866

MULE_INTERNAL

windows_866_to_utf8

WIN866

UTF8

windows_866_to_windows_1251

WIN866

WIN

windows_874_to_utf8

WIN874

UTF8

euc_jis_2004_to_utf8

EUC_JIS_2004

UTF8

utf8_to_euc_jis_2004

UTF8

EUC_JIS_2004

shift_jis_2004_to_utf8

SHIFT_JIS_2004

UTF8

utf8_to_shift_jis_2004

UTF8

SHIFT_JIS_2004

euc_jis_2004_to_shift_jis_2004

EUC_JIS_2004

SHIFT_JIS_2004

shift_jis_2004_to_euc_jis_2004

SHIFT_JIS_2004

EUC_JIS_2004

Les noms des conversions suivent un schma de nommage standard : le nom officiel de l'encodage source avec tous les caractres non alpha-numriques remplacs par des tirets bas suivi de _to_ suivi
du nom de l'encodage cible ayant subit le mme traitement que le nom de l'encodage source. Il est donc possible que les noms varient par rapport aux noms d'encodage personnaliss.

9.5. Fonctions et oprateurs de chanes binaires


Cette section dcrit les fonctions et oprateurs d'examen et de manipulation des valeurs de type bytea.
SQL dfinit quelques fonctions de chanes qui utilise des mots cls qui sont employs la place de virgules pour sparer les arguments. Les dtails sont prsents dans Tableau 9.8, Fonctions et oprateurs SQL pour chanes binaires . PostgreSQL fournit
aussi des versions de ces fonctions qui utilisant la syntaxe standard de l'appel de fonction (voir le Tableau 9.9, Autres fonctions
sur les chanes binaires ).

Note
Les rsultats en exemple montrs ici supposent que le paramtre serveur bytea_output est configur escape
(le format traditionel de PostgreSQL).
Tableau 9.8. Fonctions et oprateurs SQL pour chanes binaires

Fonction

Type renvoy

chane || chane bytea

cha

int

Description

Exemple

Rsultat

Concatnation de chane E'\\\\Post'::bytea


|| \\Post'gres\000
E'\\047gres\\000'::byte
a
Nombre d'octets d'une octet_length(
chane binaire
E'jo\\000se'::bytea)

132

Fonctions et oprateurs

Fonction

Type renvoy

Description

Exemple

Rsultat

)
overlay(chane
bytea
placing
chane
from
int
[for
int])

Remplace
chane

position(sousint
chane
in
chane)

Emplacement de la sous- position(


3
chane indique
E'\\000om'::bytea
in
E'Th\\000omas'::bytea)

substring(chane bytea
[from int] [for
int])

Extrait la sous-chane

subh\000o
string(E'Th\\000omas'::
bytea from 2 for 3)

Supprime la plus longue


chane compose uniquement d'octets de octets partir du dbut
et de la fin de chane

trim(E'\\000'::bytea
Tom
from
E'\\000Tom\\000'::bytea
)

trim([both]
tets
chane)

oc- bytea
from

une

sous- overT\\002\\003mas
lay(E'Th\\000omas'::byt
ea
placing
E'\\002\\003'::bytea
from 2 for 3)

Des fonctions supplmentaires de manipulations de chanes binaires sont listes dans le Tableau 9.9, Autres fonctions sur les
chanes binaires . Certaines sont utilises en interne pour coder les fonctions de chanes suivant le standard SQL et sont listes
dans le Tableau 9.8, Fonctions et oprateurs SQL pour chanes binaires .
Tableau 9.9. Autres fonctions sur les chanes binaires

Fonction
btrim(chane
tea, octets
tea)

Type re- Description


tourn
by- bytea
by-

Exemple

Supprime la plus longue btrim(


chane constitue uni- E'\\000trim\\000'::bytea,
quement d'octets de oc- E'\\000'::bytea)
tets partir du dbut
et de la fin de chane.

Rsultat
trim

decode(chane
bytea
text,
format
text)

Dcode les donnes bi- decode(E'123\\000456', 'es- 123\000456


naires de leur reprsen- cape')
tation textuelle dans
chane auparavant code. Les options pour
format sont les mmes
que pour encode.

encode(chane
text
bytea,
type
text)

Code les donnes bi- en123\000456


naires en une reprsenta- code(E'123\\000456'::bytea,
tion textuelle. Les for- 'escape')
mats supports sont :
base64,
hex,
escape.
escape
convertit les octets nuls
et les octets dont le bit
de poids fort est 1, en
squence octal (\nnn)
et
des
antislashs
doubles.

get_bit(chane,
offset)

int

get_byte(chane, int
offset)
length(chane)

int

Extrait
chane

un

bit

d'une get_bit(E'Th\\000omas'::byt 1
ea, 45)

Extrait un octet d'une get_byte(E'Th\\000omas'::by 109


chane
tea, 4)
Longueur de la chane length(E'jo\\000se'::bytea) 5
binaire
133

Fonctions et oprateurs

Fonction

Type re- Description


tourn

Exemple

Rsultat

md5(chane)

text

Calcule le hachage MD5 md5(E'Th\\000omas'::bytea)


de la chane et retourne le rsultat en
hexadcimal

set_bit(chane,
offset,
newvalue)

bytea

Positionne un bit dans set_bit(E'Th\\000omas'::byt Th\000omAs


une chane
ea, 45, 0)

set_byte(chane, bytea
offset,
newvalue)

Positionne un octet dans set_byte(E'Th\\000omas'::by Th\000o@as


une chane
tea, 4, 64)

8ab2d3c9689aaf18
b4958c334c82d8b1

get_byte et set_byte prennent en compte le premier octet d'une chane binaire comme l'octet numro zro. get_bit et
set_bit comptent les bits partir de la droite pour chaque octet. Par exemple, le bit 0 est le bit le moins significatif du premier
octet et le bit 15 est le bit le plus significatif du second octet.

9.6. Fonctions et oprateurs sur les chanes de bits


Cette section dcrit les fonctions et oprateurs d'examen et de manipulation des chanes de bits, c'est--dire des valeurs de types bit
et bit varying. En dehors des oprateurs de comparaison habituels, les oprateurs prsents dans le Tableau 9.10, Oprateurs sur
les chanes de bits peuvent tre utiliss. Les oprandes de chanes de bits utiliss avec &, | et # doivent tre de mme longueur.
Lors d'un dcalage de bits, la longueur originale de la chane est prserve comme le montrent les exemples.
Tableau 9.10. Oprateurs sur les chanes de bits

Oprateur

Description

Exemple

Rsultat

||

concatnation

B'10001' || B'011'

10001011

&

AND bit bit

B'10001' & B'01101'

00001

OR bit bit

B'10001' | B'01101'

11101

XOR bit bit

B'10001' # B'01101'

11100

NOT bit bit

~ B'10001'

01110

<<

dcalage gauche bit bit

B'10001' << 3

01000

>>

dcalage droit bit bit

B'10001' >> 2

00100

Les fonctions SQL suivantes fonctionnent sur les chanes de bits ainsi que sur les chanes de caractres : length, bit_length,
octet_length, position, substring, overlay.
Les fonctions suivantes fonctionnent sur les chanes de bits ainsi que sur les chanes binaires : get_bit, set_bit. En travaillant sur des chanes de bits, ces fonctions numrotent le premier bit (le plus gauche) comme le bit 0.
De plus, il est possible de convertir des valeurs intgrales vers ou depuis le type bit. Quelques exemples :
44::bit(10)
44::bit(3)
cast(-44 as bit(12))
'1110'::bit(4)::integer

0000101100
100
111111010100
14

Le transtypage bit signifie transtyper en bit(1) et, de ce fait, seul le bit de poids faible de l'entier est rendu.

Note
Avant PostgreSQL 8.0, la conversion d'un entier en bit(n) copiait les n bits les plus gauche de l'entier. Dsormais, ce sont les n bits les plus droite qui sont copis. De plus, la conversion d'un entier en une chane de bits plus
grande que l'entier lui-mme tend l'entier, avec signature, vers la gauche.

9.7. Correspondance de motif


PostgreSQL fournit trois approches diffrentes la correspondance de motif : l'oprateur SQL traditionnel LIKE, le plus rcent
134

Fonctions et oprateurs

SIMILAR TO (ajout dans SQL:1999) et les expressions rationnelles de type POSIX. En dehors des oprateurs basiques du style
est-ce que cette chane correspond ce modle ? , les fonctions sont disponibles pour extraire ou remplacer des sous-chanes
correspondantes ou pour diviser une chane aux emplacements correspondants.

Astuce
Si un besoin de correspondances de motif va au-del, il faut considrer l'criture d'une fonction en Perl ou Tcl.

9.7.1. LIKE
chane LIKE motif [ESCAPE caractre d'chappement]
chane NOT LIKE motif [ESCAPE caractre d'chappement]
L'expression LIKE renvoie true si la chane est contenue dans l'ensemble de chanes reprsent par le motif. (L'expression
NOT LIKE renvoie false si LIKE renvoie true et vice versa. Une expression quivalente est NOT (chane LIKE motif).)
Si le motif ne contient ni signe pourcent ni tiret bas, alors il ne reprsente que la chane elle-mme ; dans ce cas, LIKE agit
exactement comme l'oprateur d'galit. Un tiret bas (_) dans motif correspond un seul caractre, un signe pourcent (%)
toutes les chanes de zro ou plusieurs caractres.
Quelques exemples :
'abc'
'abc'
'abc'
'abc'

LIKE
LIKE
LIKE
LIKE

'abc'
'a%'
'_b_'
'c'

true
true
true
false

Le modle LIKE correspond toujours la chane entire. Du coup, pour faire correspondre une squence l'intrieur d'une chane,
le motif doit donc commencer et finir avec un signe pourcent.
Pour faire correspondre un vrai tiret bas ou un vrai signe de pourcentage sans correspondance avec d'autres caractres, le caractre
correspondant dans motif doit tre prcd du caractre d'chappement. Par dfaut, il s'agit de l'antislash, mais un autre caractre
peut tre slectionn en utilisant la clause ESCAPE. Pour un correspondance avec le caractre d'chappement lui-mme, on crit
deux fois ce caractre.

Note
Si vous avez dsactiv standard_conforming_strings, tout antislash crit dans des chanes litrales devra tre doubl. Voir Section 4.1.2.1, Constantes de chanes pour plus d'informations.
Il est aussi possible de ne slectionner aucun caractre d'chappement en crivant ESCAPE ''. Ceci dsactive compltement le
mcanisme d'chappement, ce qui rend impossible la dsactivation de la signification particulire du tiret bas et du signe de pourcentage dans le motif.
Le mot cl ILIKE est utilis la place de LIKE pour faire des correspondances sans tenir compte de la casse mais en tenant
compte de la locale active. Ceci ne fait pas partie du standard SQL mais est une extension PostgreSQL.
L'oprateur ~~ est quivalent LIKE alors que ~~* correspond ILIKE. Il existe aussi les oprateurs !~~ et !~~* reprsentant
respectivement NOT LIKE et NOT ILIKE. Tous ces oprateurs sont spcifiques PostgreSQL.

9.7.2. Expressions rationnelles SIMILAR TO


chane SIMILAR TO motif [ESCAPE caractre d'chappement]
chane NOT SIMILAR TO motif [ESCAPE caractre d'chappement]
L'oprateur SIMILAR TO renvoie true ou false selon que le motif correspond ou non la chane donne. Il se rapproche de LIKE
la diffrence qu'il interprte le motif en utilisant la dfinition SQL d'une expression rationnelle. Les expressions rationnelles
SQL sont un curieux mlange de la notation LIKE et de la notation habituelle des expressions rationnelles.
l'instar de LIKE, l'oprateur SIMILAR TO ne russit que si son motif correspond la chane entire ; ceci en dsaccord avec
les pratiques habituelles des expressions rationnelles o le modle peut se situer n'importe o dans la chane. Tout comme LIKE,
SIMILAR TO utilise _ et % comme caractres joker reprsentant respectivement tout caractre unique et toute chane (ils sont
comparables . et .* des expressions rationnelles compatibles POSIX).
En plus de ces fonctionnalits empruntes LIKE, SIMILAR TO supporte trois mta-caractres de correspondance de motif emprunts aux expressions rationnelles de POSIX :
135

Fonctions et oprateurs

| reprsente une alternative (une des deux alternatives) ;

* reprsente la rptition des lments prcdents, 0 ou plusieurs fois ;

+ reprsente la rptition des lments prcdents, une ou plusieurs fois ;

? dnote une rptition du prcdent lment zro ou une fois.

{m} dnote une rptition du prcdent lment exactement m fois.

{m,} dnote une rptition du prcdent lment m ou plusieurs fois.

{m,n} dnote une rptition du prcdent lment au moins m et au plus n fois.

les parenthses () peuvent tre utilises pour grouper des lments en un seul lment logique ;

une expression entre crochets [...] spcifie une classe de caractres, comme dans les expressions rationnelles POSIX.

Notez que le point (.) n'est pas un mta-caractre pour SIMILAR TO.
Comme avec LIKE, un antislash dsactive la signification spciale de tous les mta-caractres ; un autre caractre d'chappement
peut tre indiqu avec ESCAPE.
Quelques exemples :
'abc'
'abc'
'abc'
'abc'

SIMILAR
SIMILAR
SIMILAR
SIMILAR

TO
TO
TO
TO

'abc'
'a'
'%(b|d)%'
'(b|c)%'

true
false
true
false

La fonction substring avec trois paramtres, substring(chane from motif for caractre
d'chappement), fournit l'extraction d'une sous-chane correspondant un motif d'expression rationnelle SQL. Comme avec
SIMILAR TO, le motif fourni doit correspondre la chane de donnes entire, sinon la fonction choue et renvoie NULL. Pour
indiquer la partie du motif retourner en cas de succs, le motif doit contenir deux occurrences du caractre d'chappement suivi
d'un guillemet double ("). Le texte correspondant la portion du motif entre ces deux marqueurs est renvoy.
Quelques exemples, avec #" dlimitant la chane en retour :
substring('foobar' from '%#"o_b#"%' for '#')
oob
substring('foobar' from '#"o_b#"%' for '#')
NULL

9.7.3. Expressions rationnelles POSIX


Le Tableau 9.11, Oprateurs de correspondance des expressions rationnelles liste les oprateurs disponibles pour la correspondance de motifs partir d'expressions rationnelles POSIX.
Tableau 9.11. Oprateurs de correspondance des expressions rationnelles

Oprateur Description

Exemple

Correspondance d'expression rationnelle, en tenant compte de la casse

'thomas' ~ '.*thomas.*'

~*

Correspondance d'expression rationnelle, sans tenir compte de la casse

'thomas' ~* '.*Thomas.*'

!~

Non-correspondance d'expression rationnelle, en tenant compte de la 'thomas' !~ '.*Thomas.*'


casse

!~*

Non-correspondance d'expression rationnelle, sans tenir compte de la 'thomas' !~* '.*vadim.*'


casse

Les expressions rationnelles POSIX sont un outil de correspondance de motifs plus puissant que les oprateurs LIKE et SIMILAR
TO. Beaucoup d'outils Unix comme egrep, sed ou awk utilisent un langage de correspondance de modles similaire celui dcrit
ici.
Une expression rationnelle est une squence de caractres reprsentant une dfinition abrge d'un ensemble de chanes (un ensemble rationnel). Une chane est dclare correspondre une expression rationnelle si elle est membre de l'ensemble rationnel
dcrit par l'expression rationnelle. Comme avec LIKE, les caractres du motif correspondent exactement aux caractres de le
chane sauf s'ils reprsentent des caractres spciaux dans le langage des expressions rationnelles -- mais les expressions rationnelles utilisent des caractres spciaux diffrents de ceux utiliss par LIKE. Contrairement aux motifs de LIKE, une expression
136

Fonctions et oprateurs

rationnelle peut avoir une correspondance en toute place de la chane, sauf si l'expression rationnelle est explicitement ancre au
dbut ou la fin de la chane.
Quelques exemples :
'abc'
'abc'
'abc'
'abc'

~
~
~
~

'abc'
'^a'
'(b|d)'
'^(b|c)'

true
true
true
false

Le langage modle POSIX est dcrit avec plus de dtail ci-dessous.


La fonction substring avec deux paramtres, substring(chane from motif), extrait une sous-chane qui correspond un motif d'expression rationnelle POSIX. Elle renvoie NULL s'il n'y a pas de correspondance, la portion de texte correspondant au modle dans le cas contraire. Mais si le motif contient des parenthses, c'est la portion de texte qui correspond la premire sous-expression entre parenthses (la premire dont la parenthse gauche apparat) qui est renvoye. Il est possible de placer
toute l'expression entre parenthses pour pouvoir utiliser des parenthses l'intrieur sans dclencher cette exception. Si des parenthses sont ncessaires dans le motif avant la sous-expression extraire, il faut utiliser les proprits des parenthses noncapturantes dcrites plus bas.
Quelques exemples :
substring('foubar' from 'o.b')
substring('foubar' from 'o(.)b')

oub
u

La fonction regexp_replace substitue un nouveau texte aux sous-chanes correspondantes des motifs d'expressions rationnelles. Elle a la syntaxe regexp_replace(source, motif, remplacement [, options ]). La chane source est renvoye non modifie s'il n'existe pas de correspondance avec motif. S'il existe une correspondance, la chane source est renvoye avec la chane remplacement substitue la sous-chane correspondante. La chane remplacement peut contenir \n,
avec n de 1 9, pour indiquer que la n-ime sous-chane source correspondante doit tre insre. Elle peut aussi contenir \& pour
indiquer que la sous-chane qui correspond au motif entier doit tre insre. On crit \\ pour placer un antislash littral dans le
texte de remplacement. Le paramtre options est une chane optionnelle de drapeaux (0 ou plus) d'une lettre qui modifie le
comportement de la fonction. Le drapeau i indique une recherche insensible la casse, le drapeau g un remplacement de chaque
sous-chane correspondante (pas uniquement la premire). Les autres options supportes sont dcrites dans Tableau 9.19, Lettres
d'option intgres une ERA .
Quelques exemples :
regexp_replace('foobarbaz', 'b..', 'X')
fooXbaz
regexp_replace('foobarbaz', 'b..', 'X', 'g')
fooXX
regexp_replace('foobarbaz', 'b(..)', E'X\\1Y', 'g')
fooXarYXazY
La fonction regexp_matches renvoie un tableau de texte contenant toutes les sous-chanes captures rsultant de la correspondance avec une expression rationnelle POSIX. Elle a la syntaxe : regexp_matches(chaine, modele [, options ]). La
fonction peut ne renvoyer aucune ligne, une ligne ou plusieurs lignes (voir le drapeau g ci-dessous). Si le motif ne correspond
pas, la fonction ne renvoie aucune ligne. Si le motif ne contient aucune sous-expressions entre parenthses, alors chaque ligne renvoye est un tableau de texte un seul lment contenant la sous-chane correspondant au motif complet. Si le motif contient des
sous-expressions entre parenthses, la fonction renvoie un tableau de texte dont l'lment n est la sous-chane en correspondance
avec la n-ime sous-expression entre parenthses du modle (sans compter les parenthses non capturantes ; voir ci-dessous
pour les dtails). Le paramtre options est une chane optionnelle contenant zro ou plus options d'une lettre, modifiant ainsi le
comportement de la fonction. L'option g indique que la fonction trouve chaque correspondance dans la chane, pas seulement la
premire, et renvoie une ligne pour chaque correspondance. Les autres options supportes sont dcrites dans Tableau 9.19,
Lettres d'option intgres une ERA .
Quelques exemples :
SELECT regexp_matches('foobarbequebaz', '(bar)(beque)');
regexp_matches
---------------{bar,beque}
(1 row)
SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');
regexp_matches
---------------137

Fonctions et oprateurs

{bar,beque}
{bazil,barf}
(2 rows)
SELECT regexp_matches('foobarbequebaz', 'barbeque');
regexp_matches
---------------{barbeque}
(1 row)
Il est possible de forcer regexp_matches() toujours renvoyer une ligne en utilisant une sous-slection ; ceci est particulirement utile dans une liste cible SELECT lorsque vous voulez renvoyer toutes les lignes, y compris celles qui ne correspondent pas :
SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab;
La fonction regexp_split_to_table divise une chane en utilisant une expression rationnelle POSIX comme dlimiteur.
Elle a la syntaxe suivante : regexp_split_to_table(chaine, modele [, options ]). S'il n'y a pas de correspondance
avec le modele, la fonction renvoie la chaine. S'il y a au moins une correspondance, pour chaque correspondance, elle renvoie
le texte partir de la fin de la dernire correspondance (ou le dbut de la chane) jusqu'au dbut de la correspondance. Quand il ne
reste plus de correspondance, elle renvoie le texte depuis la fin de la dernire correspondance jusqu' la fin de la chane. Le paramtre options est une chane optionnelle contenant zro ou plus options d'un caractre, modifiant ainsi le comportement de la
fonction. regexp_split_to_table supporte les options dcrites dans Tableau 9.19, Lettres d'option intgres une
ERA .
La fonction regexp_split_to_array se comporte de la mme faon que regexp_split_to_table, sauf que regexp_split_to_array renvoie son rsultat en tant que tableau de text. Elle a comme syntaxe
regexp_split_to_array(chaine, modele [, options ]). Les paramtres sont les mmes que pour regexp_split_to_table.
Quelques exemples :

SELECT foo FROM regexp_split_to_table('the quick brown fox jumped over the lazy dog',
E'\\s+') AS foo;
foo
-------the
quick
brown
fox
jumped
over
the
lazy
dog
(9 rows)
SELECT regexp_split_to_array('the quick brown fox jumped over the lazy dog', E'\\s+');
regexp_split_to_array
-----------------------------------------------{the,quick,brown,fox,jumped,over,the,lazy,dog}
(1 row)
SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
foo
----t
h
e
q
u
i
c
k
b
r
138

Fonctions et oprateurs

o
w
n
f
o
x
(16 rows)
Comme le montre le dernier exemple, les fonctions de division des expressions rationnelles ignorent les correspondances de longueur nulle qui surviennent au dbut ou la fin de la chane ou immdiatement aprs une correspondance. C'est contraire la dfinition stricte de la correspondance des expressions rationnelles implante par regexp_matches, mais c'est habituellement le
comportement le plus pratique. Les autres systmes comme Perl utilisent des dfinitions similaires.

9.7.3.1. Dtails des expressions rationnelles


Les expressions rationnelles de PostgreSQL sont implantes l'aide d'un paquetage crit par Henry Spencer. Une grande partie
de la description des expressions rationnelles ci-dessous est une copie intgrale de son manuel.
Les expressions rationnelles (ERs), telles que dfinies dans POSIX 1003.2, existent sous deux formes : les ER tendues ou ERE
(en gros celles de egrep) et les ER basiques ou ERB (BRE en anglais) (en gros celles d'ed). PostgreSQL supporte les deux
formes et y ajoute quelques extensions ne faisant pas partie du standard POSIX mais largement utilises du fait de leur disponibilit dans les langages de programmation tels que Perl et Tcl. Les ER qui utilisent ces extensions non POSIX sont appeles des ER
avances ou ERA (ARE en anglais) dans cette documentation. Les ERA sont un sur-ensemble exact des ERE alors que les ERB
ont des incompatibilits de notation (sans parler du fait qu'elles sont bien plus limites). En premier lieu sont dcrits les formats
ERA et ERE, en prcisant les fonctionnalits qui ne s'appliquent qu'aux ERA. L'explication des diffrences des ERB vient ensuite.

Note
PostgreSQL prsume toujours au dpart qu'une expression rationnelle suit les rgles ERA. Nanmoins, les rgles
ERE et BRE (plus limites) peuvent tre choisies en ajoutant au dbut une option d'imbrication sur le motif de
l'ER, comme dcrit dans Section 9.7.3.4, Mtasyntaxe des expressions rationnelles . Cela peut tre utile pour la
compatibilit avec les applications qui s'attendent suivre exactement les rgles POSIX.
Une expression rationnelle est dfinie par une ou plusieurs branches spares par des caractres |. Elle tablit une correspondance
avec tout ce qui correspond une des branches.
Une branche contient des atomes quantifis, ou contraintes, concatns. Elle tablit une correspondance pour le premier suivi
d'une correspondance pour le second, etc ; une branche vide tablit une correspondance avec une chane vide.
Un atome quantifi est un atome ventuellement suivi d'un quantificateur unique. Sans quantificateur, il tablit une correspondance avec l'atome. Avec un quantificateur, il peut tablir un certain nombre de correspondances avec l'atome. Un atome est une
des possibilits du Tableau 9.12, Atomes d'expressions rationnelles . Les quantificateurs possibles et leurs significations sont
disponibles dans le Tableau 9.13, quantificateur d'expressions rationnelles .
Une contrainte tablit une correspondance avec une chane vide, mais cette correspondance n'est tablie que lorsque des conditions spcifiques sont remplies. Une contrainte peut tre utilise l o un atome peut l'tre et ne peut pas tre suivie d'un quantificateur. Les contraintes simples sont affiches dans le Tableau 9.14, Contraintes des expressions rationnelles ; quelques
contraintes supplmentaires sont dcrites plus loin.
Tableau 9.12. Atomes d'expressions rationnelles

Atome

Description

(re)

(o re est toute expression rationnelle) tablit une correspondance avec re, la correspondance tant
conserve en vue d'un ventuel report

(?:re)

comme ci-dessus mais la correspondance n'est pas conserve pour report (un ensemble de parenthses
sans capture ) (seulement pour les ERA)

correpondance avec tout caractre unique

[caractres]

une expression entre crochets, qui tablit une correspondance avec tout caractre de caractres
(voir la Section 9.7.3.2, Expressions avec crochets pour plus de dtails)

\k

(o k n'est pas un caractre alpha-numrique) tablit une correspondance avec ce caractre, considr
comme caractre ordinaire. Par exemple, \\ tablit une correspondance avec un caractre antislash

\c

avec c un caractre alphanumrique (ventuellement suivi d'autres caractres) est un chappement,


voir la Section 9.7.3.3, chappement d'expressions rationnelles (ERA seulement ; pour les ERE et
139

Fonctions et oprateurs

Atome

Description
ERB, tablit une correspondance avec c)

lorsqu'il est suivi d'un caractre autre qu'un chiffre, tablit une correspondance avec l'accolade ouvrante
{ ; suivi d'un chiffre, c'est le dbut d'une limite (voir ci-dessous)

o x est un caractre unique sans signification, tablit une correspondance avec ce caractre

Une ER ne peut pas se terminer par un antislash (\).

Note
Si vous avez dsactiv standard_conforming_strings, tout antislash crit dans des chantes litrales devra tre doubl. Voir Section 4.1.2.1, Constantes de chanes pour plus d'informations.
Tableau 9.13. quantificateur d'expressions rationnelles

quantificateur

Correspondance

une squence de 0 ou plus correspondance(s) de l'atome

une squence de 1 ou plus correspondance(s) de l'atome

une squence de 0 ou 1 correspondance de l'atome

{m}

une squence d'exactement m correspondances de l'atome

{m,}

une squence de m ou plus correspondances de l'atome

{m,n}

une squence de m n (inclus) correspondances de l'atome ; m ne doit pas tre suprieur n

*?

version non gourmande de *

+?

version non gourmande de +

??

version non gourmande de ?

{m}?

version non gourmande de {m}

{m,}?

version non gourmande de {m,}

{m,n}?

version non gourmande de {m,n}

Les formes qui utilisent {...} sont appeles limites. Les nombres m et n l'intrieur d'une limite sont des entiers non signs dont
les valeurs vont de 0 255 inclus.
Les quantificateurs non gourmands (disponibles uniquement avec les ERA) correspondent aux mme possibilits que leurs quivalents normaux (gourmand), mais prfrent le plus petit nombre de correspondances au plus grand nombre. Voir la Section 9.7.3.5, Rgles de correspondance des expressions rationnelles pour plus de dtails.

Note
Un quantificateur ne peut pas immdiatement suivre un autre quantificateur, autrement dit ** est invalide. Il ne
peut pas non plus dbuter une expression ou sous-expression ni suivre ^ ou |.
Tableau 9.14. Contraintes des expressions rationnelles

Contrainte

Description

correspondance de dbut de chane

correspondance de fin de chane

(?=er)

positive lookahead (recherche positive) tablit une correspondance avec tout point o une sous-chane
qui correspond er dbute (uniquement pour les ERA)

(?!er)

negative lookahead (recherche ngative) tablit une correspondance avec tout point o aucune souschane qui correspond re ne dbute (uniquement pour les ERA)

Les contraintes lookahead ne doivent pas contenir de rfrences arrires (voir la Section 9.7.3.3, chappement d'expressions
140

Fonctions et oprateurs

rationnelles ), et toutes les parenthses contenues sont considres comme non capturantes.

9.7.3.2. Expressions avec crochets


Une expression entre crochets est une liste de caractres contenue dans []. Une correspondance est habituellement tablie avec
tout caractre de la liste (voir cependant plus bas). Si la liste dbute par ^, la correspondance est tablie avec tout caractre non
compris dans la liste. Si deux caractres de la liste sont spars par un tiret (-), il s'agit d'un raccourci pour reprsenter tous les caractres compris entre ces deux-l, c'est--dire qu'en ASCII, [0-9] correspond tout chiffre. Deux squences ne peuvent pas partager une limite, par exemple a-c-e. Les plages tant fortement lies la squence de tri (collate), il est recommand de ne pas
les utiliser dans les programmes portables.
Un ] peut tre inclus dans la liste s'il en est le premier caractre (ventuellement prcd de ^). Un - peut tre inclus dans la liste
s'il en est le premier ou le dernier caractre ou s'il est la deuxime borne d'une plage. Un - peut tre utilis comme premire borne
d'une plage s'il est entour par [. et .] et devient de ce fait un lment d'interclassement (collating element). l'exception de ces
caractres, des combinaisons utilisant [ (voir les paragraphes suivants) et des chappements (uniquement pour les ERA), tous les
autres caractres spciaux perdent leur signification spciale l'intrieur d'une expression entre crochets. En particulier, \ n'est pas
spcial lorsqu'il suit les rgles des ERE ou des ERB bien qu'il soit spcial (en tant qu'introduction d'un chappement) dans les
ERA.
Dans une expression entre crochets, un lment d'interclassement (un caractre, une squence de caractres multiples qui
s'interclasse comme un lment unique, ou le nom d'une squence d'interclassement) entour de [. et .] reprsente la squence
de caractres de cet lment d'interclassement. La squence est un lment unique de la liste dans l'expression entre crochets. Une
expression entre crochets contenant un lment d'interclassement multi-caractres peut donc correspondre plusieurs caractres
(par exemple, si la squence d'interclassement inclut un lment d'interclassement ch, alors l'ER [[.ch.]]*c tablit une correspondance avec les cinq premiers caractres de chchcc.

Note
PostgreSQL n'a pas, ce jour, d'lments d'interclassement multi-caractres. L'information porte ici dcrit un
ventuel comportement futur.
Dans une expression entre crochets, un lment d'interclassement crit entre [= et =] est une classe d'quivalence qui reprsente
les squences de caractres de tous les lments d'interclassement quivalents celui-l, lui compris. (En l'absence d'lment
d'interclassement quivalent, le traitement correspond celui obtenu avec les dlimiteurs [. et .]). Par exemple, si o et ^ sont les
membres d'une classe d'quivalence, alors [[=o=]], [[=^=]] et [o^] sont tous synonymes. Une classe d'quivalence ne peut
pas tre borne d'une plage.
Dans une expression entre crochets, le nom d'une classe de caractres crit entre [: et :] reprsente la liste de tous les caractres
appartenant cette classe. Les noms de classes de caractres standard sont alnum, alpha, blank, cntrl, digit, graph,
lower, print, punct, space, upper, xdigit. Ils correspondent aux classes de caractres dfinies dans ctype(3). Une locale peut en fournir d'autres. Une classe de caractres ne peut pas tre utilise comme borne d'une plage.
Il existe deux cas spciaux d'expressions entre crochets : les expressions entre crochets [[:<:]] et [[:>:]] sont des
contraintes, qui tablissent une correspondance avec des chanes vides respectivement au dbut et la fin d'un mot. Un mot est dfini comme une squence de caractres de mot qui n'est ni prcde ni suivie de caractres de mot. Un caractre de mot est un caractre alnum (comme dfini par ctype(3)) ou un tiret bas. C'est une extension, compatible avec, mais non spcifie dans POSIX
1003.2, et devant tre utilise avec prcaution dans les logiciels conus pour tre portables sur d'autres systmes. Les chappements de contraintes dcrits ci-dessous sont gnralement prfrables (ils ne sont pas plus standard mais certainement plus simples
saisir).

9.7.3.3. chappement d'expressions rationnelles


Les chappements sont des squences spciales dbutant avec \ suivi d'un caractre alphanumrique. Il existe plusieurs sortes
d'chappements : entre de caractre, raccourci de classe, chappement de contraintes et rtro-rfrences. Un \ suivi d'un caractre
alphanumrique qui ne constitue pas un chappement valide est illgal dans une ERA. Pour les ERE, il n'y pas d'chappement : en
dehors d'une expression entre crochets, un \ suivi d'un caractre alphanumrique reprsente simplement ce caractre (comme ordinaire) et, l'intrieur d'une expression entre crochets, \ est un caractre ordinaire. (C'est dans ce dernier cas que se situe rellement l'incompatibilit entre les ERE et les ERA.)
Les chappements de caractre (character-entry escapes) permettent d'indiquer des caractres non affichables et donc indsirables
dans les ER. Ils sont prsents dans le Tableau 9.15, chappements de caractre dans les expressions rationnelles .
Les chappements de raccourci de classe (class-shorthand escapes) fournissent des raccourcis pour certaines classes de caractres
communment utilises. Ils sont prsents dans le Tableau 9.16, chappement de raccourcis de classes dans les expressions rationnelles .

141

Fonctions et oprateurs

Un chappement de contrainte (constraint escape) est une contrainte, qui correspond la chane vide sous certaines conditions,
crite comme un chappement. Ces chappements sont prsents dans le Tableau 9.17, chappements de contrainte dans les expressions rationnelles .
Une rtro-rfrence (back reference) (\n) correspond la mme chane que la sous-expression entre parenthses prcdente indique par le nombre n (voir le Tableau 9.18, Rtro-rfrences dans les expressions rationnelles ). Par exemple, ([bc])\1 peut
correspondre bb ou cc, mais ni bc ni cb. La sous-expression doit prcder compltement la rfrence dans l'ER. Les sousexpressions sont numrotes dans l'ordre des parenthses ouvrantes. Les parenthses non capturantes ne dfinissent pas de sousexpressions.

Note
Le symbole \ qui dbute une squence d'chappement doit tre obligatoirement doubl pour saisir le motif comme
une chane SQL constante. Par exemple :
'123' ~ E'^\\d{3}' true

Tableau 9.15. chappements de caractre dans les expressions rationnelles

chappement

Description

\a

caractre alerte (cloche), comme en C

\b

effacement (backspace), comme en C

\B

synonyme de \ pour viter les doublements d'antislash

\cX

(o X est un caractre quelconque) le caractre dont les cinq bits de poids faible sont les mmes que
ceux de X et dont tous les autres bits sont zro

\e

le caractre dont le nom de squence d'interclassement est ESC, ou le caractre de valeur octale 033

\f

retour chariot (form feed), comme en C

\n

retour la ligne (newline), comme en C

\r

retour chariot (carriage return), comme en C

\t

tabulation horizontale, comme en C

\uwxyz

(o wxyz reprsente exactement quatre chiffres hexadcimaux) le caractre UTF16 (Unicode, 16 bits)
U+wxyz dans l'ordre local des octets

\Ustuvwxyz

(o stuvwxyz reprsente exactement huit chiffres hexadcimaux) rserv pour une extension, hypothtique, de l'Unicode vers le 32 bits

\v

tabulation verticale, comme en C

\xhhh

(o hhh reprsente toute squence de chiffres hexadcimaux) le caractre dont la valeur hexadcimale
est 0xhhh (un simple caractre, peu importe le nombre de chiffres hexadcimaux utiliss)

\0

le caractre dont la valeur est 0

\xy

(o xy reprsente exactement deux chiffres octaux et n'est pas une rtro-rfrence) le caractre dont la
valeur octale est 0xy

\xyz

(o xyz reprsente exactement trois chiffres octaux et n'est pas une rtro-rfrence) le caractre dont
la valeur octale est 0xyz

Les chiffres hexadcimaux sont 0-9, a-f et A-F. Les chiffres octaux sont 0-7.
Les chappements de caractre sont toujours pris comme des caractres ordinaires. Par exemple, \135 est ] en ASCII mais \135
ne termine pas une expression entre crochets.
Tableau 9.16. chappement de raccourcis de classes dans les expressions rationnelles

chappement

Description

\d

[[:digit:]]

\s

[[:space:]]

\w

[[:alnum:]_] (le tiret bas est inclus)


142

Fonctions et oprateurs

chappement

Description

\D

[^[:digit:]]

\S

[^[:space:]]

\W

[^[:alnum:]_] (le tiret bas est inclus)

Dans les expressions entre crochets, \d, \s, et \w perdent leurs crochets externes et \D, \S et \W ne sont pas autoriss. (Ainsi,
par exemple, [a-c\d] est quivalent [a-c[:digit:]]. Mais [a-c\D], qui est quivalent [a-c^[:digit:]], est interdit.)
Tableau 9.17. chappements de contrainte dans les expressions rationnelles

chappement

Description

\A

n'tablit la correspondance qu'au dbut de la chane (voir la Section 9.7.3.5, Rgles de correspondance des expressions rationnelles pour comprendre la diffrence avec ^)

\m

n'tablit la correspondance qu'au dbut d'un mot

\M

n'tablit la correspondance qu' la fin d'un mot

\y

n'tablit la correspondance qu'au dbut ou la fin d'un mot

\Y

n'tablit la correspondance qu'en dehors du dbut et de la fin d'un mot

\Z

n'tablit la correspondance qu' la fin d'une chane (voir la Section 9.7.3.5, Rgles de correspondance
des expressions rationnelles pour comprendre la diffrence avec $)

Un mot est dfini selon suivant la spcification de [[:<:]] et [[:>:]] donne ci-dessus. Les chappement de contrainte sont
interdits dans les expressions entre crochets.
Tableau 9.18. Rtro-rfrences dans les expressions rationnelles

chappement

Description

\m

(o m est un chiffre diffrent de zro) rfrence la m-ime sous-expression

\mnn

(o m est un chiffre diffrent de zro et nn quelques chiffres supplmentaires, et la valeur dcimale


mnn n'est pas plus grande que le nombre de parenthses fermantes capturantes vues jusque l) rfrence la mnn-ime sous-expression

Note
Une ambigut persiste entre les chappements de caractre octal et les rtro-rfrences. Cette ambigut est rsolue
par les heuristiques suivantes, comme montr ci-dessus. Un zro en dbut de chane indique toujours un chappement octal. Un caractre seul diffrent de zro, qui n'est pas suivi d'un autre caractre, est toujours pris comme une
rtro-rfrence. Une squence plusieurs chiffres qui ne dbute pas par zro est prise comme une rfrence si elle
suit une sous-expression utilisable (c'est--dire que le nombre est dans la plage autorise pour les rtro-rfrences).
Dans le cas contraire, il est pris comme nombre octal.

9.7.3.4. Mtasyntaxe des expressions rationnelles


En plus de la syntaxe principale dcrite ci-dessus, il existe quelques formes spciales et autres possibilits syntaxiques.
Une ER peut commencer avec un des deux prfixes director spciaux. Si une ER commence par ***:, le reste de l'ER est considr comme une ERA. (Ceci n'a normalement aucun effet dans PostgreSQL car les ER sont supposes tre des ERA mais il a
un effet si le mode ERE ou BRE a t spcifi par le paramtre flags une fonction d'expression rationnelle.) Si une ER commence par ***=, le reste de l'ER est considr comme une chane littrale, tous les caractres tant considrs ordinaires.
Une ERA peut dbuter par des options intgres : une squence (?xyz) (o xyz correspond un ou plusieurs caractres alphabtiques) spcifie les options affectant le reste de l'ER. Ces options surchargent toutes les options prcdemment dtermines -- en
particulier, elles peuvent surcharger le comportement sur la sensibilit la casse d'un oprateur d'une ER ou le paramtre flags
vers une fonction d'expression rationnelle. Les lettres d'options disponibles sont indiques dans le Tableau 9.19, Lettres d'option
intgres une ERA . Notez que ces mmes lettres d'option sont utilises dans les paramtres flags des fonctions d'expressions
rationnelles.
143

Fonctions et oprateurs

Tableau 9.19. Lettres d'option intgres une ERA

Option

Description

le reste de l'ER est une ERB

activation de la sensibilit la casse (surcharge l'oprateur type)

le reste de l'ER est une ERE

dsactivation de la sensibilit la casse (voir la Section 9.7.3.5, Rgles de correspondance des expressions rationnelles ) (surcharge l'oprateur type)

synonyme historique pour n

activation de la sensibilit aux nouvelles lignes (voir la Section 9.7.3.5, Rgles de correspondance
des expressions rationnelles )

activation de la sensibilit partielle aux nouvelles lignes (voir la Section 9.7.3.5, Rgles de correspondance des expressions rationnelles )

le reste de l'ER est une chane littrale ( entre guillemets ), compos uniquement de caractres ordinaires

dsactivation de la sensibilit aux nouvelles lignes (par dfaut)

syntaxe compacte (par dfaut ; voir ci-dessous)

activation de la sensibilit partielle inverse aux nouvelles lignes ( trange ) (voir la Section 9.7.3.5,
Rgles de correspondance des expressions rationnelles )

syntaxe tendue (voir ci-dessous)

Les options intgres prennent effet la ) qui termine la squence. Elles ne peuvent apparatre qu'au dbut d'une ERA (aprs le
directeur ***: s'il y en a un).
En plus de la syntaxe habituelle d'une ER (compacte), dans laquelle tous les caractres ont une signification, il existe une syntaxe
tendue, accessible en signifiant l'option intgre x. Avec la syntaxe tendue, les caractres espace dans l'ER sont ignors comme
le sont tous les caractres entre un # et le retour-chariot qui suit (ou la fin de l'ER). Ceci permet de mettre en paragraphe et de
commenter une ER complexe. Il existe trois exceptions cette rgle de base :

un caractre espace ou # suivi d'un \ est retenu

un caractre espace ou # l'intrieur d'une expression entre crochets est retenu

caractre espace et commentaires ne peuvent pas apparatre dans les symboles multi-caractres, tels que (?:

Pour cela, les caractres espace sont l'espace, la tabulation, le retour chariot et tout caractre appartenant la classe de caractre
space.
Enfin, dans une ERA, en dehors d'expressions entre crochets, la squence (?#ttt) (o ttt est tout texte ne contenant pas )) est
un commentaire, totalement ignor. L encore, cela n'est pas permis entre les caractres des symboles multi-caractres comme
(?:. De tels commentaires sont plus un artefact historique qu'une fonctionnalit utile et leur utilisation est obsolte ; on utilise
plutt la syntaxe tendue.
Aucune de ces extensions mtasyntaxique n'est disponible si un directeur initial ***= indique que la saisie utilisateur doit tre
traite comme une chane littrale plutt que comme une ER.

9.7.3.5. Rgles de correspondance des expressions rationnelles


Dans l'hypothse o une ER peut correspondre plusieurs sous-chanes d'une chane donne, l'ER correspond celle qui apparat
la premire dans la chane. Si l'ER peut correspondre plusieurs sous-chanes partir de ce point, c'est soit la correspondance la
plus longue possible, soit la correspondance la plus courte possible, qui est retenue selon que l'ER est gourmande ou nongourmande (greedy/non-greedy).
La gourmandise d'une ER est dtermine par les rgles suivantes :

la plupart des atomes, et toutes les contraintes, n'ont pas d'attribut de gourmandise (parce qu'ils ne peuvent, en aucune faon,
tablir de correspondance avec des quantits variables de texte) ;

l'ajout de parenthses autour d'une ER ne change pas sa gourmandise ;

un atome quantifi avec un quantificateur rptition fixe ({m} ou {m}?) a la mme gourmandise (ventuellement aucune)
144

Fonctions et oprateurs

que l'atome lui-mme ;

un atome quantifi avec d'autres quantificateurs standard (dont {m,n} avec m gal n) est gourmand (prfre la plus grande
correspondance) ;

un atome quantifi avec un quantificateur non gourmand (dont {m,n}? avec m gal n) n'est pas gourmand (prfre la plus
courte correspondance) ;

une branche -- c'est--dire une ER dpourvue d'oprateur | au sommet -- est aussi gourmande que le premier atome quantifi
qu'elle contient qui possde un attribut de gourmandise ;

une ER constitue au minimum de deux branches connectes par l'oprateur | est toujours gourmande.

Les rgles ci-dessus associent les attributs de gourmandise non seulement avec les atomes quantifis individuels, mais aussi avec
les branches et les ER compltes qui contiennent des atomes quantifis. Cela signifie que la correspondance est tablie de sorte
que la branche, ou l'ER complte, corresponde la sous-chane la plus longue ou la plus courte possible comme un tout. Une fois
la longueur de la correspondance complte dtermine, la partie de cette correspondance qui tablit une correspondance avec une
sous-expression particulire est dtermine sur la base de l'attribut de gourmandise de cette sous-expression, priorit tant donne
aux sous-expressions commenant le plus tt dans l'ER.
Exemple de signification de tout cela :
SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
Resultat : 123
SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
Resultat : 1
Dans le premier cas, l'ER dans son intgralit est gourmande parce que Y* est gourmand. Il peut tablir une correspondance qui
dbute Y et correspondre la chane la plus longue partir de l, soit Y123. La sortie reprend la partie entre parenthses, soit
123. Dans le second cas, l'ER dans son ensemble n'est pas gourmande car Y*? ne l'est pas. Il peut tablir une correspondance qui
dbute Y et correspond la chane la plus courte partir de l, soit Y1. La sous-expression [0-9]{1,3} est gourmande mais
elle ne peut pas changer la dcision sur la longueur totale de la correspondance ; elle ne peut donc correspondre qu' 1.
En rsum, quand une ER contient la fois des sous-expressions gourmandes et non gourmandes, la longueur de la correspondance totale est soit aussi longue que possible soit aussi courte que possible, en fonction de l'attribut affect l'ER complte. Les
attributs assigns aux sous-expressions permettent uniquement de dterminer la partie de la correspondance qu'elles peuvent incorporer les unes par rapport aux autres.
Les quantificateurs {1,1} et {1,1}? peuvent tre utiliss pour forcer, respectivement, la prfrence la plus longue
(gourmandise) ou la plus courte (retenue), sur une sous-expression ou une ER complte.
Les longueurs de correspondance sont mesurs en caractres, et non en lments d'interclassement. Une chane vide est considre
plus grande que pas de correspondance du tout. Par exemple : bb* correspond aux trois caractres du milieu de abbbc ;
(week|wee)(night|knights) correspond aux dix caractres de weeknights ; lorsque une correspondance est recherche entre (.*).* et abc, la sous-expression entre parenthses correspond aux trois caractres ; et lorsqu'une correspondance
est recherche entre (a*)* et bc, la fois l'ER et la sous-expression entre parenthses correspondent une chane vide.
Lorsqu'il est prcis que la recherche de correspondance ne tient pas compte de la casse, cela revient considrer que toutes les
distinctions de casse ont disparu de l'alphabet. Quand un caractre alphabtique, pour lequel existent diffrentes casses, apparat
comme un caractre ordinaire en dehors d'une expression entre crochets, il est en fait transform en une expression entre crochets
contenant les deux casses, c'est--dire que x devient [xX]. Quand il apparat dans une expression entre crochets, toutes les transformations de casse sont ajoutes l'expression entre crochets, c'est--dire que [x] devient [xX] et que [^x] devient [^xX].
Si la sensibilit aux retours chariots est prcise, . et les expressions entre crochets utilisant ^ n'tablissent jamais de correspondance avec le caractre de retour la ligne (de cette faon, les correspondances ne franchissent jamais les retours chariots sauf si
l'ER l'explicite), et ^ et $ tablissent une correspondance avec la chane vide, respectivement aprs et avant un retour chariot, en
plus d'tablir une correspondance respectivement au dbut et la fin de la chane. Mais les chappements d'ERA \A et \Z
n'tablissent toujours de correspondance qu'au dbut ou la fin de la chane.
Si une sensibilit partielle aux retours chariot est indique, cela affecte . et les expressions entre crochets, comme avec la sensibilit aux retours chariot, mais pas ^ et $.
Si une sensibilit partielle inverse aux retours chariot est indique, cela affecte ^ et $, comme avec la sensibilit aux retours chariot, mais pas . et les sous-expressions. Ceci n'est pas trs utile mais est toutefois fourni pour des raisons de symtrie.

9.7.3.6. Limites et compatibilit


Aucune limite particulire n'est impose sur la longueur des ER dans cette implantation. Nanmoins, les programmes prvus pour
tre portables ne devraient pas employer d'ER de plus de 256 octets car une implantation POSIX peut refuser d'accepter de telles
145

Fonctions et oprateurs

ER.
La seule fonctionnalit des ERA qui soit incompatible avec les ERE POSIX est le maintien de la signification spciale de \ dans
les expressions entre crochets. Toutes les autres fonctionnalits ERA utilisent une syntaxe interdite, effets indfinis ou non spcifis dans les ERE POSIX ; la syntaxe *** des directeurs ne figure pas dans la syntaxe POSIX pour les ERB et les ERE.
Un grand nombre d'extensions ERA sont empruntes Perl mais certaines ont t modifies et quelques extensions Perl ne sont
pas prsentes. Les incompatibilits incluent \b, \B, le manque de traitement spcial pour le retour la ligne en fin de chane,
l'ajout d'expressions entre crochets aux expressions affectes par les correspondances avec retour la ligne, les restrictions sur les
parenthses et les rfrences dans les contraintes et la smantique de correspondance chanes les plus longues/les plus courtes (au
lieu de la premire rencontre).
Deux incompatibilits importantes existent entre les syntaxes ERA et ERE reconnues par les versions antrieures
PostgreSQL 7.4 :

dans les ERA, \ suivi d'un caractre alphanumrique est soit un chappement soit une erreur alors que dans les versions prcdentes, c'tait simplement un autre moyen d'crire un caractre alphanumrique. Ceci ne devrait pas poser trop de problmes
car il n'y avait aucune raison d'crire une telle squence dans les versions plus anciennes ;

dans les ERA, \ reste un caractre spcial l'intrieur de [], donc un \ l'intrieur d'une expression entre crochets doit tre
crit \\.

9.7.3.7. Expressions rationnelles lmentaires


Les ERB diffrent des ERE par plusieurs aspects. Dans les BRE, |, + et ? sont des caractres ordinaires et il n'existe pas
d'quivalent pour leur fonctionnalit. Les dlimiteurs de frontires sont \{ et \}, avec { et } tant eux-mme des caractres ordinaires. Les parenthses pour les sous-expressions imbriques sont \( et \), ( et ) restent des caractres ordinaires. ^ est un caractre ordinaire sauf au dbut d'une ER ou au dbut d'une sous-expression entre parenthses, $ est un caractre ordinaire sauf la
fin d'une ER ou la fin d'une sous-expression entre parenthses et * est un caractre ordinaire s'il apparat au dbut d'une ER ou
au dbut d'une sous-expression entre parenthses (aprs un possible ^). Enfin, les rtro-rfrences un chiffre sont disponibles, et
\< et \> sont des synonymes pour respectivement [[:<:]] et [[:>:]] ; aucun autre chappement n'est disponible dans les
BRE.

9.8. Fonctions de formatage des types de donnes


Les fonctions de formatage de PostgreSQL fournissent un ensemble d'outils puissants pour convertir diffrents types de donnes
(date/heure, entier, nombre virgule flottante, numrique) en chanes formates et pour convertir des chanes formates en types
de donnes spcifiques. Le Tableau 9.20, Fonctions de formatage les liste. Ces fonctions suivent toutes une mme convention
d'appel : le premier argument est la valeur formater et le second argument est un modle dfinissant le format de sortie ou
d'entre.
La fonction to_timestamp un argument est aussi disponible ; elle accepte un argument double precision unique pour convertir une valeur de type epoch Unix en timestamp with time zone (secondes depuis 1970-01-01 00:00:00+00) en timestamp with
time zone. (Les types epoch Unix (entier) sont implicitement convertis en double precision.)
Tableau 9.20. Fonctions de formatage

Fonction

Type en retour

to_char(timestamp, text
text)
to_char(interval,
text)

text

to_char(int, text) text

Description

Exemple

convertit un champ de type ti- to_char(current_timestamp,


mestamp en chane
'HH12:MI:SS')
convertit un champ de type in- to_char(interval
terval en chane
'15h 2m 12s', 'HH24:MI:SS')
convertit un champ de type in- to_char(125, '999')
teger en chane

to_char(double
precision, text)

text

convertit un champ de type to_char(125.8::real,


real/double precision en chane '999D9')

to_char(numeric,
text)

text

convertit un champ de type nu- to_char(-125.8, '999D99S')


meric en chane

to_date(text,
text)

date

convertit une chane en date

to_number(text,
text)

numeric

convertit une chane en champ to_number('12,454.8-',


de type numeric
'99G999D9S')
146

to_date('05
Dec
'DD Mon YYYY')

2000',

Fonctions et oprateurs

Fonction

Type en retour

Description

Exemple

to_timestamp(text, timestamp
text)
zone

with

time convertit une chane string en to_timestamp('05 Dec 2000',


champ de type timestamp
'DD Mon YYYY')

timestamp
pre- zone

with

time convertit une valeur de type to_timestamp(1284352323)


epoch UNIX en valeur de type
timestamp

(doubl
to_timestampe
cision)

Dans une chane de motif pour to_char, il existe certains motifs qui sont reconnus et remplacs avec des donnes correctement
formates bases sur la valeur. Tout texte qui n'est pas un motif est copi sans modification. De faon similaire, dans toute chane
de motif en entre (tout sauf to_char), les motifs identifient les valeurs fournir la chane de donnes en entre.
Le Tableau 9.21, Modles pour le formatage de champs de type date/heure affiche les motifs disponibles pour formater les valeurs de types date et heure.
Tableau 9.21. Modles pour le formatage de champs de type date/heure

Modle

Description

HH

heure du jour (01-12)

HH12

heure du jour (01-12)

HH24

heure du jour (00-23)

MI

minute (00-59)

SS

seconde (00-59)

MS

milliseconde (000-999)

US

microseconde (000000-999999)

SSSS

secondes coules depuis minuit (0-86399)

AM ou am ou PM ou pm

indicateur du mridien (sans point)

A.M. ou a.m.
P.M. ou p.m.

ou indicateur du mridien (avec des points)

am ou a.m. ou pm ou indicateur du mridien (en minuscules)


p.m.
Y,YYY

anne (quatre chiffres et plus) avec virgule

YYYY

anne (quatre chiffres et plus)

YYY

trois derniers chiffres de l'anne

YY

deux derniers chiffres de l'anne

dernier chiffre de l'anne

IYYY

anne ISO (quatre chiffres ou plus)

IYY

trois derniers chiffres de l'anne ISO

IY

deux derniers chiffres de l'anne ISO

dernier chiffre de l'anne ISO

BC, bc, AD ou ad

indicateur de l're (sans point)

B.C., b.c., A.D. ou indicateur de l're (avec des points)


a.d.
MONTH

nom complet du mois en majuscules (espaces de compltement pour arriver neuf caractres)

Month

nom complet du mois en casse mixte (espaces de compltement pour arriver neuf caractres)

month

nom complet du mois en minuscules (espaces de compltement pour arriver neuf caractres)

MON

abrviation du nom du mois en majuscules (trois caractres en anglais, la longueur des versions localises peut varier)

Mon

abrviation du nom du mois avec la premire lettre en majuscule et les deux autres en minuscule (trois
caractres en anglais, la longueur des versions localises peut varier)

mon

abrviation du nom du mois en minuscules (trois caractres en anglais, la longueur des versions localises peut varier)
147

Fonctions et oprateurs

Modle

Description

MM

numro du mois (01-12)

DAY

nom complet du jour en majuscules (espaces de compltement pour arriver neuf caractres)

Day

nom complet du jour avec la premire lettre en majuscule et les deux autres en minuscule (espaces de
compltement pour arriver neuf caractres)

day

nom complet du jour en minuscules (espaces de compltement pour arriver neuf caractres)

DY

abrviation du nom du jour en majuscules (trois caractres en anglais, la longueur des versions localises peut varier)

Dy

abrviation du nom du jour avec la premire lettre en majuscule et les deux autres en minuscule (trois
caractres en anglais, la longueur des versions localises peut varier)

dy

abrviation du nom du jour en minuscules (trois caractres en anglais, la longueur des versions localises peut varier)

DDD

jour de l'anne (001-366)

IDDD

jour ISO de l'anne (001-371 ; le jour 1 de l'anne est le lundi de la premire semaine ISO.)

DD

jour du mois (01-31)

jour de la semaine du dimanche (1) au samedi (7)

ID

jour ISO de la semaine du lundi (1) au dimanche (7)

numro de semaine du mois, de 1 5 (la premire semaine commence le premier jour du mois)

WW

numro de la semaine dans l'anne, de 1 53 (la premire semaine commence le premier jour de
l'anne)

IW

numro ISO de la semaine dans l'anne (01 - 53 ; le premier jeudi de la nouvelle anne est dans la semaine 1)

CC

sicle (deux chiffres) (le 21 sicle commence le 1er janvier 2001)

Jour dans le calendrier Julien (nombre de jours depuis le 24 novembre -4714 minuit)

trimestre (ignor par to_date and to_timestamp)

RM

mois en majuscule en nombre romain (I-XII ; I tant janvier) (en majuscules)

rm

mois en minuscule en nombre romain (i-xii; i tant janvier) (en minuscules)

TZ

nom en majuscule du fuseau horaire (en majuscules)

tz

nom en minuscule du fuseau horaire (en minuscules)

Les modificateurs peuvent tre appliqus tous les motifs pour en changer le comportement. Par exemple, FMMonth est le motif
Month avec le modificateur FM. Le Tableau 9.22, Modificateurs de motifs pour le formatage des dates/heures affiche les modificateurs de motifs pour le formatage des dates/heures.
Tableau 9.22. Modificateurs de motifs pour le formatage des dates/heures

Modificateur

Description

prfixe FM

mode remplissage (Fill Mode) (supprime les espaces et les zros de compltion en FMMonth
fin)

Exemple

suffixe TH

suffixe du nombre ordinal en majuscules, c'est--dire 12TH

DDTH

suffixe th

suffixe du nombre ordinal en minuscules, c'est--dire 12th

DDth

prfixe FX

option globale de format fixe (voir les notes d'utilisation)

FX Month DD D
ay

prfixe TM

mode de traduction (affiche les noms des jours et mois localiss en fonction de TMMonth
lc_time)

suffixe SP

mode pel (Spell Mode) (non implant)

DDSP

Notes d'utilisation pour le formatage date/heure :

FM supprime les zros de dbut et les espaces de fin qui, autrement, sont ajouts pour fixer la taille du motif de sortie ; Dans
148

Fonctions et oprateurs

PostgreSQL, FM modifie seulement la prochaine spcification alors qu'avec Oracle, FM affecte toutes les spcifications suivantes et des modificateurs FM rpts bascule l'activation du mode de remplissage.

TM n'inclut pas les espaces de compltion en fin de chane ;

to_timestamp et to_date ignorent les espaces multiples de la chane en entre si l'option FX n'est pas utilise. Par
exemple, to_timestamp('2000
JUN', 'YYYY MON') fonctionne mais to_timestamp('2000
JUN',
'FXYYYY MON') renvoie une erreur car to_timestamp n'attend qu'une seule espace ; FX doit tre indiqu comme premier lment du modle.

il est possible d'insrer du texte ordinaire dans les modles to_char. il est alors littralement remis en sortie. Une souschane peut tre place entre guillemets doubles pour forcer son interprtation en tant que libell mme si elle contient des
mots cls de motif. Par exemple, dans '"Hello Year "YYYY', les caractres YYYY sont remplacs par l'anne mais l'Y
isol du mot Year ne l'est pas ; Dans to_date, to_number et to_timestamp, les chanes entre guillemets doubles
ignorent le nombre de caractres en entre contenus dans la chane, par exemple "XX" ignorent les deux caractres en entre.

pour afficher un guillemet double dans la sortie, il faut le faire prcder d'un antislash. '\"YYYY Month\"', par exemple.

la conversion YYYY d'une chane en champ de type timestamp ou date comporte une restriction avec les annes plus de
quatre chiffres. Il faut alors utiliser un modle ou un caractre non-numrique aprs YYYY, sans quoi l'anne est toujours interprte sur quatre chiffres. Par exemple, pour l'anne 20000 : to_date('200001131', 'YYYYMMDD') est interprt
comme une anne quatre chiffres ; il faut alors utiliser un sparateur non dcimal aprs l'anne comme
to_date('20000-1131', 'YYYY-MMDD') ou to_date('20000Nov31', 'YYYYMonDD') ;

dans les conversions de chane en timestamp ou date, le champ CC (sicle) est ignor s'il y a un champ YYY, YYYY ou Y,YYY.
Si CC est utilis avec YY ou Y, alors l'anne est calcule comme (CC-1)*100+YY ;

Une date de semaine ISO (distinct de la date grgorienne) peut tre passe to_timestamp et to_date de deux faons :

Anne, semaine et jour de la semaine. Par exemple, to_date('2006-42-4', 'IYYY-IW-ID') renvoie la date
2006-10-19. En cas d'omission du jour de la semaine, lundi est utilis.

Anne et jour de l'anne. Par exemple, to_date('2006-291', 'IYYY-IDDD') renvoie aussi 2006-10-19.

Essayer de construire une date en utilisant un mlange de champs de semaine ISO et de date grgorienne n'a pas de sens et renverra du coup une erreur. Dans le contexte d'une anne ISO, le concept d'un mois ou du jour d'un mois n'a pas de signification. Dans le contexte d'une anne grgorienne, la semaine ISO n'a pas de signification. Les utilisateurs doivent viter de
mixer les spcifications grgoriennes et les dates ISO.

les valeurs en millisecondes (MS) et microsecondes (US) dans une conversion de chane en champ de type timestamp sont utilises comme partie dcimale des secondes. Par exemple, to_timestamp('12:3', 'SS:MS') n'est pas 3 millisecondes
mais 300 car la conversion le compte comme 12 + 0,3 secondes. Cela signifie que pour le format SS:MS, les valeurs d'entre
12:3, 12:30 et 12:300 indiquent le mme nombre de millisecondes. Pour obtenir trois millisecondes, il faut crire
12:003 que la conversion compte comme 12 + 0,003 = 12,003 secondes.
Exemple plus complexe : to_timestamp('15:12:02.020.001230', 'HH:MI:SS.MS.US') reprsente 15
heures, 12 minutes et (2 secondes + 20 millisecondes + 1230 microsecondes =) 2,021230 secondes ;

la numrotation du jour de la semaine de to_char(..., 'ID') correspond la fonction extract(isodow from


...) mais to_char(..., 'D') ne correspond pas la numration des jours de extract(dow from ...).

to_char(interval) formate HH et HH12 comme indiqu dans une horloge sur 12 heures, c'est--dire que l'heure 0 et
l'heure 36 sont affiches 12, alors que HH24 affiche la valeur heure complte, qui peut mme dpasser 23 pour les

Le Tableau 9.23, Motifs de modle pour le formatage de valeurs numriques affiche les motifs de modle disponibles pour le
formatage des valeurs numriques.
Tableau 9.23. Motifs de modle pour le formatage de valeurs numriques

Motif

Description

valeur avec le nombre indiqu de chiffres

valeur avec des zros de dbut de chane

. (point)

point dcimal

, (virgule)

sparateur de groupe (milliers)

PR

valeur ngative entre chevrons


149

Fonctions et oprateurs

Motif

Description

signe accroch au nombre (utilise la locale)

symbole montaire (utilise la locale)

point dcimal (utilise la locale)

sparateur de groupe (utilise la locale)

MI

signe moins dans la position indique (si le nombre est infrieur 0)

PL

signe plus dans la position indique (si le nombre est suprieur 0)

SG

signe plus/moins dans la position indique

RN

numro romain (saisie entre 1 et 3999)

TH ou th

suffixe du nombre ordinal

dcalage du nombre indiqu de chiffres (voir les notes)

EEEE

exposant pour la notation scientifique

Notes d'utilisation pour le formatage des nombres :

un signe format l'aide de SG, PL ou MI n'est pas ancr au nombre ; par exemple, to_char(-12, 'S9999') produit
' -12' mais to_char(-12, 'MI9999') produit '- 12'. L'implantation Oracle n'autorise pas l'utilisation de MI
devant 9, mais requiert plutt que 9 prcde MI ;

9 est transform en valeur avec le mme nombre de chiffres qu'il y a de 9. Si un chiffre n'est pas disponible, il est remplac par
une espace ;

TH ne convertit pas les valeurs infrieures zro et ne convertit pas les nombres fractionnels ;

PL, SG et TH sont des extensions PostgreSQL ;

V multiplie effectivement les valeurs en entre par 10^n, o n est le nombre de chiffres qui suit V. to_char ne supporte pas
l'utilisation de V combin avec un point dcimal (donc 99.9V99 n'est pas autoris).

EEEE (notation scientifique) ne peut pas tre utilis en combinaison avec un des autres motifs de formatage ou avec un autre
modificateur, en dehors des motifs chiffre et de point dcimal, et doit tre plac la fin de la chane de format (par exemple,
9.99EEEE est valide).

Certains modificateurs peuvent tre appliqus un motif pour modifier son comportement. Par exemple, FM9999 est le motif
9999 avec le modificateur FM. Tableau 9.24, Modifications de motifs pour le formatage numrique affiche les motifs pour le
formatage numrique.
Tableau 9.24. Modifications de motifs pour le formatage numrique

Modificateur

Description

Exemple

prfixe FM

mode de remplissage (supprime les blancs FM9999


et zros en fin de chane)

suffixe TH

suffixe d'un nombre ordinal en majuscule 999TH

suffixe th

suffixe d'un nombre ordinal en minuscule 999th

Le Tableau 9.25, Exemples avec to_char affiche quelques exemples de l'utilisation de la fonction to_char.
Tableau 9.25. Exemples avec to_char

Expression
to_char(current_timestamp, 'Day, DD

Rsultat
HH12:MI:SS')

to_char(current_timestamp, 'FMDay, FMDD

HH12:MI:SS')

'Tuesday

'Tuesday, 6

to_char(-0.1, '99.99')

'

to_char(-0.1, 'FM9.99')

'-.1'

to_char(0.1, '0.9')

' 0.1'

to_char(12, '9990999.9')

'
150

, 06

-.10'

0012.0'

05:39:18'

05:39:18'

Fonctions et oprateurs

Expression

Rsultat

to_char(12, 'FM9990999.9')

'0012.'

to_char(485, '999')

' 485'

to_char(-485, '999')

'-485'

to_char(485, '9 9 9')

' 4 8 5'

to_char(1485, '9,999')

' 1,485'

to_char(1485, '9G999')

' 1 485'

to_char(148.5, '999.999')

' 148.500'

to_char(148.5, 'FM999.999')

'148.5'

to_char(148.5, 'FM999.990')

'148.500'

to_char(148.5, '999D999')

' 148,500'

to_char(3148.5, '9G999D999')

' 3 148,500'

to_char(-485, '999S')

'485-'

to_char(-485, '999MI')

'485-'

to_char(485, '999MI')

'485 '

to_char(485, 'FM999MI')

'485'

to_char(485, 'PL999')

'+485'

to_char(485, 'SG999')

'+485'

to_char(-485, 'SG999')

'-485'

to_char(-485, '9SG99')

'4-85'

to_char(-485, '999PR')

'<485>'

to_char(485, 'L999')

'DM 485

to_char(485, 'RN')

'

to_char(485, 'FMRN')

'CDLXXXV'

to_char(5.2, 'FMRN')

'V'

to_char(482, '999th')

' 482nd'

to_char(485, '"Good number:"999')

'Good number: 485'

to_char(485.8, '"Pre:"999" Post:" .999')

'Pre: 485 Post: .800'

to_char(12, '99V999')

' 12000'

to_char(12.4, '99V999')

' 12400'

to_char(12.45, '99V9')

' 125'

to_char(0.0004859, '9.99EEEE')

' 4.86e-04'

CDLXXXV'

9.9. Fonctions et oprateurs sur date/heure


Le Tableau 9.27, Fonctions date/heure affiche les fonctions disponibles pour le traitement des valeurs date et heure. Les dtails
sont prsents dans les sous-sections qui suivent. Le Tableau 9.26, Oprateurs date/heure illustre les comportements des oprateurs arithmtiques basiques (+, *, etc.). Pour les fonctions de formatage, on peut se rfrer la Section 9.8, Fonctions de formatage des types de donnes . Il est important d'tre familier avec les informations de base concernant les types de donnes date/
heure de la Section 8.5, Types date/heure .
Toutes les fonctions et oprateurs dcrits ci-dessous qui acceptent une entre de type time ou timestamp acceptent deux variantes :
une avec time with time zone ou timestamp with time zone et une autre avec time without time zone ou timestamp without time
zone. Ces variantes ne sont pas affiches sparment. De plus, les oprateurs + et * sont commutatifs (par exemple, date + integer
et integer + date) ; une seule possibilit est prsente ici.
Tableau 9.26. Oprateurs date/heure

Oprateur

Exemple

Rsultat

date '2001-09-28' + integer '7'

date '2001-10-05'

151

Fonctions et oprateurs

Oprateur

Exemple

Rsultat

date '2001-09-28' + interval '1 hour' timestamp '2001-09-28 01:00:00'

date '2001-09-28' + time '03:00'

timestamp '2001-09-28 03:00:00'

interval '1 day' + interval '1 hour'

interval '1 day 01:00:00'

timestamp '2001-09-28 01:00' + inter- timestamp '2001-09-29 00:00:00'


val '23 hours'

time '01:00' + interval '3 hours'

time '04:00:00'

- interval '23 hours'

interval '-23:00:00'

date '2001-10-01' - date '2001-09-28' integer '3' (jours)

date '2001-10-01' - integer '7'

date '2001-09-28' - interval '1 hour' timestamp '2001-09-27 23:00:00'

time '05:00' - time '03:00'

interval '02:00:00'

time '05:00' - interval '2 hours'

time '03:00:00'

timestamp '2001-09-28 23:00' - inter- timestamp '2001-09-28 00:00:00'


val '23 hours'

interval '1 day' - interval '1 hour'

timestamp '2001-09-29 03:00' - times- interval '1 day 15:00:00'


tamp '2001-09-27 12:00'

900 * interval '1 second'

interval '00:15:00'

21 * interval '1 day'

interval '21 days'

double precision '3.5' * interval '1 interval '03:30:00'


hour'

interval '1 hour' / double precision interval '00:40:00'


'1.5'

date '2001-09-24'

interval '1 day -01:00:00'

Tableau 9.27. Fonctions date/heure

Fonction

Code de Description
retour

Exemple

Rsultat

age(timestamp, timestamp)

interval

Soustrait les arguments, ce


qui produit un rsultat
symbolique en annes,
mois, jours

age(timestamp
'2001-04-10',
timestamp
'1957-06-13')

43 years 9
mons
27
days

age(timestamp)

interval

Soustrait la date courante age(timestamp


(current_date minuit) '1957-06-13')

43 years 8
mons 3 days

clock_timestamp()

timestamp Date et heure courantes


with time (change pendant l'excution
zone
de l'instruction) ; voir la
Section 9.9.4, Date/Heure
courante

current_date

date

current_time

time with Heure courante ; voir la


time zone Section 9.9.4, Date/Heure
courante

current_timestamp

timestamp Date et heure courantes


with time (dbut de la transaction en
zone
cours) ; voir la Section 9.9.4, Date/Heure
courante

date_part(text, timestamp)

double

Date courante ; voir la Section 9.9.4, Date/Heure


courante

Obtenir
152

un

sous-champ date_part('hour' 20

Fonctions et oprateurs

Fonction

Code de Description
retour

Exemple

Rsultat

precision (quivalent extract) ; ,


timestamp
voir la Section 9.9.1, EX- '2001-02-16
TRACT, date_part
20:38:40')
date_part(text, interval)

double
Obtenir un sous-champ date_part('month 3
precision (quivalent extract) ; ', interval '2
voir la Section 9.9.1, EX- years 3 months')
TRACT, date_part

date_trunc(text, timestamp)

timestamp Tronquer la prcision indique ; voir aussi la Section


9.9.2,
date_trunc

date_trunc('hour 2001-02-16
',
timestamp 20:00:00
'2001-02-16
20:38:40')

extract(champ from timestamp) double


Obtenir un sous-champ ; extract(hour
20
precision voir la Section 9.9.1, EX- from
timestamp
TRACT, date_part
'2001-02-16
20:38:40')
extract(champ from interval)

double
Obtenir un sous-champ ; extract(month
3
precision voir la Section 9.9.1, EX- from interval '2
TRACT, date_part
years 3 months')

isfinite(date)

boolean

Test si la date est finie (donc isfinite(date


diffrent de +/-infinity)
'2001-02-16')

true

isfinite(timestamp)

boolean

Teste si l'estampille tempo- isfirelle est finie (donc diffrent nite(timestamp


de +/-infinity)
'2001-02-16
21:28:30')

true

isfinite(interval)

boolean

Teste si l'intervalle est fini

justify_days(interval)

interval

Ajuste l'intervalle pour que justi1


mon
les priodes de 30 jours fy_days(interval days
soient reprsentes comme '35 days')
des mois

justify_hours(interval)

interval

Ajuste l'intervalle pour que justify_hours(


1
day
les priodes de 24 heures interval
'27 03:00:00
soient reprsentes comme hours')
des jours

justify_interval(interval)

interval

Ajuste l'intervalle en utilisant justify_days et


justify_hours,
avec
des signes supplmentaires
d'ajustement

localtime

time

Heure du jour courante ;


voir la Section 9.9.4,
Date/Heure courante

localtimestamp

timestamp Date et heure courantes


(dbut de la transaction) ;
voir la Section 9.9.4,
Date/Heure courante

now()

timestamp Date et heure courantes


with time (dbut de la transaction) ;
zone
voir la Section 9.9.4,
Date/Heure courante

statement_timestamp()

timestamp Date et heure courantes


with time (dbut de l'instruction en
zone
cours) ; voir Section 9.9.4,
Date/Heure courante
153

isfitrue
nite(interval '4
hours')
5

justi29
days
fy_interval(inte 23:00:00
rval '1 mon -1
hour')

Fonctions et oprateurs

Fonction

Code de Description
retour

timeofday()

text

transaction_timestamp()

timestamp Date et heure courantes


with time (dbut de la transaction en
zone
cours) ; voir Section 9.9.4,
Date/Heure courante

Exemple

Rsultat

Date et heure courantes


(comme
clock_timestamp mais
avec une chane de type
text) ; voir la Section 9.9.4,
Date/Heure courante

En plus de ces fonctions, l'oprateur SQL OVERLAPS est support :


( dbut1, fin1 ) OVERLAPS ( dbut2, fin2 )
( dbut1, longueur1 ) OVERLAPS ( dbut2, longueur2 )
Cette expression renvoie vrai (true) lorsque les deux priodes de temps (dfinies par leurs extrmits) se chevauchent, et faux dans
le cas contraire. Les limites peuvent tre indiques comme des paires de dates, d'heures ou de timestamps ; ou comme une date,
une heure ou un timestamp suivi d'un intervalle. Quand une paire de valeur est fournie, soit le dbut soit la fin doit tre crit en
premier ; OVERLAPS prend automatiquement la valeur la plus ancienne dans la paire comme valeur de dpart. Chaque priode de
temps est considr reprsentant l'intervalle moiti ouvert dbut1 <= longueur1 < fin2, sauf si dbut1 et fin2 sont
identiques, auquel cas ils reprsentent une instant prcis. Cela signifie en fait que deux priodes de temps avec seulement un point
final en commun ne se surchargent pas.
SELECT (DATE '2001-02-16',
(DATE '2001-10-30',
Rsultat :
true
SELECT (DATE '2001-02-16',
(DATE '2001-10-30',
Rsultat :
false
SELECT (DATE '2001-10-29',
(DATE '2001-10-30',
Rsultat : false
SELECT (DATE '2001-10-30',
(DATE '2001-10-30',
Result: true

DATE '2001-12-21') OVERLAPS


DATE '2002-10-30');
INTERVAL '100 days') OVERLAPS
DATE '2002-10-30');
DATE '2001-10-30') OVERLAPS
DATE '2001-10-31');
DATE '2001-10-30') OVERLAPS
DATE '2001-10-31');

Lors de l'ajout (ou de la soustraction) d'une valeur de type interval une valeur de type timestamp with time zone, le composant
jours incrmente (ou dcremente) la date du timestamp with time zone du nombre de jours indiqus. Avec les modifications occasionnes par les changements d'heure (avec un fuseau horaire de session qui reconnat DST), cela signifie qu'un interval '1
day' n'est pas forcment gal un interval '24 hours'. Par exemple, avec un fuseau horaire configur CST7CDT, timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' produit un timestamp with
time zone '2005-04-03 12:00-06' alors qu'ajouter interval '24 hours' au timestamp with time zone initial
produit un timestamp with time zone '2005-04-03 13:00-06' parce qu'il y a un changement d'heure le
2005-04-03 02:00 pour le fuseau horaire CST7CDT.
Il peut y avoir une ambigut dans le nombre de months retourns par age car les mois n'ont pas tous le mme nombre de jours.
L'approche de PostgreSQL utilise le mois de la date la plus ancienne lors du calcul de mois partiels. Par exemple,
age('2004-06-01', '2004-04-30') utilise avril pour ramener 1 mon 1 day, alors qu'utiliser mai aurait ramener 1
mon 2 days car mai a 31 jours alors qu'avril n'en a que 30.

9.9.1. EXTRACT, date_part


EXTRACT (champ FROM source)
La fonction extract rcupre des sous-champs de valeurs date/heure, tels que l'anne ou l'heure. source est une expression de
valeur de type timestamp, time ou interval. (Les expressions de type date sont converties en timestamp et peuvent aussi tre utilises.) champ est un identifiant ou une chane qui slectionne le champ extraire de la valeur source. La fonction extract renvoie des valeurs de type double precision. La liste qui suit prsente les noms de champs valides :
century
154

Fonctions et oprateurs

Le sicle.
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
Rsultat : 20
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 21
Le premier sicle commence le 1er janvier de l'an 1 (0001-01-01 00:00:00 AD) bien qu'ils ne le savaient pas cette poque.
Cette dfinition s'applique tous les pays qui utilisent le calendrier Grgorien. Le sicle 0 n'existe pas. On passe de -1 sicle
1 sicle. En cas de dsaccord, adresser une plainte : Sa Saintet le Pape, Cathdrale Saint-Pierre de Rome, Vatican.
Les versions de PostgreSQL antrieures la 8.0 ne suivaient pas la numrotation conventionnelle des sicles mais renvoyaient uniquement le champ anne divise par 100.
day
Pour les valeurs de type timestamp, le champ du jour (du mois), donc entre 1 et 31 ; pour les valeurs de type interval, le
nombre de jours
SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 16
SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute');
Result: 40
decade
Le champ anne divis par 10.
SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 200
dow
Le jour de la semaine du dimanche (0) au samedi (6).
SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 5
Cette numrotation du jour de la semaine est diffrente de celle de la fonction to_char(..., 'D').
doy
Le jour de l'anne (de 1 365/366).
SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 47
epoch
Pour les valeurs de type date et timestamp, le nombre de secondes depuis le 1er janvier 1970 (exactement depuis le
1970-01-01 00:00:00 UTC). Ce nombre peut tre ngatif. Pour les valeurs de type interval, il s'agit du nombre total de secondes dans l'intervalle.
SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08');
Rsultat :
982384720.12
SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
Rsultat :
442800
Convertir une valeur epoch en valeur de type date/heure :
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 982384720.12 * INTERVAL '1 second';
(La fonction to_timestamp encapsule la conversion ci-dessus.)
hour
Le champ heure (0 - 23).
SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 20
isodow
155

Fonctions et oprateurs

Le jour de la semaine du lundi (1) au dimanche (7).


SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');
Rsultat : 7
Ceci est identique dow sauf pour le dimanche. Cela correspond la numrotation du jour de la semaine suivant le format
ISO 8601.
isoyear
L'anne ISO 8601 dans laquelle se trouve la date (non applicable aux intervalles).
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01');
Rsultat : 2005
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02');
Rsultat : 2006
Chaque anne ISO commence avec le lundi de la semaine contenant le 4 janvier, donc soit dbut janvier, soit fin dcembre.
L'anne ISO peut tre diffrente de l'anne grgorienne. Voir le champ week pour plus d'informations.
Ce champ n'est disponible que depuis la version 8.3 de PostgreSQL.
microseconds
Le champ secondes, incluant la partie dcimale, multipli par 1 000 000. Cela inclut l'intgralit des secondes.
SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5');
Rsultat :
28500000
millennium
Le millnaire.
SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 3
Les annes 1900 sont dans le second millnaire. Le troisime millnaire commence le 1er janvier 2001.
Les versions de PostgreSQL antrieures la 8.0 ne suivaient pas les conventions de numrotation des millnaires mais renvoyaient seulement le champ anne divis par 1000.
milliseconds
Le champ secondes, incluant la partie dcimale, multipli par 1000. Cela inclut l'intgralit des secondes.
SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5');
Rsultat :
28500
minute
Le champ minutes (0 - 59).
SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 38
month
Pour les valeurs de type timestamp, le numro du mois dans l'anne (de 1 12) ; pour les valeurs de type interval, le nombre
de mois, modulo 12 (0 - 11).
SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 2
SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
Rsultat : 3
SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
Rsultat : 1
quarter
Le trimestre (1 - 4) dont le jour fait partie.
SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40');
156

Fonctions et oprateurs

Rsultat : 1
second
Le champs secondes, incluant la partie dcimale (0 - 591).
SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 40
SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
Rsultat :
28.5
timezone
Le dcalage du fuseau horaire depuis UTC, mesur en secondes. Les valeurs positives correspondent aux fuseaux horaires
l'est d'UTC, les valeurs ngatives l'ouest d'UTC. (Techniquement, PostgreSQL utilise UT1 plutt que UTC car les secondes intercalaires ne sont pas gres.)
timezone_hour
Le composant heure du dcalage du fuseau horaire.
timezone_minute
Le composant minute du dcalage du fuseau horaire.
week
Le numro de la semaine dans l'anne, laquelle appartient le jour. Par dfinition (ISO 8601), les semaines commencent le
lundi et la premire semaine d'une anne contient le 4 janvier de cette anne. Autrement dit, le premier jeudi d'une anne se
trouve dans la premire semaine de cette anne.
Dans la dfinition ISO, il est possible que les premiers jours de janvier fassent partie de la semaine 52 ou 53 de l'anne prcdente. Il est aussi possibles que les derniers jours de dcembre fassent partie de la premire semaine de l'anne suivante. Par
exemple, 2005-01-01 fait partie de la semaine 53 de l'anne 2004 et 2006-01-01 fait partie de la semaine 52 de l'anne
2005, alors que 2012-12-31 fait partie de la premire semaine de 2013. Il est recommand d'utiliser le champ isoyear
avec week pour obtenir des rsultats cohrents.
SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 7
year
Le champ anne. Il n'y a pas de 0 AD, la soustraction d'annes BC aux annes AD ncessite donc une attention particulire.
SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40');
Rsultat :
2001
La fonction extract a pour but principal l'excution de calculs. Pour le formatage des valeurs date/heure en vue de leur affichage, voir la Section 9.8, Fonctions de formatage des types de donnes .
La fonction date_part est modele sur l'quivalent traditionnel Ingres de la fonction extract du standard SQL :
date_part('champ', source)
Le paramtre champ est obligatoirement une valeur de type chane et non pas un nom. Les noms de champ valide pour
date_part sont les mmes que pour extract.
SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 16
SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
Rsultat : 4

9.9.2. date_trunc
La fonction date_trunc est conceptuellement similaire la fonction trunc pour les nombres.
date_trunc('champ', source)
source est une expression de type timestamp ou interval. (Les valeurs de type date et time sont converties automatiquement en,
1

60 si les secondes d'ajustement (leap second) sont implantes par le systme d'exploitation.

157

Fonctions et oprateurs

respectivement, timestamp ou interval). champ indique la prcision avec laquelle tronquer la valeur en entre. La valeur de retour
est de type timestamp ou interval avec tous les champs moins significatifs que celui slectionn positionns zro (ou un pour la
date et le mois).
Les valeurs valides pour champ sont :
microseconds
milliseconds
second
minute
hour
day
week
month
quarter
year
decade
century
millennium
Exemples :
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 2001-02-16
20:00:00
SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
Rsultat : 2001-01-01
00:00:00

9.9.3. AT TIME ZONE


La construction AT TIME ZONE permet les conversions d' estampilles temporelles (time stamps) dans les diffrents fuseaux
horaires. Le Tableau 9.28, Variantes AT TIME ZONE affiche ses variantes.
Tableau 9.28. Variantes AT TIME ZONE

Expression

Type de retour Description

timestamp without time zone AT TIME timestamp with Traite l'estampille donne without time zone (sans fuZONE zone
time zone
seau), comme situe dans le fuseau horaire indiqu.
timestamp with time zone AT TIME ZONE timestamp wi- Convertit l'estampille donne with time zone (avec fuzone
thout time zone seau) dans le nouveau fuseau horaire, sans dsignation
du fuseau.
time with time zone AT TIME ZONE zone time with time Convertit l'heure donne with time zone (avec fuseau)
zone
dans le nouveau fuseau horaire.
Dans ces expressions, le fuseau horaire dsir zone peut tre indiqu comme une chane texte (par exemple, 'PST') ou comme
un intervalle (c'est--dire INTERVAL '-08:00'). Dans le cas textuel, un nom de fuseau peut tre indiqu de toute faon dcrite
dans Section 8.5.3, Fuseaux horaires .
Exemples (en supposant que le fuseau horaire local soit PST8PDT) :
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST';
Rsultat : 2001-02-16
19:38:40-08
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST';
Rsultat : 2001-02-16
18:38:40
Le premier exemple prend une estampille temporelle sans fuseau et l'interprte comme une date MST (UTC-7), qui est ensuite
convertie en PST (UTC-8) pour l'affichage. Le second exemple prend une estampille indique en EST (UTC-5) et la convertit en
heure locale, c'est--dire en MST (UTC-7).
La fonction timezone(zone, timestamp) est quivalente la construction conforme au standard SQL, timestamp AT
TIME ZONE zone.
158

Fonctions et oprateurs

9.9.4. Date/Heure courante


PostgreSQL fournit diverses fonctions qui renvoient des valeurs relatives aux date et heure courantes. Ces fonctions du standard
SQL renvoient toutes des valeurs fondes sur l'heure de dbut de la transaction en cours :
CURRENT_DATE ;
CURRENT_TIME ;
CURRENT_TIMESTAMP ;
CURRENT_TIME(precision) ;
CURRENT_TIMESTAMP(precision) ;
LOCALTIME ;
LOCALTIMESTAMP ;
LOCALTIME(precision) ;
LOCALTIMESTAMP(precision).
CURRENT_TIME et CURRENT_TIMESTAMP dlivrent les valeurs avec indication du fuseau horaire ; LOCALTIME et LOCALTIMESTAMP dlivrent les valeurs sans indication du fuseau horaire.
CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME, et LOCALTIMESTAMP acceptent un paramtre optionnel de prcision. Celui-ci permet d'arrondir le rsultat au nombre de chiffres indiqus pour la partie fractionnelle des secondes. Sans ce paramtre de prcision, le rsultat est donn avec toute la prcision disponible.
Quelques exemples :
SELECT CURRENT_TIME;
Rsultat :
14:39:53.662522-05
SELECT CURRENT_DATE;
Rsultat :
2001-12-23
SELECT CURRENT_TIMESTAMP;
Rsultat : 2001-12-23
14:39:53.662522-05
SELECT CURRENT_TIMESTAMP(2);
Rsultat : 2001-12-23
14:39:53.66-05
SELECT LOCALTIMESTAMP;
Rsultat : 2001-12-23
14:39:53.662522
Comme ces fonctions renvoient l'heure du dbut de la transaction en cours, leurs valeurs ne changent pas au cours de la transaction. Il s'agit d'une fonctionnalit : le but est de permettre une mme transaction de disposer d'une notion cohrente de l'heure
courante . Les multiples modifications au sein d'une mme transaction portent ainsi toutes la mme heure.

Note
D'autres systmes de bases de donnes actualisent ces valeurs plus frquemment.
PostgreSQL fournit aussi des fonctions qui renvoient l'heure de dbut de l'instruction en cours, voire l'heure de l'appel de la
fonction. La liste complte des fonctions ne faisant pas partie du standard SQL est :
transaction_timestamp()
statement_timestamp()
clock_timestamp()
timeofday()
now()
transaction_timestamp() est un peu l'quivalent de CURRENT_TIMESTAMP mais est nomm ainsi pour expliciter
l'information retourne. statement_timestamp() renvoie l'heure de dbut de l'instruction en cours (plus exactement, l'heure
de rception du dernier message de la commande en provenance du client). statement_timestamp() et transaction_timestamp() renvoient la mme valeur pendant la premire commande d'une transaction, mais leurs rsultats peuvent
diffrer pour les commandes suivantes. clock_timestamp() renvoie l'heure courante, et, de ce fait, sa valeur change mme
l'intrieur d'une commande SQL unique. timeofday() est une fonction historique de PostgreSQL. Comme
159

Fonctions et oprateurs

clock_timestamp(), elle renvoie l'heure courante, mais celle-ci est alors formate comme une chane text et non comme une
valeur de type timestamp with time zone. now() est l'quivalent traditionnel PostgreSQL de CURRENT_TIMESTAMP.
Tous les types de donnes date/heure acceptent aussi la valeur littrale spciale now pour indiquer la date et l'heure courantes
(interprts comme l'heure de dbut de la transaction). De ce fait, les trois instructions suivantes renvoient le mme rsultat :
SELECT CURRENT_TIMESTAMP;
SELECT now();
SELECT TIMESTAMP 'now'; -- utilisation incorrecte avec DEFAULT

Astuce
La troisime forme ne doit pas tre utilise pour la spcification de la clause DEFAULT la cration d'une table. Le
systme convertirait now en valeur de type timestamp ds l'analyse de la constante. chaque fois que la valeur par
dfaut est ncessaire, c'est l'heure de cration de la table qui est alors utilise. Les deux premires formes ne sont
pas values avant l'utilisation de la valeur par dfaut, il s'agit d'appels de fonctions. C'est donc bien le comportement attendu, l'heure d'insertion comme valeur par dfaut, qui est obtenu.

9.9.5. Retarder l'excution


La fonction suivante permet de retarder l'excution du processus serveur :
pg_sleep(seconds)
pg_sleep endort le processus de la session courante pendant seconds secondes. seconds est une valeur de type double precision, ce qui autorise les dlais en fraction de secondes. Par exemple :
SELECT pg_sleep(1.5);

Note
La rsolution relle de l'intervalle est spcifique la plateforme ; 0,01 seconde est une valeur habituelle. Le dlai
dure au minimum celui prcis. Il peut toutefois tre plus long du fait de certains facteurs tels que la charge serveur.

Avertissement
Il convient de s'assurer que la session courante ne dtient pas plus de verrous que ncessaires lors de l'appel
pg_sleep. Dans le cas contraire, d'autres sessions peuvent tre amenes attendre que le processus de retard courant ne termine, ralentissant ainsi tout le systme.

9.10. Fonctions de support enum


Pour les types enum (dcrit dans Section 8.7, Types numration ), il existe plusieurs fonctions qui autorisent une programmation plus claire sans coder en dur les valeurs particulires d'un type enum. Elles sont listes dans Tableau 9.29, Fonctions de support enum . Les exemples supposent un type enum cr ainsi :
CREATE TYPE couleurs AS ENUM ('rouge', 'orange', 'jaune', 'vert', 'bleu', 'violet');
Tableau 9.29. Fonctions de support enum

Fonction

Description

enum_first(anyenum)

Renvoie la premire valeur du enum_first(null::coul rouge


type enum en entre
eurs)

Exemple

enum_last(anyenum)

Renvoie la dernire valeur du enum_last(null::coule violet


type enum en entre
urs)

enum_range(anyenum)

Renvoie toutes les valeurs du enum_range(null::coul {rouge,orange,jaune,v


type enum en entre dans un eurs)
ert,bleu,violet}
tableau tri

160

Rsultat de l'exemple

Fonctions et oprateurs

Fonction

Description

Exemple

Rsultat de l'exemple

enum_range(anyenum,
anyenum)

Renvoie les lments entre


deux valeurs enum donnes
dans un tableau tri. Les valeurs doivent tre du mme
type enum. Si le premier paramtre est NULL, le rsultat se
termine avec la dernire valeur
du type enum.

enum_range('orange':: {orange,jaune,vert}
couleurs,
'vert'::couleurs)
enum_range(NULL,
'vert'::couleurs)

{rouge,orange,jaune,v
ert}

enum_range('orange':: {orange,jaune,vert,bl
couleurs, NULL)
eu,violet}

En dehors de la forme deux arguments de enum_range, ces fonctions ne tiennent pas compte de la valeur qui leur est fournie ;
elles ne s'attachent qu'au type de donne dclar. NULL ou une valeur spcifique du type peut tre passe, le rsultat est le mme.
Il est plus commun d'appliquer ces fonctions la colonne d'une table ou l'argument d'une fonction qu' un nom de type en dur,
comme le suggrent les exemples.

9.11. Fonctions et oprateurs gomtriques


Les types gomtriques point, box, lseg, line, path, polygon et circle disposent d'un large ensemble de fonctions et oprateurs natifs. Ils sont lists dans le Tableau 9.30, Oprateurs gomtriques , le Tableau 9.31, Fonctions gomtriques et le Tableau 9.32, Fonctions de conversion de types gomtriques .

Attention
L'oprateur identique , ~=, reprsente la notion habituelle d'galit pour les types point, box, polygon et circle.
Certains disposent galement d'un oprateur =, mais = ne compare que les galits d'aires. Les autres oprateurs de
comparaison scalaires (<= et autres) comparent de la mme faon des aires pour ces types.
Tableau 9.30. Oprateurs gomtriques

Oprateur

Description

Exemple

Translation

box
'((0,0),(1,1))'
'(2.0,0)'

point

Translation

box
'((0,0),(1,1))'
'(2.0,0)'

point

Mise l'chelle/rotation

box
'((0,0),(1,1))'
'(2.0,0)'

point

Mise l'chelle/rotation

box
'((0,0),(2,2))'
'(2.0,0)'

point

Point ou bote d'intersection

'((1,-1),(-1,1))'
'((1,1),(-1,-1))'

Nombre de points dans le chemin ou le polygone

# '((1,0),(0,1),(-1,0))'

@-@

Longueur ou circonfrence

@-@ path '((0,0),(1,0))'

@@

Centre

@@ circle '((0,0),10)'

##

Point de la seconde oprande le plus proche de la point


'(0,0)'
premire
'((2,0),(0,2))'

##

<->

Distance entre

<->

&&

Recouvrement ? (Un point en commun renvoie la box


'((0,0),(1,1))'
valeur true.)
'((0,0),(2,2))'

<<

Est strictement gauche de ?

circle
'((0,0),1)'
'((5,0),1)'

<<

circle

>>

Est strictement droite de ?

circle
'((5,0),1)'
'((0,0),1)'

>>

circle

&<

Ne s'tend pas droite de ?

box
'((0,0),(1,1))'
'((0,0),(2,2))'

circle
'((0,0),1)'
'((5,0),1)'

161

lseg

&&

&<

circle
box

box

Fonctions et oprateurs

Oprateur

Description

Exemple

&>

Ne s'tend pas gauche de ?

box
'((0,0),(3,3))'
'((0,0),(2,2))'

&>

box

<<|

Est strictement en-dessous de ?

box
'((0,0),(3,3))'
'((3,4),(5,5))'

<<|

box

|>>

Est strictement au-dessus de ?

box
'((3,4),(5,5))'
'((0,0),(3,3))'

|>>

box

&<|

Ne s'tend pas au-dessus de ?

box
'((0,0),(1,1))'
'((0,0),(2,2))'

&<|

box

|&>

Ne s'tend pas en-dessous de ?

box
'((0,0),(3,3))'
'((0,0),(2,2))'

|&>

box

<^

Est en-dessous de (peut toucher) ?

circle
'((0,0),1)'
'((0,5),1)'

<^

circle

>^

Est au-dessus de (peut toucher) ?

circle
'((0,5),1)'
'((0,0),1)'

>^

circle

?#

Intersection ?

lseg
'((-1,0),(1,0))'
'((-2,-2),(2,2))'

?-

Horizontal ?

?- lseg '((-1,0),(1,0))'

?-

Sont aligns horizontalement ?

point '(1,0)' ?- point '(0,0)'

?|

Vertical ?

?| lseg '((-1,0),(1,0))'

?|

Sont verticalement aligns ?

point '(0,1)' ?| point '(0,0)'

?-|

Perpendiculaires ?

lseg
'((0,0),(0,1))'
'((0,0),(1,0))'

?-|

lseg

?||

Parallles ?

lseg '((-1,0),(1,0))'
'((-1,2),(1,2))'

?||

lseg

@>

Contient ?

circle
'(1,1)'

<@

Contenu ou dessus ?

point
'(1,1)'
'((0,0),2)'

~=

Identique ?

polygon '((0,0),(1,1))' ~= polygon


'((1,1),(0,0))'

'((0,0),2)'

?#

box

@>
<@

point
circle

Note
Avant PostgreSQL 8.2, les oprateurs @> et <@ s'appelaient respectivement ~ et @. Ces noms sont toujours disponibles mais, obsoltes, ils seront ventuellement supprims.
Tableau 9.31. Fonctions gomtriques

Fonction

Type de retour

Description

Exemple

area (object)

double precision

aire

area(box
'((0,0),(1,1))')

center (object)

point

centre

center(box
'((0,0),(1,2))')

diameter(circle)

double precision

diamtre du cercle

diameter(circle
'((0,0),2.0)')

height(box)

double precision

taille verticale (hauteur) de la height(box


bote
'((0,0),(1,1))')

isclosed(path)

boolean

chemin ferm ?

isclosed(path
'((0,0),(1,1),(2,0))'
)

isopen(path)

boolean

chemin ouvert ?

isopen(path

162

Fonctions et oprateurs

Fonction

Type de retour

Description

Exemple
'[(0,0),(1,1),(2,0)]'
)

length(object)

double precision

longueur

length(path
'((-1,0),(1,0))')

npoints(path)

int

nombre de points

npoints(path
'[(0,0),(1,1),(2,0)]'
)

npoints(polygon)

int

nombre de points

npoints(polygon
'((1,1),(0,0))')

pclose(path)

path

convertit un chemin en chemin pclose(path


ferm
'[(0,0),(1,1),(2,0)]'
)

popen(path)

path

convertit un chemin en chemin popen(path


ouvert
'((0,0),(1,1),(2,0))'
)

radius(circle)

double precision

rayon du cercle

width(box)

double precision

taille horizontale
d'une bote

radius(circle
'((0,0),2.0)')
(largeur) width(box
'((0,0),(1,1))')

Tableau 9.32. Fonctions de conversion de types gomtriques

Fonction

Type de retour

Description

Exemple

box(circle)

box

cercle vers bote

box(circle
'((0,0),2.0)')

circle(box)

box

points vers bote

box(point
'(0,0)',
point '(1,1)')

box(polygon)

box

polygone vers bote

box(polygon
'((0,0),(1,1),(2,0))'
)

circle(box)

circle

bote vers cercle

circle(box
'((0,0),(1,1))')

centre et rayon vers cercle

circle(point '(0,0)',
2.0)
circle(polygon
'((0,0),(1,1),(2,0))'
)

circle(point,
precision)

double circle

circle(polygon)

circle

polygone vers cercle

lseg(box)

lseg

diagonale de bote vers seg- lseg(box


ment de ligne
'((-1,0),(1,0))')

lseg(point, point)

lseg

points vers segment de ligne

lseg(point '(-1,0)',
point '(1,0)')

path(polygon)

path

polygone vers chemin

path(polygon
'((0,0),(1,1),(2,0))'
)

point de construction

point(23.4, -44.5)

point(double
sion, double
sion)

preci- point
preci-

point(box)

point

centre de la bote

point(box
'((-1,0),(1,0))')

point(circle)

point

centre du cercle

point(circle
'((0,0),2.0)')

point(lseg)

point

centre de segment de ligne

point(lseg
'((-1,0),(1,0))')

163

Fonctions et oprateurs

Fonction

Type de retour

Description

Exemple

point(polygon)

point

centre de polygone

point(polygon
'((0,0),(1,1),(2,0))'
)

polygon(box)

polygon

bote vers polygone quatre polygon(box


points
'((0,0),(1,1))')

polygon(circle)

polygon

cercle vers polygone 12 polygon(circle


points
'((0,0),2.0)')

polygon(npts, circle) polygon


polygon(path)

polygon

cercle vers polygone npts polygon(12,


circle
points
'((0,0),2.0)')
chemin vers polygone

polygon(path
'((0,0),(1,1),(2,0))'
)

Il est possible d'accder aux deux composants d'un point comme si c'tait un tableau avec des index 0 et 1. Par exemple, si t.p est
une colonne de type point, alors SELECT p[0] FROM t rcupre la coordonne X et UPDATE t SET p[1] = ... modifie la coordonne Y. De la mme faon, une valeur de type box ou lseg peut tre traite comme un tableau de deux valeurs de type
point.
La fonction area est utilisable avec les types box, circle et path. Elle ne fonctionne avec le type de donnes path que s'il n'y a pas
d'intersection entre les points du path. Le path '((0,0),(0,1),(2,1),(2,2),(1,2),(1,0),(0,0))'::PATH, par
exemple,
ne
fonctionne
pas.
Le
path,
visuellement
identique,
'((0,0),(0,1),(1,1),(1,2),(2,2),(2,1),(1,1),(1,0),(0,0))'::PATH, quant lui, fonctionne. Si les
concepts de path avec intersection et sans intersection sont sources de confusion, dessiner les deux path ci-dessus cte--cte.

9.12. Fonctions et oprateurs sur les adresses rseau


Le Tableau 9.33, Oprateurs cidr et inet affiche les oprateurs disponibles pour les types cidr et inet. Les oprateurs <<, <<=,
>> et >>= testent l'inclusion de sous-rseau. Ils ne considrent que les parties rseau des deux adresses, ignorant toute partie hte,
et dterminent si une partie rseau est identique ou consitue un sous-rseau de l'autre.
Tableau 9.33. Oprateurs cidr et inet

Oprateur

Description

Exemple

<

est plus petit que

inet '192.168.1.5' < inet '192.168.1.6'

<=

est plus petit que ou gal

inet '192.168.1.5' <= inet '192.168.1.5'

est gal

inet '192.168.1.5' = inet '192.168.1.5'

>=

est plus grand ou gal

inet '192.168.1.5' >= inet '192.168.1.5'

>

est plus grand que

inet '192.168.1.5' > inet '192.168.1.4'

<>

n'est pas gal

inet '192.168.1.5' <> inet '192.168.1.4'

<<

est contenu dans

inet '192.168.1.5' << inet '192.168.1/24'

<<=

est contenu dans ou gal

inet '192.168.1/24' <<= inet '192.168.1/24'

>>

contient

inet'192.168.1/24' >> inet '192.168.1.5'

>>=

contient ou est gal

inet '192.168.1/24' >>= inet '192.168.1/24'

bitwise NOT

~ inet '192.168.1.6'

&

bitwise AND

inet '192.168.1.6' & inet '0.0.0.255'

bitwise OR

inet '192.168.1.6' | inet '0.0.0.255'

addition

inet '192.168.1.6' + 25

soustraction

inet '192.168.1.43' - 36

soustraction

inet '192.168.1.43' - inet '192.168.1.19'

Le Tableau 9.34, Fonctions cidr et inet affiche les fonctions utilisables avec les types cidr et inet. Les fonctions abbrev,
host, text ont principalement pour but d'offrir des formats d'affichage alternatifs.
164

Fonctions et oprateurs

Tableau 9.34. Fonctions cidr et inet

Fonction

Type de retour

Description

Exemple

Rsultat

abbrev(inet)

text

format
textuel abbrev(inet
d'affichage raccourci
'10.1.0.0/16')

10.1.0.0/16

abbrev(cidr)

text

format
textuel abbrev(cidr
d'affichage raccourci
'10.1.0.0/16')

10.1/16

broadcast(inet)

inet

adresse de broadcast broad192.168.1.255/24


pour le rseau
cast('192.168.1.
5/24')

family(inet)

int

extraction de la famille family('::1')


d'adresse ; 4 pour IPv4,
6 pour IPv6

host(inet)

text

extraction de l'adresse IP host('192.168.1. 192.168.1.5


en texte
5/24')

hostmask(inet)

inet

construction du masque host0.0.0.3


d'hte pour le rseau
mask('192.168.23
.20/30')

masklen(inet)

int

extraction de la longueur mask24


du masque rseau
len('192.168.1.5
/24')

netmask(inet)

inet

construction du masque net255.255.255.0


rseau
mask('192.168.1.
5/24')

network(inet)

cidr

extraction de la partie r- net192.168.1.0/24


seau de l'adresse
work('192.168.1.
5/24')

set_masklen(inet inet
, int)

configure la longueur du set_masklen('192 192.168.1.5/16


masque rseau pour les .168.1.5/24',
valeurs inet
16)

(cidr
set_masklen,
int)

cidr

configure la longueur du set_masklen('192 192.168.0.0/16


masque rseau pour les .168.1.0/24'::ci
valeurs cidr
dr, 16)

text(inet)

text

extraction de l'adresse IP text(inet


et de la longueur du '192.168.1.5')
masque rseau comme
texte

192.168.1.5/32

Toute valeur cidr peut tre convertie en inet implicitement ou explicitement ; de ce fait, les fonctions indiques ci-dessus comme
oprant sur le type inet oprent aussi sur le type cidr. (Lorsque les fonctions sont spares pour les types inet et cidr, c'est que leur
comportement peut diffrer.) Il est galement permis de convertir une valeur inet en cidr. Dans ce cas, tout bit la droite du
masque rseau est silencieusement positionn zro pour crer une valeur cidr valide. De plus, une valeur de type texte peut tre
transtype en inet ou cidr l'aide de la syntaxe habituelle de transtypage : par exemple inet(expression) ou
nom_colonne::cidr.
Le Tableau 9.35, Fonctions macaddr affiche les fonctions utilsables avec le type macaddr. La fonction trunc(macaddr)
renvoie une adresse MAC avec les trois derniers octets initialiss zro. Ceci peut tre utilis pour associer le prfixe restant un
manufacturier.
Tableau 9.35. Fonctions macaddr

Fonction

Type de retour

Description

trunc(macaddr)

macaddr

initialiser les trois octets trunc(macaddr


12:34:56:00:00:0
finaux zro
'12:34:56:78:90: 0
ab')

165

Exemple

Rsultat

Fonctions et oprateurs

Le type macaddr supporte aussi les oprateurs relationnels standard (>, <=, etc.) de tri lexicographique.

9.13. Fonctions et oprateurs de la recherche plein texte


Tableau 9.36, Oprateurs de recherche plein texte , Tableau 9.37, Fonctions de la recherche plein texte et Tableau 9.38,
Fonctions de dbogage de la recherche plein texte rsume les fonctions et les oprateurs fournis pour la recherche plein texte.
Voir Chapitre 12, Recherche plein texte pour une explication dtaille sur la fonctionnalit de recherche plein texte de PostgreSQL.
Tableau 9.36. Oprateurs de recherche plein texte

Oprateur

Description

Exemple

Rsultat

@@

tsvector correspond tsquery ?

to_tsvector('fat cats t
ate
rats')
@@
to_tsquery('cat
&
rat')

@@@

synonym obsolte de @@

to_tsvector('fat cats t
ate
rats')
@@@
to_tsquery('cat
&
rat')

||

concatne tsvectors

'a:1
b:2'::tsvector 'a':1 'b':2,5 'c':3 'd':4
||
'c:1
d:2
b:3'::tsvector

&&

ET logique des tsquery

'fat | rat'::tsquery ( 'fat' | 'rat' ) & 'cat'


&& 'cat'::tsquery

||

OU logique des tsquery

'fat | rat'::tsquery ( 'fat' | 'rat' ) | 'cat'


|| 'cat'::tsquery

!!

inverse une tsquery

!! 'cat'::tsquery

@>

tsquery en contient une autre ?

'cat'::tsquery
@> f
'cat & rat'::tsquery

<@

tsquery est contenu dans ?

'cat'::tsquery
<@ t
'cat & rat'::tsquery

!'cat'

Note
Les oprateurs de confinement de tsquery considrent seulement les lexmes lists dans les deux requtes, ignorant
les oprateurs de combinaison.
En plus des oprateurs prsents dans la table, les oprateurs de comparaison B-tree habituels (=, <, etc) sont dfinis pour les
types tsvector et tsquery. Ils ne sont pas trs utiles dans le cadre de la recherche plein texte mais permettent la construction d'index
d'unicit sur ces types de colonne.
Tableau 9.37. Fonctions de la recherche plein texte

Fonction

Type de retour

Description

Exemple

Rsultat

get_current_ts_c regconfig
onfig()

rcupre la configuration get_current_ts_c english


par dfaut de la re- onfig()
cherche plein texte

length(tsvector) integer

nombre de lexemes dans length('fat:2,4 3


tsvector
cat:3
rat:5A'::tsvecto
r)

numnode(tsquery) integer

nombre de lexemes et numnode('(fat


d'oprateurs dans tsque- rat)
ry
cat'::tsquery)

plain-

tsquery

produit un tsquery en plain166

& 5
|
'fat' & 'rat'

Fonctions et oprateurs

Fonction

Type de retour

to_tsquery([
config regconfig
,
]
requte
text)
querytree(requte tsquery)

text

settsvector
weight(tsvector,
"char")

strip(tsvector)

tsvector

Description

Exemple

Rsultat

ignorant la ponctuation

to_tsquery('engl
ish', 'The Fat
Rats')

rcupre la partie in- querytree('foo & 'foo'


dexable d'un tsquery
! bar'::tsquery)
affecte un poids set'cat':3A
chaque lment d'un ts- weight('fat:2,4 'fat':2A,4A
vector
cat:3
'rat':5A
rat:5B'::tsvecto
r, 'A')
supprime les positions et strip('fat:2,4
'cat'
les poids du tsvector
cat:3
'rat'
rat:5A'::tsvecto
r)

'fat'

to_tsquery([
tsquery
config regconfig
,
]
requte
text)

normalise les mots et les to_tsquery('engl 'fat' & 'rat'


convertit en un tsquery ish', 'The & Fat
& Rats')

to_tsvector([
tsvector
config regconfig
,
]
document
text)

rduit le texte du docu- to_tsvector('eng 'fat':2 'rat':3


ment en un tsvector
lish', 'The Fat
Rats')

ts_headline([
text
config
regconfig, ] document
text,
requte
tsquery [, options text ])

affiche une correspon- ts_headline('x


dance avec la requte
z',
'z'::tsquery)

ts_rank([
poids float4
float4[], ] vecteur
tsvector,
requte
tsquery
[, normalization
integer ])

renvoie le score d'un do- ts_rank(textsear 0.818


cument pour une requte ch, query)

ts_rank_cd([
float4
weights
float4[], ] vector
tsvector,
requte
tsquery
[, normalization
integer ])

renvoie le score d'un document pour une requte


en utilisant une densit
personnalise

ts_rewrite(retsquery
qute
tsquery,
cible
tsquery,
substitution tsquery)

remplace la cible avec la ts_rewrite('a


& 'b' & ( 'foo' |
substitution l'intrieur b'::tsquery,
'bar' )
de la requte
'a'::tsquery,
'foo|bar'::tsque
ry)

ts_rewrite(retsquery
qute
tsquery,
select text)

remplace en utilisant les


cibles et substitutions
partir d'une commande
SELECT

SELECT
'b' & ( 'foo' |
ts_rewrite('a
& 'bar' )
b'::tsquery, 'SELECT
t,s
FROM
aliases')

tsvectrigger
tor_update_trigg
er()

fonction
dclencheur
pour la mise jour automatique de colonne tsvector

CREATE
TRIGGER
...
tsvector_update_trigg
er(tsvcol,
'pg_catalog.swed

167

y x y <b>z</b>

ts_rank_cd('{0.1 2.01317
,
0.2,
0.4,
1.0}',
textsearch, query)

Fonctions et oprateurs

Fonction

Type de retour

Description

Exemple

Rsultat

ish', title, body)


tsvectrigger
tor_update_trigg
er_column()

fonction
dclencheur
pour la mise jour automatique de colonne tsvector

CREATE
TRIGGER
...
tsvector_update_trigg
er_column(tsvcol
,
configcol,
title, body)

Note
Toutes les fonctions de recherche plein texte qui acceptent un argument regconfig optionel utilisent la configuration
indiqe par default_text_search_config en cas d'omission de cet argument.
Les fonctions de Tableau 9.38, Fonctions de dbogage de la recherche plein texte sont listes sparment, car elles ne font pas
partie des fonctions utilises dans les oprations de recherche plein texte de tous les jours. Elles sont utiles pour le dveloppement
et le dbogage de nouvelles configurations de recherche plein texte.
Tableau 9.38. Fonctions de dbogage de la recherche plein texte

Fonction

Type de retour

Description

Exemple

Rsultat

teste une configuration

ts_debug('englis
h', 'The Brightest
supernovaes')

(asciiword,"Word
,
all
ASCII",The,{englis
h_stem},english_
stem,{}) ...

teste un dictionnaire

ts_lexize('engli {star}
sh_stem',
'stars')

nom_ana
setof record
ts_parse(lyseur
text,
document
text, OUT tokid
integer, OUT token text)

teste un analyseur

ts_parse('defaul (1,foo) ...


t', 'foo - bar')

oid_ana
setof record
ts_parse(lyseur
oid,
document
text,
OUT
id_jeton
integer, OUT jeton
text)

teste un analyseur

ts_parse(3722,
'foo - bar')

pa
setof record
rs
er
_n
am
ts_token_type(e
text, OUT tokid
integer,
OUT

obtient les types de jeton ts_token_type('d (1,asciiword,"Wo


dfinis par l'analyseur
efault')
rd, all ASCII")
...

ts_debug([
setof record
config
regconfig, ] document
text, OUT alias
text, OUT description
text,
OUT token text,
OUT dictionaries
regdictionary[],
OUT
dictionary
regdictionary,
OUT
lexemes
text[])
ts_lexize(dict
regdictionary,
jeton text)

text[]

168

(1,foo) ...

Fonctions et oprateurs

Fonction
alias text,
description
text)

Type de retour

Description

Exemple

Rsultat

OUT

oi
setof record
d_
an
al
ys
eu
ts_token_type(r
oid,
OUT
id_jeton
integer, OUT alias
text, OUT description text)

obtient les types de jeton ts_token_type(37 (1,asciiword,"Wo


dfinis par l'analyseur
22)
rd, all ASCII")
...

ts_stat(sqlquery setof record


text, [ weights
text, ] OUT word
text, OUT ndoc
integer,
OUT
nentry integer)

obtient des statistiques ts_stat('SELECT (foo,10,15) ...


sur une colonne tsvector vector
from
apod')

9.14. Fonctions XML


Les fonctions et expressions dcrites dans cette section oprent sur des valeurs de type xml. Lire la Section 8.13, Type XML
pour des informations sur le type xml. Les expressions xmlparse et xmlserialize permettant de convertir vers ou partir
du type xml ne sont pas reprises ici. L'utilisation d'un grand nombre de ces fonctions ncessite que l'installation soit construite
avec configure --with-libxml.

9.14.1. Produire un contenu XML


Un ensemble de fonctions et expressions de type fonction est disponible pour produire du contenu XML partir de donnes SQL.
En tant que telles, elles conviennent particulirement bien pour formater les rsultats de requtes en XML traiter dans les applications clientes.

9.14.1.1. xmlcomment
xmlcomment(text)
La fonction xmlcomment cre une valeur XML contenant un commentaire XML avec, comme contenu, le texte indiqu. Le
texte ne peut pas contenir -- ou se terminer par un - de sorte que que la construction rsultante reprsente un commentaire XML valide. Si l'argument est NULL, le rsultat est NULL.
Exemple :
SELECT xmlcomment('bonjour');
xmlcomment
-------------<!--bonjour-->

9.14.1.2. xmlconcat
xmlconcat(xml[, ...])
La fonction xmlconcat concatne une liste de valeurs XML individuelles pour crer une valeur simple contenant un fragment
de contenu XML. Les valeurs NULL sont omises ; le rsultat est NULL seulement s'il n'y a pas d'arguments non NULL.
169

Fonctions et oprateurs

Exemple :
SELECT xmlconcat('<abc/>', '<bar>foo</bar>');
xmlconcat
---------------------<abc/><bar>foo</bar>
Les dclarations XML, si elles sont prsentes, sont combines come suit. Si toutes les valeurs en argument ont la mme dclaration de version XML, cette version est utilise dans le rsultat. Sinon aucune version n'est utilise. Si toutes les valeurs en argument ont la valeur de dclaration standalone yes , alors cette valeur est utilise dans le rsultat. Si toutes les valeurs en argument ont une valeur de dclaration standalone et qu'au moins l'une d'entre elles est no , alors cette valeur est utilise dans
le rsultat. Sinon le rsultat n'a aucune dclaration standalone . Si le rsultat ncessite une dclaration standalone sans dclaration de version, une dclaration de version 1.0 est utilise car le standard XML impose qu'une dclaration XML contienne
une dclaration de version. Les dclarations d'encodage sont ignores et supprimes dans tous les cas.
Exemple :
SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1"
standalone="no"?><bar/>');
xmlconcat
----------------------------------<?xml version="1.1"?><foo/><bar/>

9.14.1.3. xmlelement
xmlelement(name nom [, xmlattributes(valeur [AS nom_attribut] [, ... ])] [, contenu,
...])
L'expression xmlelement produit un lment XML avec le nom, les attributs et le contenu donns.
Exemples :
SELECT xmlelement(name foo);
xmlelement
-----------<foo/>
SELECT xmlelement(name foo, xmlattributes('xyz' as bar));
xmlelement
-----------------<foo bar="xyz"/>
SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');
xmlelement
------------------------------------<foo bar="2007-01-26">content</foo>
Les noms d'lment et d'attribut qui ne sont pas des noms XML valides sont modifis en remplaant les caractres indsirables par
une squence _xHHHH_, o HHHH est le codage Unicode du caractre en notation hexadcimal. Par exemple :
SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));
xmlelement
---------------------------------<foo_x0024_bar a_x0026_b="xyz"/>
Un nom explicite d'attribut n'a pas besoin d'tre indiqu si la valeur de l'attribut est la rfrence d'une colonne, auquel cas le nom
de la colonne est utilis comme nom de l'attribut par dfaut. Dans tous les autres cas, l'attribut doit avoir un nom explicite. Donc,
170

Fonctions et oprateurs

cet exemple est valide :


CREATE TABLE test (a xml, b xml);
SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
Mais ceux-ci ne le sont pas :
SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
Si le contenu de l'lment est prcis, il est format en fonction du type de donnes. Si le contenu est lui-mme de type xml, des
documents XML complexes peuvent tre construits. Par exemple :
SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
xmlelement(name abc),
xmlcomment('test'),
xmlelement(name xyz));
xmlelement
---------------------------------------------<foo bar="xyz"><abc/><!--test--><xyz/></foo>
Le contenu des autres types est format avec des donnes XML valides. Cela signifie en particulier que les caractres <, >, et &
sont convertis en entits. Les donnes binaires (type bytea) sont reprsentes dans un encodage base64 ou hexadcimal, suivant la
configuration du paramtre xmlbinary. Le comportement particulier pour les types de donnes individuels devrait voluer pour aligner les types de donnes SQL et PostgreSQL avec la spcification de XML Schema, auquel cas une description plus prcise sera
ajoute.

9.14.1.4. xmlforest
xmlforest(contenu [AS nom] [, ...])
L'expression xmlforest produit un arbre XML (autrement dit une squence) d'lments utilisant les noms et le contenu donns.
Exemples :
SELECT xmlforest('abc' AS foo, 123 AS bar);
xmlforest
-----------------------------<foo>abc</foo><bar>123</bar>
SELECT xmlforest(table_name, column_name)
FROM information_schema.columns
WHERE table_schema = 'pg_catalog';
xmlforest
------------------------------------------------------------------------------------------<table_name>pg_authid</table_name><column_name>rolname</column_name>
<table_name>pg_authid</table_name><column_name>rolsuper</column_name>
...
Comme indiqu dans le second exemple, le nom de l'lment peut tre omis si la valeur du contenu est une rfrence de colonne,
auquel cas le nom de la colonne est utilis par dfaut. Sinon, un nom doit tre indiqu.
Les noms d'lments qui ne sont pas des noms XML valides sont chapps comme indiqu pour xmlelement ci-dessus. De
faon similaire, les donnes de contenu sont chappes pour rendre le contenu XML valide sauf s'il est dj de type xml.
Les arbres XML ne sont pas des documents XML valides s'ils sont constitus de plus d'un lment. Il peut donc s'avrer utile
d'emballer les expressions xmlforest dans xmlelement.

9.14.1.5. xmlpi

171

Fonctions et oprateurs

xmlpi(name target [, content])


L'expression xmlpi cre une instruction de traitement XML. Le contenu, si prsent, ne doit pas contenir la squence de caractres ?>.
Exemple :
SELECT xmlpi(name php, 'echo "hello world";');
xmlpi
----------------------------<?php echo "hello world";?>

9.14.1.6. xmlroot
xmlroot(xml, version text | no value [, standalone yes|no|no value])
L'expression xmlroot modifie les proprits du nud racine d'une valeur XML. Si une version est indique, elle remplace la valeur dans la dclaration de version du nud racine. Si un paramtre standalone est spcifi, il remplace la valeur dans la dclaration standalone du nud racine.
SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'),
version '1.0', standalone yes);
xmlroot
---------------------------------------<?xml version="1.0" standalone="yes"?>
<content>abc</content>

9.14.1.7. xmlagg
xmlagg(xml)
La fonction xmlagg est, la diffrence des fonctions dcrites ici, une fonction d'aggrgat. Elle concatne les valeurs en entre
pour les passer en argument la fonction d'aggrgat, comme le fait la fonction xmlconcat, sauf que la concatnation survient
entre les lignes plutt qu'entre les expressions d'une mme ligne. Voir Section 9.18, Fonctions d'agrgat pour plus
d'informations sur les fonctions d'agrgat.
Exemple :
CREATE
INSERT
INSERT
SELECT

TABLE test (y int, x xml);


INTO test VALUES (1, '<foo>abc</foo>');
INTO test VALUES (2, '<bar/>');
xmlagg(x) FROM test;
xmlagg
---------------------<foo>abc</foo><bar/>
Pour dterminer l'ordre de la concatnation, une clause ORDER BY peut tre ajoute l'appel de l'agrgat comme dcrit dans Section 4.2.7, Expressions d'agrgat . Par exemple :
SELECT xmlagg(x ORDER BY y DESC) FROM test;
xmlagg
---------------------<bar/><foo>abc</foo>
L'approche non standard suivante tait recommende dans les versions prcdentes et peut toujours tre utiles dans certains cas
particuliers :

172

Fonctions et oprateurs

SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;


xmlagg
---------------------<bar/><foo>abc</foo>

9.14.2. Prdicats XML


Les expressions dcrites dans cette section vrifient les proprits de valeurs du type xml.

9.14.2.1. IS DOCUMENT
xml IS DOCUMENT
L'expression IS DOCUMENT renvoie true si la valeur de l'argument XML est un document XML correct, false dans le cas
contraire (c'est--dire qu'il s'agit d'un fragment de document) ou NULL si l'argument est NULL. Voir la Section 8.13, Type
XML pour les diffrences entre documents et fragments de contenu.

9.14.2.2. XMLEXISTS
XMLEXISTS(text PASSING [BY REF] xml [BY REF])
La fonction xmlexists renvoie true si l'expression XPath dans le premier argument renvoie des nuds. Elle renvoie faux sinon.
(Si un des arguments est NULL, le rsultat est NULL.)
Exemple :
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF
'<towns><town>Toronto</town><town>Ottawa</town></towns>');
xmlexists
-----------t
(1 row)
Les clauses BY REF n'ont pas d'effet dans PostgreSQL mais sont autorises pour se conformer au standard SQL et pour la compatibilit avec les autres implmentations. D'aprs le standard SQL, le premier BY REF est requis, le second est optionel. De plus,
notez que le standard SQL spcifie que la construction xmlexists prend une expression XQuery en premier argument mais
PostgreSQL supporte actuellement seulement XPath, qui est un sous-ensemble de XQuery.

9.14.2.3. xml_is_well_formed
xml_is_well_formed(text)
xml_is_well_formed_document(text)
xml_is_well_formed_content(text)
Ces fonctions vrifient si la chane text est du XML bien form et renvoient un rsultat boolen.
xml_is_well_formed_document vrifie si le document est bien form alors que xml_is_well_formed_content vrifie si le contenu est bien form. xml_is_well_formed est quivalent xml_is_well_formed_document si le paramtre de configuration xmloption vaut DOCUMENT et est quivalent xml_is_well_formed_content si le paramtre vaut
CONTENT. Cela signifie que xml_is_well_formed est utile pour savoir si une conversion au type xml va russir alors que les
deux autres sont utiles pour savoir si les variantes correspondantes de XMLPARSE vont russir.
Exemples :
SET xmloption TO DOCUMENT;
SELECT xml_is_well_formed('<>');
xml_is_well_formed
-------------------f
(1 row)
SELECT xml_is_well_formed('<abc/>');
173

Fonctions et oprateurs

xml_is_well_formed
-------------------t
(1 row)
SET xmloption TO CONTENT;
SELECT xml_is_well_formed('abc');
xml_is_well_formed
-------------------t
(1 row)
SELECT xml_is_well_formed_document('<pg:foo
xmlns:pg="http://postgresql.org/stuff">bar</pg:foo>');
xml_is_well_formed_document
----------------------------t
(1 row)
SELECT xml_is_well_formed_document('<pg:foo
xmlns:pg="http://postgresql.org/stuff">bar</my:foo>');
xml_is_well_formed_document
----------------------------f
(1 row)
Le dernier exemple monte que les vrifications incluent les correspondances d'espace de noms.

9.14.3. Traiter du XML


Pour traiter les valeurs du type xml, PostgreSQL fournit les fonctions xpath et xpath_exists, qui valuent les expressions
XPath 1.0.
xpath(xpath, xml [, nsarray])
La fonction xpath value l'expression XPath xpath (une valeur de type text) avec la valeur XML xml. Elle renvoie un tableau
de valeurs XML correspondant l'ensemble de nuds produit par une expression XPath.
Le second argument doit tre un document XML bien form. En particulier, il doit avoir un seul lment de nud racine.
Le troisime argument (optionnel) de la fonction est un tableau de correspondances de namespace. Ce tableau text doit avoir deux
dimensions dont la seconde a une longueur 2 (en fait, c'est un tableau de tableaux exactement deux lments). Le premier lment de chaque entre du tableau est le nom du namespace (alias), le second tant l'URI du namespace. Il n'est pas requis que les
alias fournis dans ce tableau soient les mmes que ceux utiliss dans le document XML (autrement dit, que ce soit dans le contexte
du document XML ou dans celui de la fonction xpath, les alias ont une vue locale).
Exemple :
SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
ARRAY[ARRAY['my', 'http://example.com']]);
xpath
-------{test}
(1 row)
Pour grer des namespaces par dfaut (anonymes), faites ainsi :
SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>',
ARRAY[ARRAY['mydefns', 'http://example.com']]);
xpath
-------{test}
(1 row)

174

Fonctions et oprateurs

xpath_exists(xpath, xml [, nsarray])


La fonction xpath_exists est une forme spcialise de la fonction xpath. Au lieu de renvoyer les valeurs XML individuelles
qui satisfont XPath, cette fonction renvoie un boolen indiquant si la requte a t satisfaite ou non. Cette fonction est quivalent
au prdicat standard XMLEXISTS, sauf qu'il fonctionne aussi avec un argument de correspondance d'espace de nom.
Exemple :
SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
ARRAY[ARRAY['my', 'http://example.com']]);
xpath_exists
-------------t
(1 row)

9.14.4. Transformer les tables en XML


Les fonctions suivantes transforment le contenu de tables relationnelles en valeurs XML. Il s'agit en quelque sorte d'un export
XML.
table_to_xml(tbl regclass, nulls boolean, tableforest boolean, targetns text)
query_to_xml(query text, nulls boolean, tableforest boolean, targetns text)
cursor_to_xml(cursor refcursor, count int, nulls boolean,
tableforest boolean, targetns text)
Le type en retour de ces fonctions est xml.
table_to_xml transforme le contenu de la table passe en argument (paramtre tbl). regclass accepte des chanes identifiant
les tables en utilisant la notation habituelle, incluant les qualifications possibles du schma et les guillemets doubles. query_to_xml excute la requte dont le texte est pass par le paramtre query et transforme le rsultat. cursor_to_xml rcupre le nombre indiqu de lignes partir du curseur indiqu par le paramtre cursor. Cette variante est recommande si la transformation se fait sur de grosses tables car la valeur en rsultat est construite en mmoire pour chaque fonction.
Si tableforest vaut false, alors le document XML rsultant ressemble ceci :
<tablename>
<row>
<columnname1>donnees</columnname1>
<columnname2>donnees</columnname2>
</row>
<row>
...
</row>
...
</tablename>
Si tableforest vaut true, le rsultat est un fragment XML qui ressemble ceci :
<tablename>
<columnname1>donnees</columnname1>
<columnname2>donnees</columnname2>
</tablename>
<tablename>
...
</tablename>
...
Si aucune table n'est disponible, c'est--dire lors d'une transformation partir d'une requte ou d'un curseur, la chane table est
utilise dans le premier format, et la chane row dans le second.
Le choix entre ces formats dpend de l'utilisateur. Le premier format est un document XML correct, ce qui est important dans
beaucoup d'applications. Le second format tend tre plus utile dans la fonction cursor_to_xml si les valeurs du rsultat sont
175

Fonctions et oprateurs

rassembler plus tard dans un document. Les fonctions pour produire du contenu XML discutes ci-dessus, en particulier xmlelement, peuvent tre utilises pour modifier les rsultats.
Les valeurs des donnes sont transformes de la mme faon que ce qui est dcrit ci-dessus pour la fonction xmlelement.
Le paramtre nulls dtermine si les valeurs NULL doivent tre incluses en sortie. true, les valeurs NULL dans les colonnes
sont reprsentes ainsi :
<columnname xsi:nil="true"/>
o xsi est le prfixe de l'espace de noms XML pour l'instance XML Schema. Une dclaration approprie d'un espace de noms est
ajoute la valeur du rsultat. false, les colonnes contenant des valeurs NULL sont simplement omises de la sortie.
Le paramtre targetns indique l'espace de noms souhait pour le rsultat. Si aucun espace de nom particulier n'est demand,
une chane vide doit tre passe.
Les fonctions suivantes renvoient des documents XML Schema dcrivant la transformation ralise par les fonctions ci-dessus.
table_to_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text)
query_to_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)
cursor_to_xmlschema(cursor refcursor, nulls boolean, tableforest boolean, targetns
text)
Il est essentiel que les mmes paramtres soient passs pour obtenir les bonnes transformations de donnes XML et des documents
XML Schema.
Les fonctions suivantes ralisent la transformation des donnes XML et du XML Schema correspondant en un seul document (ou
arbre), lis ensemble. Elles sont utiles lorsque les rsultats doivent tre auto-contenus et auto-descriptifs.
table_to_xml_and_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns
text)
query_to_xml_and_xmlschema(query text, nulls boolean, tableforest boolean, targetns
text)
De plus, les fonctions suivantes sont disponibles pour produire des transformations analogues de schmas complets ou de bases de
donnes compltes.
schema_to_xml(schema name, nulls boolean, tableforest boolean, targetns text)
schema_to_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text)
schema_to_xml_and_xmlschema(schema name, nulls boolean, tableforest boolean, targetns
text)
database_to_xml(nulls boolean, tableforest boolean, targetns text)
database_to_xmlschema(nulls boolean, tableforest boolean, targetns text)
database_to_xml_and_xmlschema(nulls boolean, tableforest boolean, targetns text)
Elles peuvent produire beaucoup de donnes, qui sont construites en mmoire. Lors de transformations de gros schmas ou de
grosses bases, il peut tre utile de considrer la transformation spare des tables, parfois mme via un curseur.
Le rsultat de la transformation du contenu d'un schma ressemble ceci :
<nomschema>
transformation-table1
transformation-table2
...
</nomschema>
o le format de transformation d'une table dpend du paramtre tableforest comme expliqu ci-dessus.
Le rsultat de la transformation du contenu d'une base ressemble ceci :
<nombase>
<nomschema1>
176

Fonctions et oprateurs

...
</nomschema1>
<nomschema2>
...
</nomschema2>
...
</nombase>
avec une transformation du schma identique celle indique ci-dessus.
En exemple de l'utilisation de la sortie produite par ces fonctions, la Figure 9.1, Feuille de style XSLT pour convertir du SQL/
XML en HTML montre une feuille de style XSLT qui convertit la sortie de table_to_xml_and_xmlschema en un document HTML contenant un affichage en tableau des donnes de la table. D'une faon similaire, les donnes en rsultat de ces fonctions peuvent tre converties dans d'autres formats bass sur le XML.
Figure 9.1. Feuille de style XSLT pour convertir du SQL/XML en HTML

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/xhtml"
>
<xsl:output method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
indent="yes"/>

<xsl:template match="/*">
<xsl:variable name="schema" select="//xsd:schema"/>
<xsl:variable name="tabletypename"
select="$schema/xsd:element[@name=name(current())]/@type"/>
<xsl:variable name="rowtypename"
select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/
<html>
<head>
<title><xsl:value-of select="name(current())"/></title>
</head>
<body>
<table>
<tr>
<xsl:for-each
select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name">
<th><xsl:value-of select="."/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="row">
<tr>
<xsl:for-each select="*">
<td><xsl:value-of select="."/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

177

Fonctions et oprateurs

9.15. Fonctions de manipulation de squences


Cette section dcrit les fonctions oprant sur les objets de squence, aussi appels gnrateurs de squence ou simplement squences. Ces objets sont des tables spciales, mono-lignes, cres avec la commande CREATE SEQUENCE(7). Les squences
sont gnralement utilises pour engendrer des identifiants uniques de lignes d'une table. Les fonctions de squence, listes dans le
Tableau 9.39, Fonctions squence , fournissent des mthodes simples, et sres en environnement multi-utilisateurs, d'obtention
de valeurs successives partir d'objets squence.
Tableau 9.39. Fonctions squence

Fonction

Type de retour Description

currval(regclass)

bigint

Renvoie la valeur la plus rcemment obtenue avec


nextval pour la squence indique

lastval()

bigint

Renvoie la valeur la plus rcemment obtenue avec


nextval pour toute squence

nextval(regclass)

bigint

Incrmente la squence et renvoie la nouvelle valeur

setval(regclass, bigint)

bigint

Positionne la valeur courante de la squence

setval(regclass, bigint, boolean)

bigint

Positionne la valeur courante de la squence et le drapeau is_called

La squence traiter par l'appel d'une fonction de traitement de squences est identifie par un argument regclass, qui n'est autre
que l'OID de la squence dans le catalogue systme pg_class. Il n'est toutefois pas ncessaire de se proccuper de la recherche de
cet OID car le convertisseur de saisie du type de donnes regclass s'en charge. Il suffit d'crire le nom de la squence entre guillemets simples, de faon le faire ressembler un libell. Pour obtenir une compatibilit avec la gestion des noms SQL ordinaires,
la chane est convertie en minuscules, sauf si le nom de la squence est entour de guillemets doubles. Du coup :
nextval('foo')
nextval('FOO')
nextval('"Foo"')

opre sur la squence foo


opre sur la squence foo
opre sur la squence Foo

Le nom de la squence peut, au besoin, tre qualifi du nom du schma :


nextval('mon_schema.foo')
nextval('"mon_schema".foo')
nextval('foo')
pour trouver foo

opre sur mon_schema.foo


identique ci-dessus
parcourt le chemin de recherche

Voir la Section 8.16, Types identifiant d'objet pour plus d'informations sur regclass.

Note
Avant la version 8.1 de PostgreSQL, les arguments des fonctions de traitement de squences taient du type text,
et non regclass. De ce fait, les conversions prcdemment dcrites d'une chane de caractres en valeur OID se produisaient chaque appel. Pour des raisons de compatibilit, cette fonctionnalit existe toujours. Mais, en interne, un
transtypage implicite est effectu entre text et regclass avant l'appel de la fonction.
Lorsque l'argument d'une fonction de traitement de squences est crit comme une simple chane de caractres, il
devient une constante de type regclass. Puisqu'il ne s'agit que d'un OID, il permet de suivre la squence originelle
mme en cas de renommage, changement de schma... Ce principe de lien fort est en gnral souhaitable lors de
rfrences la squence dans les vues et valeurs par dfaut de colonnes. Un lien faible est gnralement souhait lorsque la rfrence la squence est rsolue l'excution. Ce comportement peut tre obtenu en forant le stockage des constantes sous la forme de constantes text plutt que regclass :
nextval('foo'::text)

foo est recherch l'excution

Le lien faible est le seul comportement accessible dans les versions de PostgreSQL antrieures 8.1. Il peut donc
tre ncessaire de le conserver pour maintenir la smantique d'anciennes applications.
L'argument d'une fonction de traitement de squences peut tre une expression ou une constante. S'il s'agit d'une
expression textuelle, le transtypage implicite impose une recherche l'excution.
Les fonctions squence disponibles sont :
nextval
178

Fonctions et oprateurs

Avance l'objet squence sa prochaine valeur et renvoie cette valeur. Ce fonctionnement est atomique : mme si de multiples
sessions excutent nextval concurrentiellement, chacune obtient sans risque une valeur de squence distincte.
Si un objet squence a t cr avec les paramtres par dfaut, les appels nextval sur celui-ci renvoient des valeurs successives partir de 1. D'autres comportements peuvent tre obtenus en utilisant des paramtres spciaux de la commande
CREATE SEQUENCE(7) ; voir la page de rfrence de la commande pour plus d'informations.

Important
Pour viter le blocage de transactions concurrentes qui obtiennent des nombres de la mme squence, une opration nextval n'est jamais annule ; c'est--dire qu'une fois la valeur rcupre, elle est considre utilise,
mme si la transaction qui excute nextval avorte par la suite. Cela signifie que les transactions annules
peuvent laisser des trous inutiliss dans la squence des valeurs assignes.
currval
Renvoie la valeur la plus rcemment retourne par nextval pour cette squence dans la session courante. (Une erreur est
rapporte si nextval n'a jamais t appele pour cette squence dans cette session.) Parce qu'elle renvoie une valeur locale
la session, la rponse est prvisible, que d'autres sessions aient excut ou non la fonction nextval aprs la session en
cours.
lastval
Renvoie la valeur la plus rcemment retourne par nextval dans la session courante. Cette fonction est identique currval, sauf qu'au lieu de prendre le nom de la squence comme argument, elle rcupre la valeur de la dernire squence utilise par nextval dans la session en cours. Si nextval n'a pas encore t appele dans la session en cours, un appel
lastval produit une erreur.
setval
Rinitialise la valeur du compteur de l'objet squence. La forme avec deux paramtres initialise le champ last_value de la
squence la valeur prcise et initialise le champ is_called true, signifiant que le prochain nextval avance la squence avant de renvoyer une valeur. La valeur renvoye par currval est aussi configur la valeur indique. Dans la
forme trois paramtres, is_called peut tre initialis true ou false. true a le mme effet que la forme deux
paramtres. Positionn false, le prochain nextval retourne exactement la valeur indique et l'incrmentation de la squence commence avec le nextval suivant. De plus, la valeur indique par currval n'est pas modifie dans ce cas. (Il
s'agit d'une modification du comportement des versions antrieures la 8.3.) Par exemple,
SELECT setval('foo', 42);
SELECT setval('foo', 42, true);
SELECT setval('foo', 42, false);

Le nextval suivant retourne 43


Comme ci-dessus
Le nextval suivant retourne 42

Le rsultat renvoy par setval est la valeur du second argument.

Important
Comme les squences sont non transactionnelles, les modifications ralises par setval ne sont pas annules
si la transaction est annule.

9.16. Expressions conditionnelles


Cette section dcrit les expressions conditionnelles respectueuses du standard SQL disponibles avec PostgreSQL.

Astuce
S'il s'avre ncessaire d'aller au-del des possibilits offertes par les expressions conditionnelles, il faut considrer
l'criture d'une procdure stocke dans un langage de programmation plus expressif.

9.16.1. CASE
L'expression SQL CASE est une expression conditionnelle gnrique, similaire aux instructions if/else des autres langages de programmation :
CASE WHEN condition THEN rsultat
[WHEN ...]
[ELSE rsultat]
END
179

Fonctions et oprateurs

Les clauses CASE peuvent tre utilises partout o une expression est valide. Chaque condition est une expression qui renvoie
un rsultat de type boolean. Si le rsultat de la condition est vrai, alors la valeur de l'expression CASE est le rsultat qui suit la
condition. Si le rsultat de la condition n'est pas vrai, toutes les clauses WHEN suivantes sont parcourues de la mme faon. Si aucune condition WHEN n'est vraie, alors la valeur de l'expression CASE est le rsultat de la clause ELSE. Si la clause
ELSE est omise et qu'aucune condition ne correspond, alors le rsultat est nul.
Un exemple :
SELECT * FROM test;
a
--1
2
3
SELECT a,
CASE WHEN a=1 THEN 'un'
WHEN a=2 THEN 'deux'
ELSE 'autre'
END
FROM test;
a | case
---+------1 | un
2 | deux
3 | autre
Les types de donnes de toutes les expressions rsultat doivent tre convertibles dans un type de sortie unique. Voir la Section 10.5, Constructions UNION, CASE et constructions relatives pour plus de dtails.
L'expression CASE qui suit est une variante de la forme gnrale ci-dessus :
CASE expression
WHEN valeur THEN
rsultat
[WHEN ...]
[ELSE rsultat]
END
La premire expression est calcule et compare chacune des valeur des clauses WHEN jusqu' en trouver une gale. Si
aucune ne correspond, le rsultat de la clause ELSE (ou une valeur NULL) est renvoy(e). C'est similaire l'instruction
switch du langage C.
L'exemple ci-dessus peut tre rcrit en utilisant la syntaxe CASE simple :
SELECT a,
CASE a WHEN 1 THEN 'un'
WHEN 2 THEN 'deux'
ELSE 'autre'
END
FROM test;
a | case
---+------1 | un
2 | deux
3 | autre
Une expression CASE n'value pas les sous-expressions qui ne sont pas ncessaires pour dterminer le rsultat. Par exemple, une
faon possible d'viter une division par zro :
SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;

Note
Comme dcrit dans Section 35.6, Catgories de volatilit des fonctions , les fonctions et les oprateurs marqus
IMMUTABLE peuvent tre valus quand la requte est planifie plutt que quand elle est excute. Cela signifie
180

Fonctions et oprateurs

que les parties constantes d'une sous-expression qui n'est pas value durant l'excution de la requte pourrait toujours tre value pendant la planification de la requte.

9.16.2. COALESCE
COALESCE(valeur [, ...])
La fonction COALESCE renvoie le premier de ses arguments qui n'est pas nul. Une valeur NULL n'est renvoye que si tous les arguments sont nuls. Cette fonction est souvent utile pour substituer une valeur par dfaut aux valeurs NULL lorsque la donne est
rcupre pour affichage. Par exemple :
SELECT COALESCE(description, description_courte, '(aucune)') ...
l'instar d'une expression CASE, COALESCE n'value pas les arguments inutiles la dtermination du rsultat ; c'est--dire que
tous les arguments la droite du premier argument non nul ne sont pas valus. Cette fonction SQL standard fournit des fonctionnalits similaires NVL et IFNULL, qui sont utilises dans d'autres systmes de bases de donnes.

9.16.3. NULLIF
NULLIF(valeur1, valeur2)
La fonction NULLIF renvoie une valeur NULL si valeur1 et valeur2 sont gales ; sinon, elle renvoie valeur1.
On peut s'en servir pour effectuer l'opration inverse de l'exemple de COALESCE donn ci-dessus :
SELECT NULLIF(valeur, '(aucune)') ...
Dans cet exemple, si valeur vaut (aucune), la valeur NULL est renvoye, sinon la valeur de valeur est renvoye.

9.16.4. GREATEST et LEAST


GREATEST(valeur [, ...])
LEAST(valeur [, ...])
Les fonctions GREATEST et LEAST slectionnent, respectivement, la valeur la plus grande et la valeur la plus petite d'une liste
d'expressions. Elles doivent tre toutes convertibles en un type de donnes commun, type du rsultat (voir la Section 10.5,
Constructions UNION, CASE et constructions relatives pour les dtails). Les valeurs NULL contenues dans la liste sont ignores. Le rsultat est NULL uniquement si toutes les expressions sont NULL.
GREATEST et LEAST ne sont pas dans le standard SQL mais sont des extensions habituelles. D'autres SGBD leur imposent de retourner NULL si l'un quelconque des arguments est NULL, plutt que lorsque tous les arguments sont NULL.

9.17. Fonctions et oprateurs de tableaux


Le Tableau 9.40, Oprateurs pour les tableaux prsente les oprateurs disponibles pour les types tableaux.
Tableau 9.40. Oprateurs pour les tableaux

Oprateur

Description

Exemple

Rsultat

gal

ARRAY[1.1,2.1,3.1]::int[]
RAY[1,2,3]

<>

diffrent de

ARRAY[1,2,3] <> ARRAY[1,2,4]

<

infrieur

ARRAY[1,2,3] < ARRAY[1,2,4]

>

suprieur

ARRAY[1,4,3] > ARRAY[1,2,4]

<=

infrieur ou gal ARRAY[1,2,3] <= ARRAY[1,2,3]

>=

suprieur ou gal ARRAY[1,4,3] >= ARRAY[1,4,3]

@>

contient

ARRAY[1,4,3] @> ARRAY[3,1]

<@

est contenu par

ARRAY[2,7] <@ ARRAY[1,7,4,2,6]

181

AR- t

Fonctions et oprateurs

Oprateur

Description

Exemple

Rsultat

&&

se chevauchent ARRAY[1,4,3] && ARRAY[2,1]


(ont des lments
en commun)

||

concatnation de ARRAY[1,2,3] || ARRAY[4,5,6]


tableaux

{1,2,3,4,5,6}

||

concatnation de ARRAY[1,2,3]
tableaux
RAY[[4,5,6],[7,8,9]]

||

concatnation
3 || ARRAY[4,5,6]
d'un
lment
avec un tableau

{3,4,5,6}

||

concatnation
ARRAY[4,5,6] || 7
d'un tableau avec
un lment

{4,5,6,7}

||

AR- {{1,2,3},{4,5,6},{7,8,9}
}

Les comparaisons de tableaux comparent les contenus des tableaux lment par lment, en utilisant la fonction de comparaison
par dfaut du B-Tree pour le type de donnes de l'lment. Dans les tableaux multi-dimensionnels, les lments sont visits dans
l'ordre des colonnes ( row-major order , le dernier indice varie le plus rapidement). Si le contenu de deux tableaux est identique
mais que les dimensions sont diffrentes, la premire diffrence dans l'information de dimension dtermine l'ordre de tri. (Ce fonctionnement diffre de celui des versions de PostgreSQL antrieures la 8.2 : les anciennes versions indiquent que deux tableaux
de mme contenu sont identiques mme si le nombre de dimensions ou les chelles d'indices diffrent.)
Voir la Section 8.14, Tableaux pour plus de dtails sur le comportement des oprateurs.
Le Tableau 9.41, Fonctions pour les tableaux prsente les fonctions utilisables avec des types tableaux. Voir la Section 8.14,
Tableaux pour plus d'informations et des exemples d'utilisation de ces fonctions.
Tableau 9.41. Fonctions pour les tableaux

Fonction

Type de retour

array_append
anyarray
(anyarray, anyelement)
array_cat
(anyarray,
anyarray)

anyarray

(anya
int
array_ndimsrray)

array_dims
(anyarray)

text

(anyel
anyarray
array_fillement,
int[],
[,
int[]])

Description

Exemple

Rsultat

ajoute un lment la ar{1,2,3}


fin d'un tableau
ray_append(ARRAY
[1,2], 3)
concatne deux tableaux ar{1,2,3,4,5}
ray_cat(ARRAY[1,
2,3],
ARRAY[4,5])
renvoie le nombre de di- ar2
mensions du tableau
ray_ndims(ARRAY[
[1,2,3],
[4,5,6]])
renvoie une reprsenta- ar[1:2][1:3]
tion textuelle des dimen- ray_dims(array[[
sions d'un tableau
1,2,3],
[4,5,6]])
renvoie un tableau initia- array_fill(7,
[2:4]={7,7,7}
lis avec une valeur et ARRAY[3],
ARdes dimensions fournies, RAY[2])
en option avec des limites basses autre que 1

(any
array_lengtharray, int)

int

renvoie la longueur de la ar3


dimension du tableau
ray_length(array
[1,2,3], 1)

array_lower
(anyarray, int)

int

renvoie la limite inf- ar0


rieure du tableau donn ray_lower('[0:2]
={1,2,3}'::int[]
, 1)

array_prepend

anyarray

ajoute un lment au d- array_prepend(1, {1,2,3}


182

Fonctions et oprateurs

Fonction

Type de retour

Description

Exemple

(anyelement,
anyarray)

but d'un tableau

ARRAY[2,3])

(
text
a
n
y
a
r
r
a
y
array_to_string,
text [, text])

concatne des lments


de tableau en utilisant le
dlimiteur fourni et une
chane nulle optionnelle

ar1,2,3,*,5
ray_to_string(AR
RAY[1,
2,
3,
NULL, 5], ',',
'*')

array_upper
(anyarray, int)

int

Rsultat

renvoie la limite sup- ar4


rieure du tableau donn ray_upper(ARRAY[
1,8,3,7], 1)

(
text[]
t
e
x
t
string_to_array,
text [, text])

divise une chane en ta- string_to_array( {xx,NULL,zz}


bleau d'lments en utili- 'xx~^~yy~^~zz',
sant le dlimiteur fourni '~^~', 'yy')
et la chane nulle optionnelle

unnest(anyarray) setof anyelement

tend un tableau un en- un1


semble de lignes
nest(ARRAY[1,2]) 2
(2 rows)

Dans string_to_array, si le dlimiteur vaut NULL, chaque caractre de la chane en entre deviendra un lment spar
dans le tableau rsultant. Si le dlimiteur est une chane vide, alors la chane entire est renvoye dans un tableau un lment.
Dans les autres cas, la chane en entre est divise chaque occurence du dlimiteur.
Dans string_to_array, si le paramtre chane_null est omis ou vaut NULL, aucune des sous-chanes en entre ne sera remplace par NULL. Dans array_to_string, si le paramtre chane_null est omis ou vaut NULL, tous les lments NULL du
tableau seront simplement ignors et non reprsents dans la chane en sortie.

Note
Il existe deux diffrences dans le comportement de string_to_array avec les versions de PostgreSQL antrieures la 9.1. Tout d'abord, il renverra un tableau vide ( zro lment) plutt que NULL quand la chane en entre est de taille zro. Ensuite, si le dlimiteur vaut NULL, la fonction divise l'entre en caractres individuels plutt que de renvoyer NULL comme avant.
Voir aussi Section 9.18, Fonctions d'agrgat propose la fonction d'agrgat array_agg utiliser avec les tableaux.

9.18. Fonctions d'agrgat


Les fonctions d'agrgat calculent une valeur unique partir d'un ensemble de valeurs en entre. Les fonctions d'agrgats intgres
sont listes dans Tableau 9.42, Fonctions d'agrgat gnrales et Tableau 9.43, Fonctions d'agrgats pour les statistiques . La
syntaxe particulire des fonctions d'agrgat est dcrite dans la Section 4.2.7, Expressions d'agrgat . La Section 2.7, Fonctions
d'agrgat fournit un supplment d'informations introductives.
Tableau 9.42. Fonctions d'agrgat gnrales

Fonction

Type d'argument

array_agg(expression) any

avg(expression)

smallint,

int,

bigint,

Type de retour

Description

tableau du type de l'argument

les valeurs en entre, pouvant


inclure des valeurs NULL,
concatnes dans un tableau

real, numeric pour tout argument de la moyenne arithmtique de


183

Fonctions et oprateurs

Fonction

Type d'argument

Type de retour

Description

double precision, numeric ou type entier, double precision toutes les valeurs en entre
interval
pour tout argument en virgule
flottante, sinon identique au
type de donnes de l'argument
bit_and(expression)

smallint, int, bigint ou bit

identique au type de donnes le AND bit bit de toutes les


de l'argument
valeurs non NULL en entre ou
NULL s'il n'y en a pas

bit_or(expression)

smallint, int, bigint ou bit

identique au type de donnes le OR bit bit de toutes les vade l'argument


leurs non NULL en entre ou
NULL s'il n'y en a pas

bool_and(expression)

bool

bool

true si toutes les valeurs en entre valent true, false sinon

bool_or(expression)

bool

bool

true si au moins une valeur en


entre vaut true, false sinon

bigint

nombre de lignes en entre

count(*)
count(expression)

tout type

bigint

nombre de lignes en entre


pour lesquelles l'expression n'est pas NULL

every(expression)

bool

bool

quivalent bool_and

max(expression)

tout type array, numeric, string identique au type en argument valeur maximale de l'exou date/time
pression pour toutes les valeurs en entre

min(expression)

tout type array, numeric, string identique au type en argument valeur minimale de l'expresou date/time
sion pour toutes les valeurs
en entre

string_agg(expression text, text


, delimiter)

text

valeurs en entres concatnes


dans une chane, spares par
un dlimiteur

sum(expression)

smallint, int, bigint, real, bigint pour les arguments de somme de l'expression
double precision, numeric ou type smallint ou int, numeric pour toutes les valeurs en eninterval
pour les arguments de type bi- tre
gint, double precision pour les
arguments en virgule flottante,
sinon identique au type de donnes de l'argument

xmlagg(expression)

xml

xml

concatnation de valeurs XML


(voir aussi Section 9.14.1.7,
xmlagg )

En dehors de count, ces fonctions renvoient une valeur NULL si aucune ligne n'est slectionne. En particulier, une somme
(sum) sur aucune ligne renvoie NULL et non zro, et array_agg renvoie NULL plutt qu'un tableau vide quand il n'y a pas de
lignes en entre. La fonction coalesce peut tre utilise pour substituer des zros ou un tableau vide aux valeurs NULL quand
cela est ncessaire.

Note
Les agrgats boolens bool_and et bool_or correspondent aux agrgats standard du SQL every et any ou
some. Pour any et some, il semble qu'il y a une ambigut dans la syntaxe standard :
SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
Ici, ANY peut tre considr soit comme introduisant une sous-requte soit comme tant une fonction d'agrgat, si
la sous-requte renvoie une ligne avec une valeur boolenne si l'expression de slection ne renvoie qu'une ligne. Du
coup, le nom standard ne peut tre donn ces agrgats.

184

Fonctions et oprateurs

Note
Les utilisateurs habitus travailler avec d'autres systmes de gestion de bases de donnes SQL peuvent tre surpris par les performances de l'agrgat count lorsqu'il est appliqu la table entire. En particulier, une requte
identique
SELECT count(*) FROM ma_table;
est excut par PostgreSQL l'aide d'un parcours squentiel de la table entire.
Les fonctions d'agrgat array_agg, string_agg et xmlagg, ainsi que d'autres fonctions similaires d'agrgats dfinies par
l'utilisateur, produisent des valeurs de rsultats qui ont un sens diffrents, dpendant de l'ordre des valeurs en entre. Cet ordre
n'est pas prcis par dfaut mais peut tre contrl en ajoutant une clause ORDER BY comme indique dans Section 4.2.7,
Expressions d'agrgat . Une alternative revient fournir les valeurs partir d'une sous-requte trie fonctionnera gnralement.
Par exemple :
SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
Mais cette syntaxe n'est pas autorise dans le standard SQL et n'est pas portable vers d'autres systmes de bases de donnes.
Tableau 9.43, Fonctions d'agrgats pour les statistiques prsente les fonctions d'agrgat typiquement utilises dans l'analyse
statistique. (Elles sont spares pour viter de grossir la liste des agrgats les plus utiliss.) L o la description mentionne N, cela
reprsente le nombre de lignes en entre pour lesquelles toutes les expressions en entre sont non NULL. Dans tous les cas, NULL
est renvoy si le calcul n'a pas de signification, par exemple si N vaut zro.
Tableau 9.43. Fonctions d'agrgats pour les statistiques

Fonction

Type de l'argument

Type renvoy

Description

corr(Y, X)

double precision

double precision

coefficient de corrlation

covar_pop(Y, X)

double precision

double precision

covariance de population

covar_samp(Y, X)

double precision

double precision

covariance exemple

regr_avgx(Y, X)

double precision

double precision

moyenne de la variable indpendante (sum(X)/N)

regr_avgy(Y, X)

double precision

double precision

moyenne de la variable dpendante (sum(Y) / N)

regr_count(Y, X)

double precision

bigint

nombre de lignes dans lesquelles les deux expressions


sont non NULL

regr_intercept(Y, X)

double precision

double precision

interception de l'axe y pour


l'quation linaire de la mthode des moindres carrs dtermine par les paires (X, Y)

regr_r2(Y, X)

double precision

double precision

carr du coefficient de corrlation

regr_slope(Y, X)

double precision

double precision

inclinaison pour l'quation linaire de la mthode des


moindres carrs dtermine par
les paires (X, Y)

regr_sxx(Y, X)

double precision

double precision

sum(X^2) - sum(X)^2 /
N ( somme des carrs de la
variable indpendante)

regr_sxy(Y, X)

double precision

double precision

sum(X*Y) - sum(X) *
sum(Y) / N ( somme des
produits de la variable indpendante multiplie par la variable dpendante)

regr_syy(Y, X)

double precision

double precision

sum(Y^2) - sum(Y)^2 /
N ( somme des carrs de la
variable dpendante)

185

Fonctions et oprateurs

Fonction

Type de l'argument

Type renvoy

Description

stddev(expression)

smallint, int, bigint, real, double precision pour les argu- alias historique pour stddouble precision ou numeric
ments en virgule flottante, nu- dev_samp
meric sinon
smallint, int, bigint, real, double precision pour les argu- dviation standard de la popudouble precision ou numeric
ments en virgule flottante, nu- lation pour les valeurs en enmeric sinon
tre

186

Fonctions et oprateurs

Fonction

Type de l'argument

Type renvoy

Description

)
stddev_samp(expression)

smallint, int, bigint, real, double precision pour les argu- exemple de dviation standard
double precision ou numeric
ments en virgule flottante, nu- pour les valeurs en entre
meric sinon

variance(expression)

smallint, int, bigint, real, double precision pour les argu- alias historique de var_samp
double precision ou numeric
ments en virgule flottante, numeric sinon

var_pop(expression)

smallint, int, bigint, real, double precision pour les argu- variance de la population pour
double precision ou numeric
ments en virgule flottante, nu- les valeurs en entre (carr de
meric sinon
la dviation standard de la population)

var_samp(expression)

smallint, int, bigint, real, double precision pour les argu- exemple de la variance des vadouble precision ou numeric
ments en virgule flottante, nu- leurs en entre (carr de la dmeric sinon
viation standard)

9.19. Fonctions Window


Les fonction Window fournissent la possibilit de raliser des calculs au travers d'ensembles de lignes relatifs la ligne de la requte en cours. Voir Section 3.5, Fonctions de fentrage pour une introduction cette fonctionnalit.
Les fonctions window internes sont listes dans Tableau 9.44, Fonctions Window gnralistes . Notez que ces fonctions
doivent tre appeles en utilisant la syntaxe des fonctions window ; autrement dit, une clause OVER est requise.
En plus de ces fonctions, toute fonction d'agrgat interne ou dfinie par l'utilisateur peut tre utilise comme une fonction window
(voir Section 9.18, Fonctions d'agrgat pour une liste des agrgats internes). Les fonctions d'agrgat agissent comme des fonctions window seulement quand une clause OVER suit l'appel ; sinon elles agissent comme des agrgats standards.
Tableau 9.44. Fonctions Window gnralistes

Fonction

Type renvoy

Description

row_number()

bigint

numro de la ligne en cours de traitement


dans sa partition, en comptant partir de 1

rank()

bigint

rang de la ligne en cours de traitement,


avec des trous ; identique row_number
pour le premier pair

dense_rank()

bigint

rang de la ligne en cours de traitement,


sans trous ; cette fonction compte les
groupes de pairs

percent_rank()

double precision

rang relatif de la ligne en cours de traitement ;: (rank - 1) / (nombre total de


lignes - 1)

cume_dist()

double precision

rang relatif de la ligne en cours de traitement : (nombre de lignes prcdentes, ou


pair de la ligne en cours) / (nombre de
lignes total)

ntile(num_buckets integer)

integer

entier allant de 1 la valeur de l'argument,


divisant la partition aussi quitablement
que possible

lag(value any [, offset in- mme type que value


teger [, default any ]])

187

renvoie value valu la ligne qui est


offset lignes avant la ligne actuelle
l'intrieur de la partition ; s'il n'y a pas de
ligne, renvoie la place default. offset et default sont valus par rapport
la ligne en cours. Si omis, offset a
comme valeur par dfaut 1 et default
est NULL

Fonctions et oprateurs

Fonction

Type renvoy

Description

lead(value any [, offset in- same type as value


teger [, default any ]])

renvoie value valu la ligne qui est


offset lignes aprs la ligne actuelle
l'intrieur de la partition ; s'il n'y a pas de
ligne, renvoie la place default. offset et default sont valus par rapport
la ligne en cours. Si omis, offset a
comme valeur par dfaut 1 et default
est NULL

first_value(value any)

mme type que value

renvoie value value la ligne qui est


la premire ligne du frame window

last_value(value any)

mme type que value

renvoie value value la ligne qui est


la dernire ligne du frame window

nth_value(value any, nth in- mme type que value


teger)

renvoie value value la ligne qui est


lanth-ime ligne de la frame window (en
comptant partir de 1) ; NULL si aucune
ligne

Toutes les fonctions listes dans Tableau 9.44, Fonctions Window gnralistes dpendent du tri indiqu par la clause ORDER
BY de la dfinition window associe. Les lignes qui ne sont pas distinctes dans le tri ORDER BY sont des pairs ; les quatre fonctions de rang sont dfinies de ce faon ce qu'elles donnent la mme rponse pour toutes les lignes pairs.
Notez que first_value, last_value et nth_value considrent seulement les lignes l'intrieur du frame window qui
contient par dfaut les lignes du dbut de la partition jusqu'au dernier pair de la ligne en cours. Cela risque de donenr des rsultats
peu intressants pour last_value et quelque fois aussi pour nth_value. Vous pouvez redfinir la frame en ajoutant une spcification convenable de frame (avec RANGE ou ROWS) dans la clause OVER. Voir Section 4.2.8, Appels de fonction de fentrage pour plus d'informations sur les spcifications de la frame.
Quand une fonction d'agrgat est utilise comme fonction window, il aggrge les lignes sur le frame window de la ligne en cours
de traitement. Pour obtenir un agrgat sur la partition complte, omettez ORDER BY ou utilisez ROWS BETWEEN UNBOUNDED
PRECEDING AND UNBOUNDED FOLLOWING. Un agrgat utilis avec ORDER BY et la dfinition de la frame window par dfaut produit un comportement de type somme en cours d'excution , qui pourrait ou ne pas tre souhait.

Note
Le standard SQL dfinit une option RESPECT NULLS ou IGNORE NULLS pour lead, lag, first_value,
last_value et nth_value. Ceci n'est pas implant dans PostgreSQL : le comportement est toujours le
mme que dans le comportement par dfaut du standard, nommment RESPECT NULLS. De la mme faon, les
options FROM FIRST ou FROM LAST pour nth_value ne sont pas implantes : seul le comportement FROM
FIRST est support par dfaut. (Vous pouvez obtenir le rsultat d'un FROM LAST en inversant l'ordre du ORDER
BY.)

9.20. Expressions de sous-requtes


Cette section dcrit les expressions de sous-requtes compatibles SQL disponibles sous PostgreSQL. Toutes les formes
d'expressions documentes dans cette section renvoient des rsultats boolens (true/false).

9.20.1. EXISTS
EXISTS ( sous-requte )
L'argument d'EXISTS est une instruction SELECT arbitraire ou une sous-requte. La sous-requte est value pour dterminer si
elle renvoie des lignes. Si elle en renvoie au moins une, le rsultat d'EXISTS est vrai ( true ) ; si elle n'en renvoie aucune, le rsultat d'EXISTS est faux ( false ).
La sous-requte peut faire rfrence des variables de la requte englobante qui agissent comme des constantes chaque valuation de la sous-requte.
La sous-requte n'est habituellement pas excute plus qu'il n'est ncessaire pour dterminer si au moins une ligne est renvoye.
Elle n'est donc pas forcment excute dans son intgralit. Il est de ce fait fortement dconseill d'crire une sous-requte qui prsente des effets de bord (tels que l'appel de fonctions de squence) ; il est extrmement difficile de prdire si ceux-ci se produisent.
188

Fonctions et oprateurs

Puisque le rsultat ne dpend que d'un ventuel retour de lignes, et pas de leur contenu, la liste des champs retourns par la sousrequte n'a normalement aucun intrt. Une convention de codage habituelle consiste crire tous les tests EXISTS sous la forme
EXISTS(SELECT 1 WHERE ...). Il y a toutefois des exceptions cette rgle, comme les sous-requtes utilisant INTERSECT.
L'exemple suivant, simpliste, ressemble une jointure interne sur col2 mais il sort au plus une ligne pour chaque ligne de tab1,
mme s'il y a plusieurs correspondances dans les lignes de tab2 :
SELECT col1
FROM tab1
WHERE EXISTS(SELECT 1 FROM tab2 WHERE col2 = tab1.col2);

9.20.2. IN
expression IN (sous-requte)
Le ct droit est une sous-expression entre parenthses qui ne peut retourner qu'une seule colonne. L'expression de gauche est value et compare chaque ligne du rsultat de la sous-requte. Le rsultat de IN est vrai ( true ) si une ligne quivalente de la
sous-requte est trouve. Le rsultat est faux ( false ) si aucune ligne correspondante n'est trouve (ce qui inclut le cas spcial de
la sous-requte ne retournant aucune ligne).
Si l'expression de gauche est NULL ou s'il n'existe pas de correspondance avec les valeurs du ct droit et qu'au moins une ligne
du ct droit est NULL, le rsultat de la construction IN est NULL, et non faux. Ceci est en accord avec les rgles normales du
SQL pour les combinaisons boolennes de valeurs NULL.
Comme avec EXISTS, on ne peut pas assumer que la sous-requte est value compltement.
constructeur_ligne IN (sous-requte)
Le ct gauche de cette forme de IN est un constructeur de ligne comme dcrit dans la Section 4.2.13, Constructeurs de lignes .
Le ct droit est une sous-requte entre parenthses qui doit renvoyer exactement autant de colonnes qu'il y a d'expressions dans le
ct gauche. Les expressions ct gauche sont values et compares ligne ligne au rsultat de la sous-requte. Le rsultat de IN
est vrai ( true ) si une ligne quivalente de la sous-requte est trouve. Le rsultat est faux ( false ) si aucune ligne correspondante n'est trouve (ce qui inclut le cas spcial de la sous-requte ne retournant aucune ligne).
Comme d'habitude, les valeurs NULL dans les lignes sont combines suivant les rgles habituelles des expressions boolennes
SQL. Deux lignes sont considres gales si tous leurs membres correspondant sont non nuls et gaux ; les lignes diffrent si le
contenu de leurs membres sont non nuls et diffrents ; sinon le rsultat de la comparaison de la ligne est inconnu, donc nul. Si tous
les rsultats par lignes sont diffrents ou nuls, avec au moins un NULL, alors le rsultat de IN est nul.

9.20.3. NOT IN
expression NOT IN (sous-requte)
Le ct droit est une sous-requte entre parenthses, qui doit retourner exactement une colonne. L'expression de gauche est valu
et compare chaque ligne de rsultat de la sous-requte. Le rsultat de NOT IN n'est true que si des lignes diffrentes de la
sous-requte sont trouves (ce qui inclut le cas spcial de la sous-requte ne retournant pas de ligne). Le rsultat est false si
une ligne gale est trouve.
Si l'expression de gauche est nulle, ou qu'il n'y a pas de valeur gale droite et qu'au moins une ligne de droite est nulle, le rsultat
du NOT IN est nul, pas vrai. Cela concorde avec les rgles normales du SQL pour les combinaisons boulennes de valeurs nulles.
Comme pour EXISTS, on ne peut assumer que la sous-requte est value dans son intgralit.
constructeur_ligne NOT IN (sous-requte)
Le ct gauche de cette forme de NOT IN est un constructeur de lignes, comme dcrit dans la Section 4.2.13, Constructeurs de
lignes . Le ct droit est une sous-requte entre parenthses qui doit renvoyer exactement autant de colonnes qu'il y a
d'expressions dans la ligne de gauche. Les expressions de gauche sont values et compare ligne ligne au rsultat de la sousrequte. Le rsultat de NOT IN n'est vrai ( true ) que si seules des lignes diffrentes de la sous-requte sont trouves (ce qui inclut le cas spcial de la sous-requte ne retournant aucune ligne). Le rsultat est faux ( false ) si une ligne gale est trouve.
Comme d'habitude, les valeurs nulles des lignes sont combines en accord avec les rgles normales des expressions boulennes
SQL. Deux lignes sont considres gales si tous leurs membres correspondants sont non-nuls et gaux ; les lignes sont diffrentes
si les membres correspondants sont non-nuls et diffrents ; dans tous les autres cas, le rsultat de cette comparaison de ligne est inconnu (nul). Si tous les rsultats par ligne sont diffrents ou nuls, avec au minimum un nul, alors le rsultat du NOT IN est nul.

189

Fonctions et oprateurs

9.20.4. ANY/SOME
expression oprateur ANY (sous-requte)
expression oprateur SOME (sous-requte)
Le ct droit est une sous-requte entre parenthses qui ne doit retourner qu'une seule colonne. L'expression du ct gauche est
value et compare chaque ligne du rsultat de la sous-requte l'aide de l'oprateur indiqu, ce qui doit aboutir un rsultat boolen. Le rsultat de ANY est vrai ( true ) si l'un des rsultats est vrai. Le rsultat est faux ( false ) si aucun rsultat vrai
n'est trouv (ce qui inclut le cas spcial de la requte ne retournant aucune ligne).
SOME est un synonyme de ANY. IN est quivalent = ANY.
En l'absence de succs, mais si au moins une ligne du ct droit conduit NULL avec l'oprateur, le rsultat de la construction
ANY est nul et non faux. Ceci est en accord avec les rgles standard SQL pour les combinaisons boolenne de valeurs NULL.
Comme pour EXISTS, on ne peut assumer que la sous-requte est value entirement.
constructeur_ligne operator ANY (sous-requte)
constructeur_ligne operator SOME (sous-requte)
Le ct gauche de cette forme ANY est un constructeur de ligne, tel que dcrit dans la Section 4.2.13, Constructeurs de lignes .
Le ct droit est une sous-requte entre parenthses, qui doit renvoyer exactement autant de colonnes qu'il y a d'expressions dans
la ligne de gauche. Les expressions du ct gauche sont values et compares ligne ligne au rsultat de la sous-requte l'aide
de l'oprateur donn. Le rsultat de ANY est true si la comparaison renvoie true pour une ligne quelconque de la sousrequte. Le rsultat est false si la comparaison renvoie false pour chaque ligne de la sous-requte (ce qui inclut le cas spcial
de la sous-requte ne retournant aucune ligne). Le rsultat est NULL si la comparaison ne renvoie true pour aucune ligne, et renvoie NULL pour au moins une ligne.
Voir Section 9.21.5, Comparaison de lignes entires pour la signification dtaille d'une comparaison ligne ligne.

9.20.5. ALL
expression oprateur ALL
(sous-requte)
Le ct droit est une sous-requte entre parenthses qui ne doit renvoyer qu'une seule colonne. L'expression gauche est value et
compare chaque ligne du rsultat de la sous-requte l'aide de l'oprateur, ce qui doit renvoyer un rsultat boolen. Le rsultat de ALL est vrai ( true ) si toutes les lignes renvoient true (ce qui inclut le cas spcial de la sous-requte ne retournant aucune ligne). Le rsultat est faux ( false ) si un rsultat faux est dcouvert. Le rsultat est NULL si la comparaison ne renvoie
false pour aucune ligne, mais NULL pour au moins une ligne.
NOT IN est quivalent <> ALL.
Comme pour EXISTS, on ne peut assumer que la sous-requte est value entirement.
constructeur_ligne oprateur ALL (sous-requte)
Le ct gauche de cette forme de ALL est un constructeur de lignes, tel que dcrit dans la Section 4.2.13, Constructeurs de
lignes . Le ct droit est une sous-requte entre parenthses qui doit renvoyer exactement le mme nombre de colonnes qu'il y a
d'expressions dans la colonne de gauche. Les expressions du ct gauche sont values et compares ligne ligne au rsultat de la
sous-requte l'aide de l'oprateur donn. Le rsultat de ALL est true si la comparaison renvoie true pour toutes les lignes
de la sous-requte (ce qui inclut le cas spcial de la sous-requte ne retournant aucune ligne). Le rsultat est false si la comparaison renvoie false pour une ligne quelconque de la sous-requte. Le rsultat est NULL si la comparaison ne renvoie false pour
aucune ligne de la sous-requte, mais NULL pour au moins une ligne.
Voir Section 9.21.5, Comparaison de lignes entires pour la signification dtaille d'une comparaison ligne ligne.

9.20.6. Comparaison de lignes


constructeur_ligne oprateur (sous-requte)
Le ct gauche est un constructeur de lignes, tel que dcrit dans la Section 4.2.13, Constructeurs de lignes . Le ct droit est
une sous-requte entre parenthses qui doit renvoyer exactement autant de colonnes qu'il y a d'expressions du ct gauche. De
plus, la sous-requte ne peut pas renvoyer plus d'une ligne. (Si elle ne renvoie aucune ligne, le rsultat est considr nul.) Le ct
gauche est valu et compar ligne complte avec la ligne de rsultat de la sous-requte.
Voir Section 9.21.5, Comparaison de lignes entires pour plus de dtails sur la signification d'une comparaison ligne ligne.

190

Fonctions et oprateurs

9.21. Comparaisons de lignes et de tableaux


Cette section dcrit des constructions adaptes aux comparaisons entre groupes de valeurs. Ces formes sont syntaxiquement lies
aux formes des sous-requtes de la section prcdente, mais elles n'impliquent pas de sous-requtes. Les formes qui impliquent
des sous-expressions de tableaux sont des extensions de PostgreSQL ; le reste est compatible avec SQL. Toutes les formes
d'expression documentes dans cette section renvoient des rsultats boolens (true/false).

9.21.1. IN
expression IN (valeur [, ...])
Le ct droit est une liste entre parenthses d'expressions scalaires. Le rsultat est vrai ( true ) si le ct gauche de l'expression
est gal une des expressions du ct droit. C'est une notation raccourcie de
expression = valeur1
OR
expression = valeur2
OR
...
Si l'expression du ct gauche renvoie NULL, ou s'il n'y a pas de valeur gale du ct droit et qu'au moins une expression du ct
droit renvoie NULL, le rsultat de la construction IN est NULL et non pas faux. Ceci est en accord avec les rgles du standard
SQL pour les combinaisons boolennes de valeurs NULL.

9.21.2. NOT IN
expression NOT IN (valeur [, ...])
Le ct droit est une liste entre parenthses d'expressions scalaires. Le rsultat est vrai ( true ) si le rsultat de l'expression du
ct gauche est diffrent de toutes les expressions du ct droit. C'est une notation raccourcie de
expression <> valeur1
AND
expression <> valeur2
AND
...
Si l'expression du ct gauche renvoie NULL, ou s'il existe des valeurs diffrentes du ct droit et qu'au moins une expression du
ct droit renvoie NULL, le rsultat de la construction NOT IN est NULL et non pas vrai. Ceci est en accord avec les rgles du
standard du SQL pour les combinaisons boolennes de valeurs NULL.

Astuce
x NOT IN y est quivalent NOT (x IN y) dans tout les cas. Nanmoins, les valeurs NULL ont plus de
chances de surprendre le novice avec NOT IN qu'avec IN. Quand cela est possible, il est prfrable d'exprimer la
condition de faon positive.

9.21.3. ANY/SOME (array)


expression oprateur ANY (expression tableau)
expression oprateur SOME (expression tableau)
Le ct droit est une expression entre parenthses qui doit renvoyer une valeur de type array. L'expression du ct gauche est value et compare chaque lment du tableau en utilisant l'oprateur donn, qui doit renvoyer un rsultat boolen. Le rsultat
de ANY est vrai ( true ) si un rsultat vrai est obtenu. Le rsultat est faux ( false ) si aucun rsultat vrai n'est trouv (ce qui inclut le cas spcial du tableau qui ne contient aucun lment).
Si l'expression de tableau ramne un tableau NULL, le rsultat de ANY est NULL. Si l'expression du ct gauche retourne NULL,
le rsultat de ANY est habituellement NULL (bien qu'un oprateur de comparaison non strict puisse conduire un rsultat diffrent). De plus, si le tableau du ct droit contient des lments NULL et qu'aucune comparaison vraie n'est obtenue, le rsultat de
ANY est NULL, et non pas faux ( false ) (l aussi avec l'hypothse d'un oprateur de comparaison strict). Ceci est en accord
avec les rgles du standard SQL pour les combinaisons boolennes de valeurs NULL.
SOME est un synonyme de ANY.

191

Fonctions et oprateurs

9.21.4. ALL (array)


expression oprateur ALL (expression tableau)
Le ct droit est une expression entre parenthses qui doit renvoyer une valeur de type tableau. L'expression du ct gauche est
value et compare chaque lment du tableau l'aide de l'oprateur donn, qui doit renvoyer un rsultat boolen. Le rsultat de ALL est vrai ( true ) si toutes les comparaisons renvoient vrai (ce qui inclut le cas spcial du tableau qui ne contient aucun
lment). Le rsultat est faux ( false ) si un rsultat faux est trouv.
Si l'expression de tableau ramne un tableau NULL, le rsultat de ALL est NULL. Si l'expression du ct gauche retourne NULL,
le rsultat de ALL est habituellement NULL (bien qu'un oprateur de comparaison non strict puisse conduire un rsultat diffrent). De plus, si le tableau du ct droit contient des lments NULL et qu'aucune comparaison false n'est obtenue, le rsultat de
ALL est NULL, et non pas true (l aussi avec l'hypothse d'un oprateur de comparaison strict). Ceci est en accord avec les rgles
du standard SQL pour les combinaisons boolennes de valeurs NULL.

9.21.5. Comparaison de lignes entires


constructeur_ligne oprateur constructeur_ligne
Chaque ct est un constructeur de lignes, tel que dcrit dans la Section 4.2.13, Constructeurs de lignes . Les deux valeurs de
lignes doivent avoir le mme nombre de lignes. Chaque ct est valu. Ils sont alors compars sur toute la ligne. Les comparaisons de lignes sont autorises quand l'oprateur est =, <>, <, <=, >, >=, ou a une smantique similaire l'un d'eux. (Pour tre
prcis, un oprateur peut tre un oprateur de comparaison de ligne s'il est membre d'une classe d'oprateurs B-Tree ou est le ngateur du membre = d'une classe d'oprateurs B-Tree.)
Les cas = et <> fonctionnent lgrement diffremment des autres. Les lignes sont considres gales si leurs membres correspondants sont non-nuls et gaux ; les lignes sont diffrentes si des membres correspondants sont non-nuls et diffrents ; autrement, le
rsultat de la comparaison de ligne est inconnu (NULL).
Pour les cas <, <=, > et >=, les lments de ligne sont compars de gauche droite. La comparaison s'arrte ds qu'une paire
d'lments diffrents ou NULL est dcouverte. Si un des lments de cette paire est NULL, le rsultat de la comparaison de la
ligne est inconnu, donc NULL ; sinon la comparaison de cette paire d'lments dtermine le rsultat. Par exemple,
ROW(1,2,NULL) < ROW(1,3,0) est vrai, non NULL, car la troisime paire d'lments n'est pas considre.

Note
Avant PostgreSQL 8.2, les cas <, <=, > et >= n'taient pas grs d'aprs les spcifications SQL. Une comparaison comme ROW(a,b) < ROW(c,d) tait code sous la forme a < c AND b < d alors que le bon comportement est quivalent a < c OR (a = c AND b < d).
constructeur_ligne IS DISTINCT FROM constructeur_ligne
Cette construction est similaire une comparaison de ligne <>, mais elle ne conduit pas un rsultat NULL pour des entres
NULL. Au lieu de cela, une valeur NULL est considre diffrente (distincte) d'une valeur non-NULL et deux valeurs NULL sont
considres gales (non distinctes). Du coup, le rsultat est toujours soit true soit false, jamais NULL.
constructeur_ligne IS NOT DISTINCT FROM constructeur_ligne
Cette construction est similaire une comparaison de lignes =, mais elle ne conduit pas un rsultat NULL pour des entres
NULL. Au lieu de cela, une valeur NULL est considre diffrente (distincte) d'une valeur non NULL et deux valeurs NULL sont
considres identiques (non distinctes). Du coup, le rsultat est toujours soit true soit false, jamais NULL.

Note
Le standard SQL requiert qu'une comparaison d'une ligne complte renvoie NULL si le rsultat dpend de la comparaison de deux valeurs NULL ou d'une valeur NULL et d'une valeur non NULL. PostgreSQL le fait en comparant le rsultat de deux constructeurs de lignes ou en comparant un constructeur de ligne avec le rsultat d'une sousrequte (comme dans Section 9.20, Expressions de sous-requtes ). Dans d'autres contextes o deux valeurs de
type composite sont compares, deux champs NULL sont considrs gaux, et un champ NULL est considr plus
grand qu'un champ non NULL. Ceci est ncessaire pour voir un comportement de tri et d'indexage cohrent pour
les types composites.

192

Fonctions et oprateurs

9.22. Fonctions retournant des ensembles


Cette section dcrit des fonctions qui peuvent renvoyer plus d'une ligne. Actuellement, les seules fonctions dans cette classe sont
les fonctions de gnration de sries, dtailles dans le Tableau 9.45, Fonctions de gnration de sries et Tableau 9.46,
Fonctions de gnration d'indices .
Tableau 9.45. Fonctions de gnration de sries

Fonction

Type
d'argument

Type de retour

Description

generate_series
fin)

(dbut, int ou bigint

setof int ou setof Produit une srie de valeurs, de dbut fin avec un
bigint
(mme incrment de un.
type que l' argument)

generate_series
fin, pas)

(dbut, int ou bigint

setof int ou setof Produit une srie de valeurs, de dbut fin avec un
bigint
(mme incrment de pas.
type
que
l'argument)

generate_series(dbut,
fin, pas interval)

timestamp ou ti- setof timestamp Gnre une srie de valeurs, allant de start stop
mestamp
with ou setof times- avec une taille pour chaque tape de pas
time zone
tamp with time
zone (identique
au
type
de
l'argument)

Quand pas est positif, aucune ligne n'est renvoye si dbut est suprieur fin. l'inverse, quand pas est ngatif, aucune
ligne n'est renvoye si dbut est infrieur fin. De mme, aucune ligne n'est renvoye pour les entres NULL. Une erreur est
leve si pas vaut zro.
Quelques exemples :
SELECT * FROM generate_series(2,4);
generate_series
----------------2
3
4
(3 rows)
SELECT * FROM generate_series(5,1,-2);
generate_series
----------------5
3
1
(3 rows)
SELECT * FROM generate_series(4,3);
generate_series
----------------(0 rows)
-- cet exemple se base sur l'oprateur date-plus-entier
SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a);
dates
-----------2004-02-05
2004-02-12
2004-02-19
(3 rows)
SELECT * FROM generate_series('2008-03-01 00:00'::timestamp,
'2008-03-04 12:00', '10 hours');
generate_series
--------------------193

Fonctions et oprateurs

2008-03-01
2008-03-01
2008-03-01
2008-03-02
2008-03-02
2008-03-03
2008-03-03
2008-03-03
2008-03-04
(9 rows)

00:00:00
10:00:00
20:00:00
06:00:00
16:00:00
02:00:00
12:00:00
22:00:00
08:00:00

Tableau 9.46. Fonctions de gnration d'indices

Nom

Type de retour

Description

generate_subscripts(array
anyarray, dim int)

setof int

Gnre une srie comprenant les indices du tableau donn.

generate_subscripts(array
setof int
anyarray, dim int, reverse
boolean)

Gnre une srie comprenant les indices du tableau donn.


Quand reverse vaut true, la srie est renvoy en ordre inverse.

generate_subscripts est une fonction qui gnre un ensemble d'indices valides pour la dimension indique du tableau
fourni. Aucune ligne n'est renvoye pour les tableaux qui n'ont pas la dimension requise ou pour les tableaux NULL (mais les indices valides sont renvoyes pour les lments d'un tableau NULL). Quelques exemples suivent :
-- usage basique
SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s;
s
--1
2
3
4
(4 rows)
-- presenting an array, the subscript and the subscripted
-- value requires a subquery
SELECT * FROM arrays;
a
-------------------{-1,-2}
{100,200,300}
(2 rows)
SELECT a AS array, s AS subscript, a[s] AS value
FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo;
array
| subscript | value
---------------+-----------+------{-1,-2}
|
1 |
-1
{-1,-2}
|
2 |
-2
{100,200,300} |
1 |
100
{100,200,300} |
2 |
200
{100,200,300} |
3 |
300
(5 rows)
-- aplatir un tableau 2D
CREATE OR REPLACE FUNCTION unnest2(anyarray)
RETURNS SETOF anyelement AS $$
select $1[i][j]
from generate_subscripts($1,1) g1(i),
generate_subscripts($1,2) g2(j);
$$ LANGUAGE sql IMMUTABLE;
CREATE FUNCTION
postgres=# SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]);
unnest2
--------194

Fonctions et oprateurs

1
2
3
4
(4 rows)

9.23. Fonctions d'informations systme


Le Tableau 9.47, Fonctions d'information de session prsente diverses fonctions qui extraient des informations de session et
systme.
En plus des fonctions listes dans cette section, il existe plusieurs fonctions relatives au systme de statistiques qui fournissent
aussi des informations systme. Voir Section 27.2.2, Visualiser les statistiques rcupres pour plus d'informations.
Tableau 9.47. Fonctions d'information de session

Nom

Type de retour

Description

current_catalog

name

nom de la base de donnes en cours (appele


catalog dans le standard SQL)

current_database()

nom

nom de la base de donnes courante

current_query()

text

texte de la requte en cours d'excution, tel qu'elle


a t soumise par le client (pourrait contenir plus
d'une instruction)

current_schema[()]

nom

nom du schma courant

current_schemas(boolean)

nom[]

nom des schmas dans le chemin de recherche,


avec optionnellement les schmas implicites

current_user

nom

nom d'utilisateur du contexte d'excution courant

inet_client_addr()

inet

adresse de la connexion distante

inet_client_port()

int

port de la connexion distante

inet_server_addr()

inet

adresse de la connexion locale

inet_server_port()

int

port de la connexion locale

pg_backend_pid()

int

Identifiant du processus serveur attach la session en cours

pg_conf_load_time()

timestamp with time zone

date et heure du dernier chargement de la configuration

pg_is_other_temp_schema(oid) boolean

s'agit-il du schma temporaire d'une autre session ?

pg_listening_channels()

setof text

noms des canaux que la session est en train


d'couter

pg_my_temp_schema()

oid

OID du schma temporaire de la session, 0 si aucun

pg_postmaster_start_time()

timestamp with time zone

date et heure du dmarrage du serveur

session_user

name

nom de l'utilisateur de session

user

name

quivalent current_user

version()

text

informations de version de PostgreSQL

Note
current_catalog, current_schema, current_user, session_user, et user ont un statut syntaxique spcial en SQL : ils doivent tre appels sans parenthses droite (optionnel avec PostgreSQL dans le cas
de current_schema).
session_user est habituellement l'utilisateur qui a initi la connexion la base de donnes ; mais les superutilisateurs peuvent
modifier ce paramtrage avec SET SESSION AUTHORIZATION(7). current_user est l'identifiant de l'utilisateur, utilisable
pour les vrifications de permissions. Il est habituellement identique l'utilisateur de la session, mais il peut tre modifi avec
195

Fonctions et oprateurs

SET ROLE(7). Il change aussi pendant l'excution des fonctions comprenant l'attribut SECURITY DEFINER. En langage Unix,
l'utilisateur de la session est le real user (NdT : l'utilisateur rel) et l'utilisateur courant est l' effective user (NdT :
l'utilisateur effectif) .
current_schema renvoie le nom du premier schma dans le chemin de recherche (ou une valeur NULL si ce dernier est vide).
C'est le schma utilis pour toute cration de table ou autre objet nomm sans prcision d'un schma cible. current_schemas(boolean) renvoie un tableau qui contient les noms de tous les schmas du chemin de recherche. L'option
boolenne indique si les schmas systme implicitement inclus, comme pg_catalog, doivent tre inclus dans le chemin de recherche retourn.

Note
Le chemin de recherche est modifiable l'excution. La commande est :
SET search_path TO schema [, schema, ...]
pg_listening_channels renvoie un ensemble de noms de canaux que la session actuelle coute. Voir LISTEN(7) pour plus
d'informations.
inet_client_addr renvoie l'adresse IP du client courant et inet_client_port le numro du port. inet_server_addr renvoie l'adresse IP sur laquelle le serveur a accept la connexion courante et inet_server_port le numro du port. Toutes ces fonctions renvoient NULL si la connexion courante est tablie via une socket de domaine Unix.
pg_my_temp_schema renvoie l'OID du schma temporaire de la session courante, ou 0 s'il n'existe pas (parce qu'il n'y a pas eu
de cration de tables temporaires). pg_is_other_temp_schema renvoie true si l'OID donn est l'OID d'un schma temporaire d'une autre session. (Ceci peut tre utile pour exclure les tables temporaires d'autres sessions lors de l'affichage d'un catalogue, par exemple.)
pg_postmaster_start_time renvoie la date et l'heure (type timestamp with time zone) de dmarrage du serveur.
pg_conf_load_time renvoie timestamp with time zone indiquant quel moment les fichiers de configuration du serveur ont
t chargs. (Si la session en cours tait dj l ce moment, ce sera le moment o la sessions elle-mme a relu les fichiers de
configurations. Cela veut dire que ce que renvoie cette fonction peut varier un peu suivant les sessions. Sinon, c'est le temps o le
processus matre a relu les fichiers de configuration.)
version renvoie une chane qui dcrit la version du serveur PostgreSQL.
Le Tableau 9.48, Fonctions de consultation des privilges d'accs liste les fonctions qui permettent aux utilisateurs de consulter les privilges d'accs. Voir la Section 5.6, Droits pour plus d'informations sur les privilges.
Tableau 9.48. Fonctions de consultation des privilges d'accs

Nom

Type de retour

Description

use
has_any_column_privilege(r,
table, privilege)

boolean

l'utilisateur a-t-il un droit sur une des colonnes de cette table

tab
boolean
has_any_column_privilege(le,
privilege)

l'utilisateur actuel a-t-il un droit sur une


des colonnes de cette table

has_column_privilege(user,
table, column, privilege)

boolean

l'utilisateur a-t-il un droit sur la colonne

has_column_privilege(table,
column, privilege)

boolean

l'utilisateur actuel a-t-il un droit sur la colonne

has_database_privilege (uti- boolean


lisateur, base, privilge)

utilisateur a-t-il le privilge privilge sur base

boolean

l'utilisateur courant a-t-il le privilge


privilge sur base

has_foreign_data_wrapper_pri boolean
vilege(user, fdw, privilege)

l'utilisateur a-t-il un droit sur ce wrapper


de donnes distantes

has_foreign_data_wrapper_pri boolean
vilege(fdw, privilege)

l'utilisateur actuel a-t-il un droit sur ce


wrapper de donnes distantes

has_function_privilege (uti- boolean

utilisateur a-t-il le privilge pri-

has_database_privilege
(base, privilge)

196

Fonctions et oprateurs

Nom
lisateur,
lge)

Type de retour
fonction,

Description
vilge sur fonction

priviboolean

l'utilisateur courant a-t-il e privilge privilge sur fonction

has_language_privilege (uti- boolean


lisateur,
langage,
privilge)

utilisateur a-t-il le privilge privilge sur langage

has_language_privilege (lan- boolean


gage, droit)

l'utilisateur courant a-t-il le privilge


privilge sur langage

boolean

utilisateur a-t-il le privilge privilge sur schma

has_schema_privilege(schma, boolean
privilge)

l'utilisateur courant a-t-il le privilge


privilge sur schma

has_sequence_privilege(user, boolean
sequence, privilege)

l'utilisateur a-t-il un droit sur cette squence

has_sequence_privilege(sequence, privilege)

boolean

l'utilisateur actuel a-t-il un droit sur cette


squence

has_server_privilege(user,
server, privilege)

boolean

l'utilisateur actuel a-t-il un droit sur ce serveur

has_server_privilege(server, boolean
privilege)

l'utilisateur actuel a-t-il un droit sur ce serveur

has_table_privilege(utilisa- boolean
teur, table, privilge)

utilisateur a-t-il le privilge privilge sur table

boolean

l'utilisateur courant a-t-il le privilge


privilge sur table

has_tablespace_privilege
boolean
(utilisateur,
tablespace,
privilge)

utilisateur a-t-il le privilge privilge sur tablespace

has_tablespace_privilege
(tablespace, privilge)

boolean

l'utilisateur courant a-t-il le privilge


privilge sur tablespace

pg_has_role(utilisateur,
rle, privilge)

boolean

utilisateur a-t-il le privilge privilge sur rle

pg_has_role(rle, privilge) boolean

l'utilisateur courant a-t-il le privilge


privilge sur rle

has_function_privilege
(fonction, privilge)

has_schema_privilege(utilisateur, schma, privilge)

has_table_privilege(table,
privilege)

has_table_privilege vrifie si l'utilisateur possde un privilge particulier d'accs une table. L'utilisateur peut tre indiqu par son nom ou son OID (pg_authid.oid), public pour indiquer le pseudo-rle PUBLIC. Si l'argument est omis, current_user est utilis. La table peut tre indique par son nom ou par son OID. (Il existe donc six versions de
has_table_privilege qui se distinguent par le nombre et le type de leurs arguments.) Lors de l'indication par nom, il est
possible de prciser le schma. Les privilges possibles, indiqus sous la forme d'une chane de caractres, sont : SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES ou TRIGGER. En option, WITH GRANT OPTION peut tre ajout un
type de droit pour tester si le droit est obtenu avec l'option grant . De plus, plusieurs types de droit peuvent tre lists, spars
par des virgules, auquel cas le rsultat sera true si un des droits lists est obtenu. (la casse des droits n'a pas d'importance et les
espaces blancs supplmentaires sont autoriss entre mais pas dans le nom des droits.) Certains exemples :
SELECT has_table_privilege('myschema.mytable', 'select');
SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION');
has_sequence_privilege vrifie si un utilisateur peut accder une squence d'une faon ou d'une autre. Les arguments
sont analogues ceux de la fonction has_table_privilege. Le type de droit d'accs doit valoir soit USAGE, soit SELECT
soit UPDATE.
has_any_column_privilege vrifie si un utilisateur peut accder une colonne d'une table d'une faon particulire. Les
possibilits pour que ces arguments correspondent ceux de has_table_privilege, sauf que le type de droit d'accs dsir
doit tre valu une combinaison de SELECT, INSERT, UPDATE ou REFERENCES. Notez qu'avoir un droit au niveau de la
197

Fonctions et oprateurs

table le donne implicitement pour chaque colonne de la table, donc has_any_column_privilege renverra toujours true si
has_table_privilege le fait pour les mmes arguments. Mais has_any_column_privilege russit aussi s'il y a un
droit grant sur une colonne pour ce droit.
has_column_privilege vrifie si un utilisateur peut accder une colonne d'une faon particulire. Les possibilits pour ses
arguments sont analogues has_table_privilege, avec un supplment : la colonne doit tre indique soit par nom soit par
numro d'attribut. Le type de droit d'accs dsir doit tre une combinaison de SELECT, INSERT, UPDATE ou REFERENCES.
Notez qu'avoir un de ces droits au niveau table les donne implicitement pour chaque colonne de la table.
has_database_privilege vrifie si un utilisateur peut accder une base de donnes d'une faon particulire. Les possibilits pour ses arguments sont analogues has_table_privilege. Le type de droit d'accs dsir doit tre une combinaison
de CREATE, CONNECT, TEMPORARY ou TEMP (qui est quivalent TEMPORARY).
has_function_privilege vrifie si un utilisateur peut accder une fonction d'une faon particulire. Les possibilits pour
ses arguments sont analogues has_table_privilege. Lors de la spcification d'une fonction par une chane texte plutt
que par un OID, l'entre autorise est la mme que pour le type de donnes regprocedure (voir Section 8.16, Types identifiant
d'objet ). Le type de droit d'accs dsir doit tre EXECUTE. Voici un exemple :
SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
has_foreign_data_wrapper_privilege vrifie si un utilisateur peut accder un wrapper de donnes distantes d'une
faon particulire. Les possibilits pour ses arguments sont analogues has_table_privilege. Le type de droit d'accs dsir doit tre USAGE.
has_language_privilege vrifie si un utilisateur peut accder un langage de procdure d'une faon particulire. Les possibilits pour ses arguments sont analogues has_table_privilege. Le type de droit d'accs dsir doit tre USAGE.
has_schema_privilege vrifie si un utilisateur peut accder un schma d'une faon particulire. Les possibilits pour ses
arguments sont analogues has_table_privilege. Le type de droits d'accs dsir doit tre une combinaison de CREATE et
USAGE.
has_server_privilege vrifie si un utilisateur peut accder un serveur distant d'une faon particulire. Les possibilits
pour ses arguments sont analogues has_table_privilege. Le type de droit d'accs dsir doit tre USAGE.
has_tablespace_privilege vrifie si l'utilisateur possde un privilge particulier d'accs un tablespace. Ses arguments
sont analogues has_table_privilege. Le seul privilge possible est CREATE.
pg_has_role vrifie si l'utilisateur possde un privilge particulier d'accs un rle. Ses arguments sont analogues
has_table_privilege, sauf que public n'est pas autoris comme nom d'utilisateur. Le privilge doit tre une combinaison
de MEMBER et USAGE. MEMBER indique une appartenance directe ou indirecte au rle (c'est--dire le droit d'excuter SET ROLE)
alors que USAGE indique que les droits du rle sont immdiatement disponibles sans avoir excuter SET ROLE.
Le Tableau 9.49, Fonctions d'interrogation de visibilit dans les schmas affiche les fonctions qui permettent de savoir si un
objet particulier est visible dans le chemin de recherche courant. Une table est dite visible si son schma contenant est dans le chemin de recherche et qu'aucune table de mme nom ne la prcde dans le chemin de recherche. C'est quivalent au fait que la table
peut tre rfrence par son nom sans qualification explicite de schma. Par exemple, pour lister les noms de toutes les tables visibles :
SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
Tableau 9.49. Fonctions d'interrogation de visibilit dans les schmas

Nom

Type de retour

Description

pg_collation_is_visible(collation_oid)

boolean

le collationnement est-il visible dans le


chemin de recherche

pg_conversion_is_visible (conversion_oid)

boolean

la conversion est-elle visible dans le chemin de recherche

pg_function_is_visible (function_oid)

boolean

la fonction est-elle visible dans le chemin


de recherche

pg_opclass_is_visible(opclass_oid)

boolean

la classe d'oprateur est-elle visible dans


le chemin de recherche

pg_operator_is_visible(operator_oid)

boolean

l'oprateur est-il visible dans le chemin de


recherche

pg_table_is_visible(table_oid)

boolean

la table est-elle visible dans le chemin de

198

Fonctions et oprateurs

Nom

Type de retour

Description
recherche

pg_ts_config_is_visible(config_oid)

boolean

la configuration de la recherche textuelle


est-elle visible dans le chemin de recherche

pg_ts_dict_is_visible(dict_oid)

boolean

le dictionnaire de recherche textuelle est-il


visible dans le chemin de recherche

pg_ts_parser_is_visible(parser_oid)

boolean

l'analyseur syntaxique de recherche textuelle est-il visible dans le chemin de recherche

pg_ts_template_is_visible(template_oid)

boolean

le modle de recherche textuelle est-il visible dans le chemin de recherche

pg_type_is_visible(type_oid)

boolean

le type (ou domaine) est-il visible dans le


chemin de recherche

Chaque fonction vrifie la visibilit d'un type d'objet de la base de donnes. pg_table_is_visible peut aussi tre utilise
avec des vues, index et squences, pg_type_is_visible avec les domaines. Pour les fonctions et les oprateurs, un objet est
visible dans le chemin de recherche si aucun objet de mme nom et prenant des arguments de mmes types de donnes n'est prcdemment prsent dans le chemin de recherche. Pour les classes d'oprateurs, on considre la fois le nom et la mthode d'accs
l'index associ.
Toutes ces fonctions ncessitent des OID pour identifier les objets vrifier. Pour tester un objet par son nom, il est prfrable
d'utiliser les types d'alias d'OID (regclass, regtype, regprocedure ou regoperator). Par exemple
SELECT pg_type_is_visible('mon_schema.widget'::regtype);
Il n'est pas trs utile de tester ainsi un nom non qualifi -- si le nom peut tre reconnu, c'est qu'il est visible.
Le Tableau 9.50, Fonctions d'information du catalogue systme liste les fonctions qui extraient des informations des catalogues systme.
Tableau 9.50. Fonctions d'information du catalogue systme

Nom

Type de retour Description

format_type (type_oid, typemod)

text

rcupre le nom SQL d'un type de donnes

ob- text

pg_describe_object(catalog_id,
ject_id, object_sub_id)

rcupre une description d'un objet de la base de donnes

pg_get_constraintdef(constraint_oid)

text

rcupre la dfinition d'une contrainte

pg_get_constraintdef(constraint_oid,
pretty_bool)

text

rcupre la dfinition d'une contrainte

pg_get_expr(pg_node_tree,
tion_oid)

rela- text

dcompile la forme interne d'une expression, en supposant que toutes les variables qu'elle contient font rfrence la relation indique par le second paramtre

pg_get_expr(pg_node_tree,
tion_oid, pretty_bool)

rela- text

dcompile la forme interne d'une expression, en supposant que toutes les variables qu'elle contient font rfrence la relation indique par le second paramtre

pg_get_functiondef(func_oid)

text

obtient une dfinition de la fonction

pg_get_function_arguments(func_oid)

text

obtient une dfinition de la liste des arguments de la


fonction (avec les valeurs par dfaut)

pg_get_function_identity_arguments
(func_oid)

text

obtient une dfinition de la liste des arguments de la


fonction (sans valeurs par dfaut)

pg_get_function_result(func_oid)

text

obtient la clause RETURNS pour la fonction

pg_get_indexdef(index_oid)

text

rcupre la commande CREATE INDEX de l'index

pg_get_indexdef(index_oid, column_no, text


pretty_bool)
pg_get_keywords()

rcupre la commande CREATE INDEX pour l'index,


ou la dfinition d'une seule colonne d'index quand column_no ne vaut pas zro

setof record
199

rcupre la liste des mots cls SQL et leur catgories

Fonctions et oprateurs

Nom

Type de retour Description

pg_get_ruledef(rule_oid)

text

rcupre la commande CREATE RULE pour une


rgle

pg_get_ruledef(rule_oid, pretty_bool) text

rcupre la commande CREATE RULE de la rgle

pg_get_serial_sequence(table_name,
column_name)

text

rcupre le nom de la squence qu'une colonne serial


ou bigserial utilise

pg_get_triggerdef(trigger_oid)

text

rcupre la commande CREATE [ CONSTRAINT ]


TRIGGER du trigger

pg_get_triggerdef(trigger_oid,
ty_bool)

pret- text

rcupre la commande CREATE [ CONSTRAINT ]


TRIGGER du dclencheur

pg_get_userbyid(role_oid)

name

rcupre le nom du rle possdant cet OID

pg_get_viewdef(view_name)

text

rcupre la commande SELECT sous-jacente la vue


(obsolte)

pg_get_viewdef(view_name,
pretty_bool)

text

rcupre la commande SELECT sous-jacente la vue


(obsolte)

pg_get_viewdef(view_oid)

text

rcupre la commande SELECT sous-jacente la vue

pg_get_viewdef(view_oid, pretty_bool) text

rcupre la commande SELECT sous-jacente la vue

pg_options_to_table(reloptions)

setof record

rcupre l'ensemble de paires nom/valeur des options


de stockage

pg_tablespace_databases(tablespace_oid)

setof oid

rcupre l'ensemble des OID des bases qui possdent


des objets dans ce tablespace

pg_typeof(any)

regtype

obtient le type de donnes de toute valeur

format_type renvoie le nom SQL d'un type de donnes identifi par son OID de type et ventuellement un modificateur de
type. On passe NULL pour le modificateur de type si aucun modificateur spcifique n'est connu.
pg_get_keywords renvoie un ensemble d'enregistrements dcrivant les mots cls SQL reconnus par le serveur. La colonne
word contient le mot cl. La colonne catcode contient un code de catgorie : U pour non rserv, C pour nom de colonne, T
pour nom d'un type ou d'une fonction et R pour rserv. La colonne catdesc contient une chane pouvant tre traduite dcrivant
la catgorie.
pg_get_constraintdef, pg_get_indexdef, pg_get_ruledef et pg_get_triggerdef reconstruisent respectivement la commande de cration d'une contrainte, d'un index, d'une rgle ou d'un dclencheur. (Il s'agit d'une reconstruction dcompile, pas du texte originale de la commande.) pg_get_expr dcompile la forme interne d'une expression individuelle, comme
la valeur par dfaut d'une colonne. Cela peut tre utile pour examiner le contenu des catalogues systme. Si l'expression contient
des variables, spcifiez l'OID de la relation laquelle elles font rfrence dans le second paramtre ; si aucune variable n'est attendue, zro est suffisant. pg_get_viewdef reconstruit la requte SELECT qui dfinit une vue. La plupart de ces fonctions
existent en deux versions, l'une d'elles permettant, optionnellement, d' afficher joliment le rsultat. Ce format est plus lisible,
mais il est probable que les futures versions de PostgreSQL continuent d'interprter le format par dfaut actuel de la mme
faon ; la version jolie doit tre vite dans les sauvegardes. Passer false pour le paramtre de jolie sortie conduit au
mme rsultat que la variante sans ce paramtre.
pg_get_functiondef renvoie une instruction CREATE OR REPLACE FUNCTION complte pour une fonction.
pg_get_function_arguments renvoie une liste des arguments d'un fonction, de la faon dont elle apparatrait dans
CREATE FUNCTION. pg_get_function_result renvoie de faon similaire la clause RETURNS approprie pour la fonction. pg_get_function_identity_arguments renvoie la liste d'arguments ncessaire pour identifier une fonction, dans
la forme qu'elle devrait avoir pour faire partie d'un ALTER FUNCTION, par exemple. Cette forme omet les valeurs par dfaut.
pg_get_serial_sequence renvoie le nom de la squence associe une colonne ou NULL si aucune squence n'est associe la colonne. Le premier argument en entre est un nom de table, ventuellement qualifi du schma. Le second paramtre est
un nom de colonne. Comme le premier paramtre peut contenir le nom du schma et de la table, il n'est pas trait comme un identifiant entre guillemets doubles, ce qui signifie qu'il est converti en minuscules par dfaut, alors que le second paramtre, simple
nom de colonne, est trait comme s'il tait entre guillemets doubles et sa casse est prserve. La fonction renvoie une valeur
convenablement formate pour tre traite par les fonctions de traitement des squences (voir Section 9.15, Fonctions de manipulation de squences ). Cette association peut tre modifie ou supprime avec ALTER SEQUENCE OWNED BY. (La fonction aurait probablement d s'appeler pg_get_owned_sequence ; son nom reflte le fait qu'elle est typiquement utilise avec
les colonnes serial et bigserial.)
pg_get_userbyid rcupre le nom d'un rle d'aprs son OID.
200

Fonctions et oprateurs

pg_options_to_table
renvoie
l'ensemble
de
paires
nom/valeur
des
options
de
(nom_option/valeur_option) quand lui est fourni pg_class.reloptions ou pg_attribute.attoptions.

stockage

pg_tablespace_databases autorise l'examen d'un tablespace. Il renvoie l'ensemble des OID des bases qui possdent des
objets stocks dans le tablespace. Si la fonction renvoie une ligne, le tablespace n'est pas vide et ne peut pas tre supprime. Pour
afficher les objets spcifiques peuplant le tablespace, il est ncessaire de se connecter aux bases identifies par
pg_tablespace_databases et de requter le catalogue pg_class.
pg_describe_object renvoie une description d'un objet de la base de donnes spcifie par l'OID du catalogue, l'OID de
l'objet et un identifiant de sous-objet (en option). C'est utile pour dterminer l'identit d'un objet tel qu'il est stock dans le catalogue pg_depend.
pg_typeof renvoie l'OID du type de donnes de la valeur qui lui est pass. Ceci est utile pour dpanner ou pour construire dynamiquement des requtes SQL. La fonction est dclare comme renvoyant regtype, qui est une type d'alias d'OID (voir Section 8.16, Types identifiant d'objet ) ; cela signifie que c'est la mme chose qu'un OID pour un bit de comparaison mais que cela s'affiche comme un nom de type. Par exemple :
SELECT pg_typeof(33);
pg_typeof
----------integer
(1 row)
SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
typlen
-------4
(1 row)
Les fonctions affiches dans Tableau 9.51, Fonctions d'informations sur les commentaires extraient les commentaires stockes
prcdemment avec la commande COMMENT(7). Une valeur NULL est renvoye si aucun commentaire ne correspond aux paramtres donns.
Tableau 9.51. Fonctions d'informations sur les commentaires

Nom

Type de retour Description

col_description(table_oid,
lumn_number)
obj_description
log_name)

(object_oid,

obj_description(object_oid)
shobj_description(object_oid,
log_name)

co- text

rcupre le commentaire d'une colonne de la table

cata- text

rcupre le commentaire d'un objet de la base de donnes

text

rcupre le commentaire d'un objet de la base de donnes (obsolte)

cata- text

rcupre le commentaire d'un objet partag de la base


de donnes

col_description renvoie le commentaire d'une colonne de table, la colonne tant prcise par l'OID de la table et son numro de colonne. obj_description ne peut pas tre utilise pour les colonnes de table car les colonnes n'ont pas d'OID propres.
La forme deux paramtres de obj_description renvoie le commentaire d'un objet de la base de donnes, prcis par son
OID et le nom du catalogue systme le contenant. Par exemple, obj_description(123456,'pg_class') rcupre le
commentaire pour la table d'OID 123456. La forme un paramtre de obj_description ne requiert que l'OID de l'objet. Elle
est maintenant obsolte car il n'existe aucune garantie que les OID soient uniques au travers des diffrents catalogues systme ; un
mauvais commentaire peut alors tre renvoy.
shobj_description est utilis comme obj_description, mais pour les commentaires des objets partags. Certains catalogues systmes sont globaux toutes les bases de donnes l'intrieur de chaque cluster et les descriptions des objets imbriqus
sont stockes globalement.
Les fonctions prsentes dans Tableau 9.52, ID de transaction et instantans remontent l'utilisateur des informations de transaction de niveau interne au serveur. L'usage principal de ces fonctions est de dterminer les transactions commites entre deux
instantans ( snapshots ).

201

Fonctions et oprateurs

Tableau 9.52. ID de transaction et instantans

Nom

Type retour

Description

txid_current()

bigint

rcupre l'ID de transaction courant

txid_current_snapshot()

txid_snapshot

rcupre l'instantan courant

txid_snaps
txid_snapshot_xip(hot)

setof bigint

rcupre l'ID de la transaction en cours dans l'instantan

txid_snap
txid_snapshot_xmax(shot)

bigint

rcupre le xmax de l'instantan

txid_snap
txid_snapshot_xmin(shot)

bigint

rcupre le xmin de l'instantan

txid_visible_in_snapshot(bi- boolean
gint, txid_snapshot)

l'ID de transaction est-il visible dans l'instantan ? (ne pas utiliser les identifiants de sous-transactions)

Le type interne ID de transaction (xid) est sur 32 bits. Il boucle donc tous les 4 milliards de transactions. Cependant, ces fonctions
exportent au format 64 bits, tendu par un compteur epoch , de faon viter tout cycle sur la dure de vie de l'installation. Le
type de donnes utilis par ces fonctions, txid_snapshot, stocke l'information de visibilit des ID de transaction un instant particulier. Ces composants sont dcrits dans Tableau 9.53, Composants de l'instantan .
Tableau 9.53. Composants de l'instantan

Nom

Description

xmin

ID de transaction (txid) le plus ancien encore actif. Toutes les transactions


plus anciennes sont soient commites et visibles, soient annules et mortes.

xmax

Premier txid non encore assign. Tous les txids plus grands ou gals celuici ne sont pas encore dmarrs ce moment de l'instantan, et donc invisibles.

xip_list

Active les identifiants de transactions (txids) au moment de la prise de


l'image. La liste inclut seulement les identifiants actifs entre xmin et xmax ;
il pourrait y avoir des identifiants plus gros que xmax. Un identifiant qui est
xmin <= txid < xmax et qui n'est pas dans cette liste est dj termin
au moment de la prise de l'image, et du coup est soit visible soit mort suivant
son statut de validation. La liste n'inclut pas les identifiants de transactions
des sous-transactions.

La reprsentation textuelle du txid_snapshot est xmin:xmax:xip_list. Ainsi 10:20:10,14,15 signifie xmin=10,


xmax=20, xip_list=10, 14, 15.

9.24. Fonctions d'administration systme


Le Tableau 9.54, Fonctions agissant sur les paramtres de configuration affiche les fonctions disponibles pour consulter et modifier les paramtres de configuration en excution.
Tableau 9.54. Fonctions agissant sur les paramtres de configuration

Nom

Type de retour Description

current_setting (nom_paramtre)

text

set_config
(nom_paramtre,
velle_valeur, est_local)

valeur courante du paramtre

nou- text

configure le paramtre et renvoie la nouvelle valeur

La fonction current_setting renvoie la valeur courante du paramtre nom_paramtre. Elle correspond la commande
SQL SHOW. Par exemple :
SELECT current_setting('datestyle');
current_setting
202

Fonctions et oprateurs

----------------ISO, MDY
(1 row)
set_config positionne le paramtre nom_paramtre nouvelle_valeur. Si est_local vaut true, la nouvelle valeur s'applique uniquement la transaction en cours. Si la nouvelle valeur doit s'appliquer la session en cours, on utilise false.
La fonction correspond la commande SQL SET. Par exemple :
SELECT set_config('log_statement_stats', 'off', false);
set_config
-----------off
(1 row)
Les fonctions prsentes dans le Tableau 9.55, Fonctions d'envoi de signal au serveur envoient des signaux de contrle aux
autres processus serveur. L'utilisation de ces fonctions est restreinte aux superutilisateurs.
Tableau 9.55. Fonctions d'envoi de signal au serveur

Nom

Type de retour Description

pg_cancel_backend (pid int)

boolean

Annule une requte en cours sur le serveur

pg_reload_conf()

boolean

Impose le rechargement des fichiers de configuration


par les processus serveur

pg_rotate_logfile()

boolean

Impose une rotation du journal des traces du serveur

pg_terminate_backend(pid int)

boolean

Termine un processus serveur

Ces fonctions renvoient true en cas de succs, false en cas d'chec.


pg_cancel_backend et pg_terminate_backend envoie un signal (respectivement SIGINT ou SIGTERM) au processus
serveur identifi par l'ID du processus. L'identifiant du processus serveur actif peut tre trouv dans la colonne procpid dans la
vue pg_stat_activity ou en listant les processus postgres sur le serveur avec ps sur Unix ou le Gestionnaire des tches sur Windows.
pg_reload_conf envoie un signal SIGHUP au serveur, ce qui impose le rechargement des fichiers de configuration par tous
les processus serveur.
pg_rotate_logfile signale au gestionnaire de journaux de trace de basculer immdiatement vers un nouveau fichier de sortie. Cela ne fonctionne que lorsque le collecteur de traces interne est actif, puisqu'il n'y a pas de sous-processus de gestion des fichiers journaux dans le cas contraire.
Les fonctions prsentes dans le Tableau 9.56, Fonctions de contrle de la sauvegarde aident l'excution de sauvegardes
chaud. Ces fonctions ne peuvent pas tre excutes lors d'une restauration.
Tableau 9.56. Fonctions de contrle de la sauvegarde

Nom

Type de retour Description

pg_create_restore_point(name text)

text

Cre un point nomm pour raliser une restauration


(restreint aux superutilisateurs)

pg_current_xlog_insert_location()

text

Rcupration de l'emplacement d'insertion du journal


de transactions courant

pg_current_xlog_location()

text

Rcupration de l'emplacement d'criture du journal de


transactions courant

pg_start_backup (label text [, fast text


boolean ])

Prparation de la sauvegarde chaud (restreint aux superutilisateurs et aux rles ayant l'attribut rplication)

pg_stop_backup()

text

Arrt de la sauvegarde chaud (restreint aux superutilisateurs et aux rles ayant l'attribut rplication)

pg_switch_xlog()

text

Passage forc un nouveau journal de transactions


(restreint aux superutilisateurs)

pg_xlogfile_name(location text)

text

Conversion de la chane dcrivant l'emplacement du


203

Fonctions et oprateurs

Nom

Type de retour Description


journal de transactions en nom de fichier

pg_xlogfile_name_offset(location
text)

text, integer

Conversion de la chane dcrivant l'emplacement du


journal de transactions en nom de fichier et dcalage en
octets dans le fichier

pg_start_backup accepte un label utilisateur de la sauvegarde (typiquement, le nom du fichier d'enregistrement de la sauvegarde). La fonction crit un fichier de label (backup_label) dans le rpertoire de donnes du cluster, ralise un point de retournement, et renvoie la position du dbut de la sauvegarde dans le journal de transactions au format texte. Ce rsultat ne ncessite
pas qu'on s'y intresse, mais il est fourni dans cette ventualit.
postgres=# select pg_start_backup('le_label_ici');
pg_start_backup
----------------0/D4445B8
(1 row)
Il existe un second paramtre boolen optionnel. Si true, il prcise l'excution de pg_start_backup aussi rapidement que
possible. Cela force un point de retournement immdiat qui causera un pic dans les oprations d'entres/sorties, ralentissant toutes
les requtes excutes en parallle.
pg_stop_backup supprime le fichier de label cr par pg_start_backup et cre, la place, un fichier d'historique dans
l'aire de stockage des archives des journaux de transactions. Ce fichier contient le label pass pg_start_backup, les emplacements de dbut et de fin des journaux de transactions correspondant la sauvegarde et les heures de dbut et de fin de la sauvegarde. La valeur de retour est l'emplacement du journal de la transaction de fin de sauvegarde (de peu d'intrt, l encore). Aprs
notification de l'emplacement de fin, le point d'insertion courant du journal de transactions est automatiquement avanc au prochain journal de transactions, de faon ce que le journal de transactions de fin de sauvegarde puisse tre archiv immdiatement
pour terminer la sauvegarde.
pg_switch_xlog bascule sur le prochain journal de transactions, ce qui permet d'archiver le journal courant (en supposant que
l'archivage continu soit utilis). La fonction retourne l'emplacement de la transaction finale + 1 dans le journal ainsi termin. S'il
n'y a pas eu d'activit dans les journaux de transactions depuis le dernier changement de journal, pg_switch_xlog ne fait rien
et renvoie l'emplacement de fin du journal de transactions en cours.
pg_create_restore_point cre un enregistrement dans les journaux de transactions, pouvant tre utilis comme une cible
de restauration, et renvoie l'emplacement correspondant dans les journaux de transactions. Le nom donn peut ensuite tre utilis
avec recovery_target_name pour spcifier la fin de la restauration. vitez de crer plusieurs points de restauration ayant le mme
nom car la restauration s'arrtera au premier nom qui correspond la cible de restauration.
pg_current_xlog_location affiche la position d'criture du journal de transactions en cours dans le mme format que celui utilis dans les fonctions ci-dessus. De faon similaire, pg_current_xlog_insert_location affiche le point
d'insertion dans le journal de transactions courant. Le point d'insertion est la fin logique du journal de transactions tout instant alors que l'emplacement d'criture est la fin de ce qui a dj t crit partir des tampons internes du serveur. La position
d'criture est la fin de ce qui peut tre examin extrieurement au serveur. C'est habituellement l'information ncessaire qui souhaite archiver des journaux de transactions partiels. Le point d'insertion n'est donn principalement que pour des raisons de dbogage du serveur. Il s'agit l d'oprations de lecture seule qui ne ncessitent pas de droits superutilisateur.
pg_xlogfile_name_offset peut tre utilise pour extraire le nom du journal de transactions correspondant et le dcalage
en octets partir du rsultat de n'importe quelle fonction ci-dessus. Par exemple :
postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
file_name
| file_offset
--------------------------+------------00000001000000000000000D |
4039624
(1 row)
De faon similaire, pg_xlogfile_name n'extrait que le nom du journal de la transaction. Quand la position dans le journal de
la transaction donne est exactement sur une limite de journal, les deux fonctions renvoient le nom du journal prcdent. C'est gnralement le comportement souhait pour grer l'archivage des journaux, car le fichier prcdent est le dernier devoir tre archiv.
Pour les dtails sur le bon usage de ces fonctions, voir la Section 24.3, Archivage continu et rcupration d'un instantan
(PITR) .
Les fonctions affiches dans Tableau 9.57, Fonctions d'information sur la restauration fournissent des informations sur le statut
actuel du serveur en attente. Ces fonctions peuvent tre utilises lors d'une restauration mais aussi lors d'un fonctionnement normal.
204

Fonctions et oprateurs

Tableau 9.57. Fonctions d'information sur la restauration

Nom

Type du retour

Description

pg_is_in_recovery()

bool

True si la restauration est en cours.

pg_last_xlog_receive_locatio text
n()

Rcupre l'emplacement de la dernire


transaction reue et synchronise sur
disque par la rplication en flux. Lorsque
cette dernire est en cours d'excution,
l'emplacement aura une progression monotone. Si la restauration a termin, elle
deviendra statique et aura comme valeur
celui du dernier enregistrement de transaction reu et synchronis sur disque lors
de la restauration. Si la rplication en flux
est dsactiv ou si elle n'a pas encore
commenc, la fonction renvoie NULL.

text

Rcupre l'emplacement du dernier enregistrement WAL rejou lors de la restauration. Si la restauration est toujours en
cours, cela va augmenter progressivement.
Si la restauration s'est termine, alors cette
valeur restera statique et dpendera du
dernier enregistrement WAL reu et synchronis sur disque lors de cette restauration. Quand le serveur a t lanc sans
restauration de flux, la valeur renvoye
par la fonction sera NULL.

205

Fonctions et oprateurs

Nom

Type du retour

Description

()
pg_last_xact_replay_timestam timestamp with time zone
p()

Rcupre la date et l'heure de la dernire


transaction rejoue pendant la restauration.
C'est
l'heure

laquelle
l'enregistrement du journal pour cette
transaction a t gnr sur le serveur
principal, que la transaction soit valide
ou annule. Si aucune transaction n'a t
rejoue pendant la restauration, cette fonction renvoie NULL. Sinon, si la restauration est toujours en cours, cette valeur
augmentera continuellement. Si la restauration s'est termine, alors cette valeur
restera statique et indiquera la valeur correspondant la dernire transaction rejoue pendant la restauration. Quand le
serveur a t dmarr normalement
(autrement dit, sans restauration), cette
fonction renvoie NULL.

Les fonctions affiches dans Tableau 9.58, Fonctions de contrle de la restauration contrlent la progression de la restauration.
Ces fonctions sont seulement excutables pendant la restauration.
Tableau 9.58. Fonctions de contrle de la restauration

Nom

Type de la valeur de retour

Description

pg_is_xlog_replay_paused()

bool

True si la restauration est en pause.

pg_xlog_replay_pause()

void

Met en pause immdiatement.

pg_xlog_replay_resume()

void

Relance la restauration si elle a t mise


en pause.

Quand la restauration est en pause, aucune modification de la base n'est applique. Si le serveur se trouve en Hot Standby, toutes
les nouvelles requtes verront la mme image cohrente de la base et aucun conflit de requtes ne sera rapport jusqu' la remise
en route de la restauration.
Si la rplication en flux est dsactive, l'tat pause peut continuer indfiniment sans problme. Si elle est active, les enregistrements des journaux continueront tre reus, ce qui peut ventuellement finir par remplir l'espace disque disponible, suivant la
dure de la pause, le taux de gnration des journaux et l'espace disque disponible.
Les fonctions prsentes dans le Tableau 9.59, Fonctions de calcul de la taille des objets de la base de donnes calculent
l'utilisation de l'espace disque par les objets de la base de donnes.
Tableau 9.59. Fonctions de calcul de la taille des objets de la base de donnes

Nom

Code de retour Description

pg_column_size(any)

int

Nombre d'octets utiliss pour stocker une valeur particulire (ventuellement compresse)

pg_database_size(oid)

bigint

Espace disque utilis par la base de donnes d'OID indiqu

pg_database_size(name)

bigint

Espace disque utilis par la base de donnes de nom indiqu

pg_indexes_size(regclass)

bigint

Espace disque total utilis par les index attachs la


table dont l'OID ou le nom est indiqu

pg_relation_size(relation
fork text)

regclass, bigint

Espace disque utilis par le fork indiqu, 'main',


'fsm' ou 'vm', d'une table ou index d'OID ou de
nom indiqu.

pg_relation_size(relation regclass)

bigint
206

Raccourci

pour

pg_relation_size(...,

Fonctions et oprateurs

Nom

Code de retour Description


'main')

pg_size_pretty(bigint)

text

Convertit une taille en octets en format interprtable


par l'utilisateur avec units

pg_table_size(regclass)

bigint

Espace disque utilis par la table spcifie, en excluant


les index (mais en incluant les donnes TOAST, la
carte des espaces libres et la carte de visibilit)

pg_tablespace_size(oid)

bigint

Espace disque utilis par le tablespace ayant cet OID

pg_tablespace_size(name)

bigint

Espace disque utilis par le tablespace ayant ce nom

pg_total_relation_size(regclass)

bigint

Espace disque total utilis par la table spcifie, en incluant toutes les donnes TOAST et les index

pg_column_size affiche l'espace utilis pour stocker toute valeur individuelle.


pg_total_relation_size accepte en argument l'OID ou le nom d'une table ou d'une table TOAST. Elle renvoie l'espace
disque total utilis par cette table, incluant les index associs. Cette fonction est quivalente pg_table_size +
pg_indexes_size.
pg_table_size accepte en argument l'OID ou le nom d'une table et renvoie l'espace disque ncessaire pour cette table,
l'exclusion des index (espace des donnes TOAST, carte des espaces libres et carte de visibilit inclus.)
pg_indexes_size accepte en argument l'OID ou le nom d'une table et renvoie l'espace disque total utilis par tous les index
attachs cette table.
pg_database_size et pg_tablespace_size acceptent l'OID ou le nom d'une base de donnes ou d'un tablespace et renvoient l'espace disque total utilis. Pour utiliser pg_database_size, vous devez avoir l'attribut CONNECT sur la base de donnes indique (qui est donn par dfaut). Pour utiliser pg_tablespace_size, vous devez avoir l'attribut CREATE sur le tablespace indiqu, sauf s'il s'agit du tablespace par dfaut de la base courante.
pg_relation_size accepte l'OID ou le nom d'une table, d'un index ou d'une table toast et renvoie la taille sur disque en octets. Indiquer 'main' ou laisser le second argument renvoie la taille du morceau de donnes principal de la relation. Indiquer
'fsm' renvoie la taille de la carte des espaces libres (voir Section 55.3, Carte des espaces libres ) associe cette relation. Indiquer 'vm' renvoie la taille de la carte de visibilit (voir Section 55.4, Carte de visibilit ) associe avec la relation. Notez
que cette fonction affiche la taille d'un seul fichier ; dans la plupart des cas, c'est plus simple utiliser que les fonctions de hautniveau comme pg_total_relation_size ou pg_table_size.
pg_size_pretty peut tre utilis pour formater le rsultat d'une des autres fonctions de faon interprtable par l'utilisateur, en
utilisant kB, MB, GB ou TB suivant le cas.
Les fonctions ci-dessus qui oprent sur des tables ou des index acceptent un argument regclass, qui est simplement l'OID de la
table ou de l'index dans le catalogue systme pg_class. Vous n'avez pas rechercher l'OID manuellement. Nanmoins, le convertisseur de type de donnes regclass fera ce travail pour vous. crivez simplement le nom de la table entre guillements simples pour
qu'il ressemble une constante littrale. Pour compatibilit avec la gestion des noms SQL standards, la chane sera convertie en
minuscule sauf si elle est entoure de guillemets doubles.
Les fonctions affiches dans Tableau 9.60, Fonctions de rcupration de l'emplacement des objets de la base de donnes facilitent l'identification des fichiers associes aux objets de la base de donnes.
Tableau 9.60. Fonctions de rcupration de l'emplacement des objets de la base de donnes

Nom

Type en retour

Description

pg_relation_filenode(relation regclass)

oid

Numro filenode de la relation indique

pg_relation_filepath(relation regclass)

text

Chemin et nom du fichier pour la relation


indique

pg_relation_filenode accepte l'OID ou le nom d'une table, d'un index, d'une squence ou d'une table TOAST. Elle renvoie le numro filenode qui lui est affect. Ce numro est le composant de base du nom de fichier utilis par la relation (voir
Section 55.1, Emplacement des fichiers de la base de donnes pour plus d'informations). Pour la plupart des tables, le rsultat
est identique pg_class.relfilenode mais pour certains catalogues systme, relfilenode vaut zro et cette fonction doit
tre utilise pour obtenir la bonne valeur. La fonction renvoie NULL si l'objet qui lui est fourni est une relation qui n'a pas de stockage, par exemple une vue.
207

Fonctions et oprateurs

pg_relation_filepath est similaire pg_relation_filenode mais elle renvoie le chemin complet vers le fichier
(relatif au rpertoire des donnes de l'instance, PGDATA) de la relation.
Les fonctions prsentes dans le Tableau 9.61, Fonctions d'accs gnrique aux fichiers fournissent un accs natif aux fichiers
situs sur le serveur. Seuls les fichiers contenus dans le rpertoire du cluster et ceux du rpertoire log_directory sont accessibles. On utilise un chemin relatif pour les fichiers contenus dans le rpertoire du cluster et un chemin correspondant la configuration du paramtre log_directory pour les journaux de trace. L'utilisation de ces fonctions est restreinte aux superutilisateurs.
Tableau 9.61. Fonctions d'accs gnrique aux fichiers

Nom

Code de retour Description

pg_ls_dir(nom_rpertoire text)

setof text

Liste le contenu d'un rpertoire

pg_read_file(filename text [, offset text


bigint, length bigint])

Renvoie le contenu d'un fichier texte

pg_read_binary_file(filename text [, bytea


offset bigint, length bigint])

Renvoie le contenu d'un fichier

pg_stat_file(nom_fichier text)

record

Renvoie les informations concernant un fichier

pg_ls_dir renvoie tous les noms contenus dans le rpertoire indiqu, l'exception des entres spciales . et .. .
pg_read_file renvoie une partie d'un fichier texte, dbutant au dcalage indiqu, renvoyant au plus longueur octets
(moins si la fin du fichier est atteinte avant). Si le dcalage est ngatif, il est relatif la fin du fichier. Si offset et length
sont omis, le fichier entier est renvoy. Les octets lus partir de ce fichier sont interprts comme une chane dans l'encodage du
serveur. Une erreur est affiche si l'encodage est mauvais.
pg_read_binary_file est similaire pg_read_file, sauf que le rsultat est une valeur de type bytea ; du coup, aucune
vrification d'encodage n'est ralise. Avec la fonction convert_from, cette fonction peut tre utilise pour lire un fichier dans
un encodage spcifi :
SELECT convert_from(pg_read_binary_file('fichier_en_utf8.txt'), 'UTF8');
pg_stat_file renvoie un enregistrement contenant la taille du fichier, les date et heure de dernier accs, les date et heure de
dernire modification, les date et heure de dernier changement de statut (plateformes Unix seulement), les date et heure de cration (Windows seulement) et un boolen indiquant s'il s'agit d'un rpertoire. Les usages habituels incluent :
SELECT * FROM pg_stat_file('nomfichier');
SELECT (pg_stat_file('nomfichier')).modification;
Les fonctions prsentes dans Tableau 9.62, Fonctions de verrous consultatifs grent les verrous consultatifs. Pour les dtails
sur le bon usage de ces fonctions, voir Section 13.3.4, Verrous informatifs .
Tableau 9.62. Fonctions de verrous consultatifs

Nom

Type renvoy

Description

pg_advisory_lock(key bigint) void

Obtient un verrou consultatif exclusif au niveau session

int, void

Obtient un verrou consultatif exclusif au niveau session

void

Obtient un verrou consultatif partag au niveau session

pg_advisory_lock_shared(key1 void
int, key2 int)

Obtient un verrou consultatif partag au niveau session

pg_try_advisory_lock(key bi- boolean


gint)

Obtient un verrou consultatif exclusif si disponible

boolean

Obtient un verrou consultatif exclusif si disponible

boolean

Obtient un verrou consultatif partag si disponible

pg_advisory_lock(key1
key2 int)

pg_advisory_lock_shared(key
bigint)

pg_try_advisory_lock(key1
int, key2 int)

208

Fonctions et oprateurs

Nom

Type renvoy

Description

boolean

Obtient un verrou consultatif partag si disponible

key bigint)

209

Fonctions et oprateurs

Nom

Type renvoy

Description

key1 int, key2 int)


bi- boolean

Relche un verrou consultatif exclusif au niveau session

pg_advisory_unlock(key1 int, boolean


key2 int)

Relche un verrou consultatif exclusif au niveau session

pg_advisory_unlock(key
gint)

pg_advisory_unlock_all()

void

Relche tous les verrous consultatifs au niveau session dtenus


par la session courante

ke
pg_advisory_unlock_shared(y
bigint)

boolean

Relche un verrou consultatif partag au niveau session

ke
boolean
pg_advisory_unlock_shared(y1
int, key2 int)

Relche un verrou consultatif partag au niveau session

pg_advisory_xact_lock(key
bigint)

void

Obtient un verrou consultatif exclusif au niveau transaction

pg_advisory_xact_lock(key1
int, key2 int)

void

Obtient un verrou consultatif exclusif au niveau transaction

pg_advisory_xact_lock_shared void
(key bigint)

Obtient un verrou consultatif partag au niveau transaction

pg_advisory_xact_lock_shared void
(key1 int, key2 int)

Obtient un verrou consultatif partag au niveau transaction

pg_try_advisory_lock(key bi- boolean


gint)

Obtient un verrou consultatif exclusif au niveau session si disponible

boolean

Obtient un verrou consultatif exclusif au niveau session si disponible

boolean

Obtient un verrou consultatif partag au niveau session si disponible

pg_try_advisory_lock(key1
int, key2 int)

210

Fonctions et oprateurs

Nom

Type renvoy

Description

boolean

Obtient un verrou consultatif partag au niveau session si disponible

key bigint)

211

Fonctions et oprateurs

Nom

Type renvoy

Description

boolean

Obtient un verrou consultatif exclusif au niveau transaction si


disponible

ke
boolean
pg_try_advisory_xact_lock(y1
int, key2 int)

Obtient un verrou consultatif exclusif au niveau transaction si


disponible

pg_try_advisory_xact_lock_sh boolean
ared(key bigint)

Obtient un verrou consultatif partag au niveau transaction si


disponible

pg_try_advisory_xact_lock_sh boolean
ared(key1 int, key2 int)

Obtient un verrou consultatif partag au niveau transaction si


disponible

key1 int, key2 int)


ke
pg_try_advisory_xact_lock(y
bigint)

pg_advisory_lock verrouille une ressource applicative qui peut tre identifie soit par une valeur de cl sur 64 bits soit par
deux valeurs de cl sur 32 bits (les deux espaces de cl ne se surchargent pas). Si une autre session dtient dj un verrou sur la
mme ressource, la fonction attend que la ressource devienne disponible. Le verrou est exclusif. Les demandes de verrou
s'empilent de sorte que, si une mme ressource est verrouille trois fois, elle doit tre dverrouille trois fois pour tre disponible
par les autres sessions.
pg_advisory_lock_shared fonctionne de faon identique pg_advisory_lock sauf que le verrou peut tre partag
avec d'autres sessions qui rclament des verrous partags. Seules les demandes de verrou exclusif sont bloques.
pg_try_advisory_lock est similaire pg_advisory_lock sauf que la fonction n'attend pas la disponibilit du verrou.
Si le verrou peut tre obtenu immdiatement, la fonction renvoie true, sinon, elle renvoie false.
pg_try_advisory_lock_shared fonctionne de la mme faon que pg_try_advisory_lock sauf qu'elle tente
d'acqurir un verrou partag au lieu d'un verrou exclusif.
pg_advisory_unlock relche un verrou exclusif prcdemment acquis au niveau session. Elle retourne true si le verrou est
relach avec succs. Si le verrou n'tait pas dtenu, false est renvoy et un message d'avertissement SQL est mis par le serveur.
pg_advisory_unlock_shared fonctionne de la mme faon que pg_advisory_unlock mais pour relcher un verrou
partag au niveau session.
pg_advisory_unlock_all relche tous les verrous consultatifs au niveau session dtenus par la session courante. (Cette
fonction est appele implicitement la fin de la session, mme si le client se dconnecte brutalement.)
pg_advisory_xact_lock fonctionne de la mme faon que pg_advisory_lock, sauf que le verrou est automatiquement
relch la fin de la transaction courante et ne peut pas tre relch de faon explicite.
pg_advisory_xact_lock_shared fonctionne de la mme faon que pg_advisory_lock_shared, sauf que le verrou
est automatiquement relch la fin de la transaction courante et ne peut pas tre relch de faon explicite.
pg_try_advisory_xact_lock fonctionne de la mme faon que pg_try_advisory_lock, sauf que le verrou, s'il est
acquis, est automatiquement relch la fin de la transaction courante et ne peut pas tre relch de faon explicite.
pg_try_advisory_xact_lock_shared fonctionne de la mme faon que pg_try_advisory_lock_shared, sauf
que le verrou, s'il est acquis, est automatiquement relch la fin de la transaction courante et ne peut pas tre relch de faon explicite.

9.25. Fonctions trigger


Actuellement, PostgreSQL fournit une fonction de trigger interne, suppress_redundant_updates_trigger, qui empchera toute mise jour qui ne modifie pas rellement les donnes de cette ligne, en contrate au comportement normal qui ralise
toujours une mise jour, que les donnes soient rellement changes ou pas. (Ce comportement normal fait que les mises jour
s'excutent rapidement car aucune vrification n'est ncessaire et c'est aussi utile dans certains cas.)
Idalement, vous devriez normalement viter d'excuter des mises jour qui ne modifient pas rellement les donnes de
l'enregistrement. Les mise jour redondantes peuvent coter considrablement en temps d'excution, tout spcialement si vous
avez beaucoup d'index modifier, et en espace dans des lignes mortes que vous devrez finir par VACUUMes. Nanmoins, la dtection de telles situations dans le code client n'est pas toujours facile, voire mme possible, et crire des expressions pour dtecter
ce
type
de
cas
peut
facilement
amener
des
erreurs.
Une
alternative
est
d'utiliser
suppress_redundant_updates_trigger, qui ignorera les mises jour qui ne modifient pas rellement les donnes.
Nanmoins, vous devez tre trs prudent quant son utilisation. Le trigger consomme un temps petit, mais ne pas ngliger, pour
vrifier que la mise jour doit se faire. Autrement dit, si la plupart des enregistrements affects par une mise jour seront relle212

Fonctions et oprateurs

ment modifis, utiliser ce trigger rendra la mise jour bien plus lente.
La fonction suppress_redundant_updates_trigger peut tre ajoute une table de cette faon :
CREATE TRIGGER z_min_update
BEFORE UPDATE ON tablename
FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
Dans la plupart des cas, vous voudrez dclencher ce tigger en dernier pour chaque ligne. Gardez en tte que les triggers sont dclenchs dans l'ordre alphabtique de leur nom, vous choisirez donc un nom de trigger qui vient apr_s le nom des autres triggers
que vous pourriez avoir sur la table.
Pour plus d'informations sur la cration des trigger, voir CREATE TRIGGER(7).

213

Chapitre 10. Conversion de types


Le mlange de diffrents types de donnes dans la mme expression peut tre requis, intentionnellement ou pas, par les instructions SQL. PostgreSQL possde des fonctionnalits tendues pour valuer les expressions de type mixte.
Dans la plupart des cas, un utilisateur n'aura pas besoin de comprendre les dtails du mcanisme de conversion des types. Cependant, les conversions implicites faites par PostgreSQL peuvent affecter le rsultat d'une requte. Quand cela est ncessaire,
ces rsultats peuvent tre atteints directement en utilisant la conversion explicite de types.
Ce chapitre introduit les mcanismes et les conventions sur les conversions de types dans PostgreSQL. Rfrez-vous aux sections appropries du Chapitre 8, Types de donnes et du Chapitre 9, Fonctions et oprateurs pour plus d'informations sur les
types de donnes spcifiques, les fonctions et les oprateurs autoriss.

10.1. Aperu
SQL est un langage fortement typ. C'est--dire que chaque lment de donnes est associ un type de donnes qui dtermine
son comportement et son utilisation permise. PostgreSQL a un systme de types extensible qui est beaucoup plus gnral et
flexible que les autres implmentations de SQL. Par consquent, la plupart des comportements de conversion de types dans
PostgreSQL est rgie par des rgles gnrales plutt que par une heuristique ad hoc. Cela permet aux expressions de types
mixtes d'tre significatives mme avec des types dfinis par l'utilisateur.
L'analyseur de PostgreSQL divise les lments lexicaux en cinq catgories fondamentales : les entiers, les nombres non entiers, les chanes de caractres, les identifieurs et les mots-cl. Les constantes de la plupart des types non-numriques sont
d'abord classifies comme chanes de caractres. La dfinition du langage SQL permet de spcifier le nom des types avec une
chane et ce mcanisme peut tre utilis dans PostgreSQL pour lancer l'analyseur sur le bon chemin. Par exemple, la requte :
SELECT text 'Origin' AS "label", point '(0,0)' AS "value";
label | value
--------+------Origin | (0,0)
(1 row)
a deux constantes littrales, de type text et point. Si un type n'est pas spcifi pour une chane littrale, alors le type unknown est
assign initialement pour tre rsolu dans les tapes ultrieures comme dcrit plus bas.
Il y a quatre constructions SQL fondamentales qui exigent des rgles distinctes de conversion de types dans l'analyseur de PostgreSQL :
Les appels de fonctions
Une grande partie du systme de types de PostgreSQL est construit autour d'un riche ensemble de fonctions. Les fonctions peuvent avoir un ou plusieurs arguments. Puisque que PostgreSQL permet la surcharge des fonctions, le nom seul
de la fonction n'identifie pas de manire unique la fonction appeler ; l'analyseur doit slectionner la bonne fonction par
rapport aux types des arguments fournis.
Les oprateurs
PostgreSQL autorise les expressions avec des oprateurs de prfixe et de suffixe unaires (un argument) aussi bien que binaires (deux arguments). Comme les fonctions, les oprateurs peuvent tre surchargs. Du coup, le mme problme existe
pour slectionner le bon oprateur.
Le stockage des valeurs
Les instructions SQL INSERT et UPDATE placent le rsultat des expressions dans une table. Les expressions dans une
instruction doivent tre en accord avec le type des colonnes cibles et peuvent tre converties vers celles-ci.
Les constructions UNION, CASE et des constructions relatives
Comme toutes les requtes issues d'une instruction SELECT utilisant une union doivent apparatre dans un ensemble
unique de colonnes, les types de rsultats de chaque instruction SELECT doivent tre assortis et convertis en un ensemble
uniforme. De faon similaire, les expressions de rsultats d'une construction CASE doivent tre converties vers un type
commun de faon ce que l'ensemble de l'expression CASE ait un type de sortie connu. Cela est la mme chose pour les
constructions avec ARRAY et pour les fonctions GREATEST et LEAST.
Les catalogues systmes stockent les informations concernant l'existence de conversions entre certains types de donnes et la
faon d'excuter ces conversions. Les conversions sont appeles casts en anglais. Des conversions de types supplmentaires
peuvent tre ajoutes par l'utilisateur avec la commande CREATE CAST(7) (c'est habituellement ralis en conjonction avec la
dfinition de nouveaux types de donnes. L'ensemble des conversions entre les types prdfinis a t soigneusement choisi et le
mieux est de ne pas le modifier).
214

Conversion de types

Une heuristique supplmentaire est fournie dans l'analyseur pour permettre de meilleures estimations sur la bonne conversion de
type parmi un groupe de types qui ont des conversions implicites. Les types de donnes sont divises en plusieurs catgories de
type basiques, incluant boolean, numeric, string, bitstring, datetime, timespan, geometric, network et dfinis par l'utilisateur. (Pour
une liste, voir Tableau 45.49, Codes typcategory ; mais notez qu'il est aussi possible de crer des catgories de type personnalises.) l'intrieur de chaque catgorie, il peut y avoir une ou plusieurs types prfrs, qui sont slectionns quand il y a un
choix possible de types. Avec une slection attentive des types prfrs et des conversions implicites disponibles, il est possible de
s'assurer que les expressions ambigues (celles avec plusieurs solutions candidates) peuvent tre rsolus d'une faon utile.
Toutes les rgles de conversions de types sont crites en gardant l'esprit plusieurs principes :

Les conversions implicites ne doivent jamais avoir de rsultats surprenants ou imprvisibles.

Il n'y aura pas de surcharge depuis l'analyseur ou l'excuteur si une requte n'a pas besoin d'une conversion implicite de types.
C'est--dire que si une requte est bien formule et si les types sont dj bien distinguables, alors la requte devra s'excuter
sans perte de temps supplmentaire et sans introduire l'intrieur de celle-ci des appels des conversions implicites non ncessaires.
De plus, si une requte ncessite habituellement une conversion implicite pour une fonction et si l'utilisateur dfinit une nouvelle fonction avec les types des arguments corrects, l'analyseur devrait utiliser cette nouvelle fonction et ne fera plus des
conversions implicites en utilisant l'ancienne fonction.

10.2. Oprateurs
L'oprateur spcifique qui est rfrence par une expression d'oprateur est dtermin par la procdure ci-dessous. Notez que cette
procdure est indirectement affecte par l'ordre d'insertion des oprateurs car cela va dterminer les sous-expressions prises en entre des oprateurs. Voir la Section 4.1.6, Prcdence d'oprateurs pour plus d'informations.
Procdure 10.1. Rsolution de types pour les oprateurs

1.

Slectionner les oprateurs examiner depuis le catalogue systme pg_operator. Si un nom non-qualifi d'oprateur tait
utilis (le cas habituel), les oprateurs examins sont ceux avec un nom et un nombre d'arguments corrects et qui sont visibles
dans le chemin de recherche courant (voir la Section 5.7.3, Chemin de parcours des schmas ). Si un nom qualifi
d'oprateur a t donn, seuls les oprateurs dans le schma spcifi sont examins.

2.

Vrifier que l'oprateur accepte le type exact des arguments en entre. Si un oprateur existe (il peut en avoir uniquement un
qui corresponde exactement dans l'ensemble des oprateurs considrs), utiliser cet oprateur.

3.

Si un chemin de recherche trouve de nombreux oprateurs avec des types d'arguments identiques, seul sera examin celui apparaissant le plus tt dans le chemin. Mais les oprateurs avec des types d'arguments diffrents sont examins sur
une base d'galit indpendamment de leur position dans le chemin de recherche.

Si un argument lors d'une invocation d'oprateur binaire est de type unknown (NdT : inconnu), alors considrer pour ce
contrle que c'est le mme type que l'autre argument. Les invocations impliquant deux entres de type unknown, ou un
oprateur unitaire avec en entre une donne de type unknown ne trouveront jamais une correspondance ce niveau.

Rechercher la meilleure correspondance.


a.

Se dbarrasser des oprateurs candidats pour lesquels les types en entre ne correspondent pas et qui ne peuvent pas tre
convertis (en utilisant une conversion implicite) dans le type correspondant. Le type unknown est suppos tre convertible vers tout. Si un candidat reste, l'utiliser, sinon aller la prochaine tape.

b.

Parcourir tous les candidats et garder ceux avec la correspondance la plus exacte par rapport aux types en entre (les domaines sont considrs de la mme faon que leur type de base pour cette tape). Garder tous les candidats si aucun n'a
de correspondance exacte. Si un seul candidat reste, l'utiliser ; sinon, aller la prochaine tape.

c.

Parcourir tous les candidats et garder ceux qui acceptent les types prfrs (de la catgorie des types de donnes en entre) aux positions o la conversion de types aurait t requise. Garder tous les candidats si aucun n'accepte les types
prfrs. Si seulement un candidat reste, l'utiliser ; sinon aller la prochaine tape.

d.

Si des arguments en entre sont inconnus, vrifier la catgorie des types accepts la position de ces arguments par les
candidats restants. chaque position, slectionner la catgorie chane de caractres si un des candidats accepte cette catgorie (cette prfrence vers les chanes de caractres est approprie car le terme type-inconnu ressemble une chane
de caractres). Dans le cas contraire, si tous les candidats restants acceptent la mme catgorie de types, slectionner
215

Conversion de types

cette catgorie. Dans le cas contraire, chouer car le choix correct ne peut pas tre dduit sans plus d'indices. Se dbarrasser maintenant des candidats qui n'acceptent pas la catgorie slectionne. De plus, si des candidats acceptent un type
prfr de cette catgorie, se dbarrasser des candidats qui acceptent, pour cet argument, les types qui ne sont pas prfrs.
e.

Si un seul candidat reste, l'utiliser. Sinon, chouer.

Quelques exemples suivent.


Exemple 10.1. Rsolution du type d'oprateur factoriel

Il n'existe qu'un seul oprateur factoriel (! postfix) dfini dans le catalogue standard. Il prend un argument de type bigint. Le scanner affecte au dbut le type integer l'argument dans cette expression :
SELECT 40 ! AS "40 factorial";
40 factorial
-------------------------------------------------815915283247897734345611269596115894272000000000
(1 row)
L'analyseur fait donc une conversion de types sur l'oprande et la requte est quivalente
SELECT CAST(40 AS bigint) ! AS "40 factorial";

Exemple 10.2. Rsolution de types pour les oprateurs de concatnation de chanes

La syntaxe d'une chane de caractres est utilise pour travailler avec les types chanes mais aussi avec les types d'extensions complexes. Les chanes de caractres avec un type non spcifi sont compares avec les oprateurs candidats probables.
Un exemple avec un argument non spcifi :
SELECT text 'abc' || 'def' AS "text and unknown";
text and unknown
-----------------abcdef
(1 row)
Dans ce cas, l'analyseur cherche voir s'il existe un oprateur prenant text pour ses deux arguments. Comme il y en a, il suppose
que le second argument devra tre interprt comme un type text.
Voici une concatnation sur des types non spcifis :
SELECT 'abc' || 'def' AS "unspecified";
unspecified
------------abcdef
(1 row)
Dans ce cas, il n'y a aucune allusion initiale sur quel type utiliser puisqu'aucun type n'est spcifi dans la requte. Donc,
l'analyseur regarde pour tous les oprateurs candidats et trouve qu'il existe des candidats acceptant en entre la catgorie chane de
caractres (string) et la catgorie morceaux de chanes (bit-string). Puisque la catgorie chanes de caractres est prfre quand
elle est disponible, cette catgorie est slectionne. Le type prfr pour la catgorie chanes tant text, ce type est utilis comme
le type spcifique pour rsoudre les types inconnus.

Exemple 10.3. Rsolution de types pour les oprateurs de valeur absolue et de ngation

Le catalogue d'oprateurs de PostgreSQL a plusieurs entres pour l'oprateur de prfixe @. Ces entres implmentent toutes des
oprations de valeur absolue pour des types de donnes numriques varies. Une de ces entres est pour le type float8 (rel) qui
216

Conversion de types

est le type prfr dans la catgorie des numriques. Par consquent, PostgreSQL utilisera cette entre quand il sera en face d'un
argument de type unknown :
SELECT @ '-4.5' AS "abs";
abs
----4.5
(1 row)
Le systme a compris implicitement que le litral de type unknown est de type float8 (rel) avant d'appliquer l'oprateur choisi.
Nous pouvons vrifier que float8, et pas un autre type, a t utilis :
SELECT @ '-4.5e500' AS "abs";
ERROR:

"-4.5e500" is out of range for type double precision

D'un autre ct, l'oprateur prfixe ~ (ngation bit par bit) est dfini seulement pour les types entiers et non pas pour float8 (rel).
Ainsi, si nous essayons un cas similaire avec ~, nous obtenons :
SELECT ~ '20' AS "negation";
ERROR: operator is not unique: ~ "unknown"
HINT: Could not choose a best candidate operator. You might need to add explicit
type casts.
Ceci se produit parce que le systme ne peut pas dcider quel oprateur doit tre prfr parmi les diffrents oprateurs ~ possibles. Nous pouvons l'aider avec une conversion explicite :
SELECT ~ CAST('20' AS int8) AS "negation";
negation
----------21
(1 row)

10.3. Fonctions
La fonction spcifique rfrence par un appel de fonction est dtermine selon les tapes suivantes.
Procdure 10.2. Rsolution de types pour les fonctions

1.

2.

Slectionner les fonctions examiner depuis le catalogue systme pg_proc. Si un nom non-qualifi de fonction tait utilis,
les fonctions examines sont celles avec un nom et un nombre d'arguments corrects et qui sont visibles dans le chemin de recherche courant (voir la Section 5.7.3, Chemin de parcours des schmas ). Si un nom qualifi de fonctions a t donn,
seules les fonctions dans le schma spcifique sont examines.
a.

Si un chemin de recherche trouve de nombreuses fonctions avec des types d'arguments identiques, seule celle apparaissant le plus tt dans le chemin sera examine. Mais les fonctions avec des types d'arguments diffrents sont examines
sur une base d'galit indpendamment de leur position dans le chemin de recherche.

b.

Si une fonction est dclare avec un paramtre VARIADIC et que l'appel n'utilise pas le mot cl VARIADIC, alors la
fonction est traite comme si le paramtre tableau tait remplac par une ou plusieurs occurrences de son type lmentaire, autant que ncessaire pour correspondre l'appel. Aprs cette expansion, la fonction pourrait avoir des types
d'arguments identiques certaines fonctions non variadic. Dans ce cas, la fonction apparaissant plus tt dans le chemin
de recherche est utilise ou, si les deux fonctions sont dans le mme schma, celle qui n'est pas VARIADIC est prfre.

c.

Les fonctions qui ont des valeurs par dfaut pour les paramtres sont considrs comme correspondant un appel qui
omet zro ou plus des paramtres ayant des valeurs par dfaut. Si plus d'une fonction de ce type correspondent un appel, celui apparaissant en premier dans le chemin des schmas est utilis. S'il existe deux ou plus de ces fonctions dans
le mme schmas avec les mme types de paramtres pour les paramtres sans valeur par dfaut (ce qui est possible s'ils
ont des ensembles diffrents de paramtres par dfaut), le systme ne sera pas capable de dterminer laquelle slectionne, ce qui rsultera en une erreur ambiguous function call .

Vrifier que la fonction accepte le type exact des arguments en entre. Si une fonction existe (il peut en avoir uniquement une
qui correspond exactement dans tout l'ensemble des fonctions considres), utiliser cette fonction (les cas impliquant le type
unknown ne trouveront jamais de correspondance cette tape).
217

Conversion de types

3.

Si aucune correspondance n'est trouve, vrifier si l'appel la fonction apparat tre une requte spciale de conversion de
types. Cela arrive si l'appel la fonction a juste un argument et si le nom de la fonction est le mme que le nom (interne) de
certains types de donnes. De plus, l'argument de la fonction doit tre soit un type inconnu soit un type qui a une compatibilit binaire avec le type de donnes nomms, soit un type qui peut tre converti dans le type de donnes indiqu en appliquant
les fonctions d'entres/sorties du type (c'est--dire que la conversion est vers ou partir d'un type standard de chane). Quand
ces conditions sont rencontres, l'appel de la fonction est trait sous la forme d'une spcification CAST. 1

4.

Regarder pour la meilleure correspondance.


a.

Se dbarrasser des fonctions candidates pour lesquelles les types en entre ne correspondent pas et qui ne peuvent pas
tre convertis (en utilisant une conversion implicite) pour correspondre. Le type unknown est suppos tre convertible
vers n'importe quoi. Si un seul candidat reste, utiliser le ; sinon, aller la prochaine tape.

b.

Parcourir tous les candidats et garder ceux avec la correspondance la plus exacte par rapport aux types en entre (les domaines sont considrs de la mme faon que leur type de base pour cette tape). Garder tous les candidats si aucun n'a
de correspondance exacte. Si un seul candidat reste, utiliser le ; sinon, aller la prochaine tape.

c.

Parcourir tous les candidats et garder ceux qui acceptent les types prfrs (de la catgorie des types de donnes en entre) aux positions o la conversion de types aurait t requise. Garder tous les candidats si aucun n'accepte les types
prfrs. Si un seul candidat reste, utiliser le ; sinon, aller la prochaine tape.

d.

Si des arguments en entre sont unknown, vrifier les catgories de types acceptes la position de ces arguments par
les candidats restants. chaque position, slectionner la catgorie chane de caractres si un des candidats accepte cette
catgorie (cette prfrence envers les chanes de caractres est approprie depuis que le terme type-inconnu ressemble
une chane de caractres). Dans le cas contraire, si tous les candidats restants acceptent la mme catgorie de types, slectionner cette catgorie. Dans le cas contraire, chouer car le choix correct ne peut pas tre dduit sans plus d'indices.
Se dbarrasser maintenant des candidats qui n'acceptent pas la catgorie slectionne. De plus, si des candidats acceptent un type prfr dans cette catgorie, se dbarrasser des candidats qui acceptent, pour cet argument, les types qui
ne sont pas prfrs.

e.

Si un seul candidat reste, utiliser le. Sinon, chouer.

Notez que les rgles de correspondance optimale sont identiques pour la rsolution de types concernant les oprateurs et les
fonctions. Quelques exemples suivent.
Exemple 10.4. Rsolution de types pour les arguments de la fonction arrondie

Il n'existe qu'une seule fonction round avec deux arguments (le premier est de type numeric, le second est de type integer). Ainsi,
la requte suivante convertie automatiquement le type du premier argument de integer vers numeric.
SELECT round(4, 4);
round
-------4.0000
(1 row)
La requte est en fait transforme par l'analyseur en
SELECT round(CAST (4 AS numeric), 4);
Puisque le type numeric est initialement assign aux constantes numriques avec un point dcimal, la requte suivante ne requirera pas une conversion de types et pourra par consquent tre un peu plus efficace :
SELECT round(4.0, 4);

Exemple 10.5. Rsolution de types pour les fonctions retournant un segment de chane

Il existe plusieurs fonctions substr, une d'entre elles prend les types text et integer. Si cette fonction est appele avec une
constante de chanes d'un type inconnu, le systme choisi la fonction candidate qui accepte un argument issu de la catgorie prfre string (c'est--dire de type text).
SELECT
substr('1234', 3);
1

La raison de cette tape est le support des spcifications de conversion au format fonction pour les cas o la vraie fonction de conversion n'existe pas. S'il existe une fonction de conversion, elle est habituellement nomme suivant le nom du type en sortie et donc il n'est pas ncessaire d'avoir un cas spcial. Pour plus d'informations, voir CREATE CAST(7).

218

Conversion de types

substr
-------34
(1 row)
Si la chane de caractres est dclare comme tant du type varchar (chane de caractres de longueur variable), ce qui peut tre le
cas si elle vient d'une table, alors l'analyseur essayera de la convertir en text :
SELECT substr(varchar '1234', 3);
substr
-------34
(1 row)
Ceci est transform par l'analyseur en
SELECT substr(CAST (varchar '1234' AS text), 3);

Note
L'analyseur apprend depuis le catalogue pg_cast que les types text et varchar ont une compatibilit binaire, ce qui
veut dire que l'un peut tre pass une fonction qui accepte l'autre sans avoir faire aucune conversion physique.
Par consquent, aucun appel de conversion de types n'est rellement insr dans ce cas.
Et si la fonction est appele avec un argument de type integer, l'analyseur essaie de le convertir en text :
SELECT substr(1234, 3);
ERROR: function substr(integer, integer) does not exist
HINT: No function matches the given name and argument types. You might need
to add explicit type casts.
Ceci ne fonctionne pas car integer n'a pas de conversion implicite vers text. Nanmoins, une conversion explicite fonctionnera :
SELECT substr(CAST (1234 AS text), 3);
substr
-------34
(1 row)

10.4. Stockage de valeurs


Les valeurs qui doivent tre insres dans une table sont converties vers le type de donnes de la colonne de destination selon les
rgles suivantes.
Procdure 10.3. Conversion de types pour le stockage de valeurs

1.

Vrifier qu'il y a une correspondance exacte avec la cible.

2.

Dans le cas contraire, essayer de convertir l'expression vers le type cible. Cela russira s'il y a une conversion (cast) enregistre entre ces deux types. Si une expression est de type inconnu, le contenu de la chane littrale sera fourni l'entre de la
routine de conversion pour le type cible.

3.

Vrifier s'il y a une conversion de taille pour le type cible. Une conversion de taille est une conversion d'un type vers luimme. Si elle est trouve dans le catalogue pg_cast, appliquez-la l'expression avant de la stocker dans la colonne de destination. La fonction d'implmentation pour une telle conversion prend toujours un paramtre supplmentaire de type integer,
qui reoit la valeur atttypmod de la colonne de destination (en fait, sa valeur dclare ; l'interprtation de atttypmod varie pour les diffrents types de donnes). La fonction de conversion est responsable de l'application de toute smantique dpendante de la longueur comme la vrification de la taille ou une troncature.

219

Conversion de types

Exemple 10.6. Conversion de types pour le stockage de character

Pour une colonne cible dclare comme character(20), la dclaration suivante montre que la valeur stocke a la taille correcte :
CREATE TABLE vv (v character(20));
INSERT INTO vv SELECT 'abc' || 'def';
SELECT v, octet_length(v) FROM vv;
v
| octet_length
----------------------+-------------abcdef
|
20
(1 row)
Voici ce qui s'est rellement pass ici : les deux types inconnus sont rsolus en text par dfaut, permettant l'oprateur || de les
rsoudre comme une concatnation de text. Ensuite, le rsultat text de l'oprateur est converti en bpchar ( blank-padded char ,
le nom interne du type de donnes character (caractre)) pour correspondre au type de la colonne cible (comme la conversion de
text bpchar est compatible binairement, cette conversion n'insre aucun appel rel une fonction). Enfin, la fonction de taille
bpchar(bpchar, integer, boolean) est trouve dans le catalogue systme et applique au rsultat de l'oprateur et la
longueur de la colonne stocke. Cette fonction de type spcifique effectue le contrle de la longueur requise et ajoute des espaces
pour combler la chane.

10.5. Constructions UNION, CASE et constructions relatives


Les constructions SQL avec des UNION doivent potentiellement faire correspondre des types diffrents pour avoir un ensemble
unique dans le rsultat. L'algorithme de rsolution est appliqu sparment chaque colonne de sortie d'une requte d'union. Les
constructions INTERSECT et EXCEPT rsolvent des types diffrents de la mme manire qu'UNION. Les constructions CASE,
ARRAY, VALUES, GREATEST et LEAST utilisent le mme algorithme pour faire correspondre les expressions qui les composent
et slectionner un type de rsultat.
Procdure 10.4. Rsolution des types pour UNION, CASE et les constructions relatives

1.

Si toutes les entres sont du mme type et qu'il ne s'agit pas du type unknown, rsoudre comme tant de ce type. Sinon, remplacer tous les types de domaine dans la liste avec les types de base sous-jacents.

2.

Si toutes les entres sont du type unknown, rsoudre comme tant du type text (le type prfr de la catgorie chane). Dans
le cas contraire, les entres unknown seront ignores.

3.

Si toutes les entres non-inconnues ne sont pas toutes de la mme catgorie, chouer.

4.

Choisir la premire entre non-inconnue qui est un type prfr dans sa catgorie, s'il y en a une.

5.

Sinon, choisir le dernier type en entre qui ne soit pas inconnu et qui permet toutes les entres prcdentes qui ne sont pas
inconnues tre implicitement converties. (Il y a toujours un type de ce genre car au moins le premier type dans la liste doit
satisfaire cette condition.)

6.

Convertir toutes les entres du type slectionn. choue s'il n'y a pas de conversion partir de l'entre donne vers le type slectionn.

Quelques exemples suivent.


Exemple 10.7. Rsolution de types avec des types sous-spcifis dans une union

SELECT text 'a' AS "text" UNION SELECT 'b';


text
-----a
b
(2 rows)
Ici, la chane de type inconnu 'b' sera convertie vers le type text.

220

Conversion de types

Exemple 10.8. Rsolution de types dans une union simple

SELECT 1.2 AS "numeric" UNION SELECT 1;


numeric
--------1
1.2
(2 rows)
Le littral 1.2 est du type numeric et la valeur 1, de type integer, peut tre convertie implicitement vers un type numeric, donc ce
type est utilis.

Exemple 10.9. Rsolution de types dans une union transpose

SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);


real
-----1
2.2
(2 rows)
Dans cet exemple, le type real (rel) ne peut pas tre implicitement converti en integer (entier) mais un integer peut tre implicitement converti en real ; le rsultat de l'union est rsolu comme tant un real.

221

Chapitre 11. Index


L'utilisation d'index est une faon habituelle d'amliorer les performances d'une base de donnes. Un index permet au serveur de
bases de donnes de retrouver une ligne spcifique bien plus rapidement. Mais les index ajoutent aussi une surcharge au systme
de base de donnes dans son ensemble, si bien qu'ils doivent tre utiliss avec discernement.

11.1. Introduction
Soit une table dfinie ainsi :
CREATE TABLE test1 (
id integer,
contenu varchar
);
et une application qui utilise beaucoup de requtes de la forme :
SELECT contenu FROM test1 WHERE id = constante;
Sans prparation, le systme doit lire la table test1 dans son intgralit, ligne par ligne, pour trouver toutes les lignes qui correspondent. S'il y a beaucoup de lignes dans test1, et que seules quelques lignes correspondent la requte (peut-tre mme zro ou
une seule), alors, clairement, la mthode n'est pas efficace. Mais si le systme doit maintenir un index sur la colonne id, alors il
peut utiliser une manire beaucoup plus efficace pour trouver les lignes recherches. Il se peut qu'il n'ait ainsi qu' parcourir
quelques niveaux d'un arbre de recherche.
Une approche similaire est utilise dans la plupart des livres autres que ceux de fiction : les termes et concepts frquemment recherchs par les lecteurs sont lists par ordre alphabtique la fin du livre. Le lecteur qui recherche un mot particulier peut facilement parcourir l'index, puis aller directement la page (ou aux pages) indique(s). De la mme faon que l'auteur doit anticiper les sujets que les lecteurs risquent de rechercher, il est de la responsabilit du programmeur de prvoir les index qui sont
utiles.
La commande suivante peut tre utilis pour crer un index sur la colonne id :
CREATE INDEX test1_id_index ON test1 (id);
Le nom test1_id_index peut tre choisi librement mais il est conseill de choisir un nom qui rappelle le but de l'index.
Pour supprimer l'index, on utilise la commande DROP INDEX. Les index peuvent tre ajouts et retirs des tables tout moment.
Une fois un index cr, aucune intervention supplmentaire n'est ncessaire : le systme met jour l'index lorsque la table est
modifie et utilise l'index dans les requtes lorsqu'il pense que c'est plus efficace qu'une lecture complte de la table. Il faut
nanmoins lancer la commande ANALYZE rgulirement pour permettre l'optimiseur de requtes de prendre les bonnes dcisions. Voir le Chapitre 14, Conseils sur les performances pour comprendre quand et pourquoi l'optimiseur dcide d'utiliser ou de
ne pas utiliser un index.
Les index peuvent aussi bnficier aux commandes UPDATE et DELETE conditions de recherche. De plus, les index
peuvent tre utiliss dans les jointures. Ainsi, un index dfini sur une colonne qui fait partie d'une condition de jointure peut aussi acclrer significativement les requtes avec jointures.
Crer un index sur une grosse table peut prendre beaucoup de temps. Par dfaut, PostgreSQL autorise la lecture (SELECT)
sur la table pendant la cration d'un index sur celle-ci, mais interdit les critures (INSERT, UPDATE, DELETE). Elles sont
bloques jusqu' la fin de la construction de l'index. Dans des environnements de production, c'est souvent inacceptable. Il est
possible d'autoriser les critures en parallle de la cration d'un index, mais quelques prcautions sont prendre. Pour plus
d'informations, voir la section intitule Construire des index en parallle .
Aprs la cration d'un index, le systme doit le maintenir synchronis avec la table. Cela rend plus lourdes les oprations de manipulation de donnes. C'est pourquoi les index qui sont peu, voire jamais, utiliss doivent tre supprims.

11.2. Types d'index


PostgreSQL propose plusieurs types d'index : B-tree, Hash, GiST et GIN. Chaque type d'index utilise un algorithme diffrent
qui convient un type particulier de requtes. Par dfaut, la commande CREATE INDEX cre un index B-tree, ce qui convient
dans la plupart des situations. Les index B-tree savent traiter les requtes d'galit et par tranches sur des donnes qu'il est possible de trier. En particulier, l'optimiseur de requtes de PostgreSQL considre l'utilisation d'un index B-tree lorsqu'une colonne indexe est utilise dans une comparaison qui utilise un de ces oprateurs :
<
222

Index

<=
=
>=
>
Les constructions quivalentes des combinaisons de ces oprateurs, comme BETWEEN et IN, peuvent aussi tre implantes avec
une recherche par index B-tree. Une condition IS NULL ou IS NOT NULL sur une colonne indexe peut aussi tre utilis avec
un index B-tree.
L'optimiseur peut aussi utiliser un index B-tree pour des requtes qui utilisent les oprateurs de recherche de motif LIKE et ~ si le
motif est une constante et se trouve au dbut de la chane rechercher -- par exemple, col LIKE 'foo%' ou col ~
'^foo', mais pas col LIKE '%bar'. Toutefois, si la base de donnes n'utilise pas la locale C, il est ncessaire de crer
l'index avec une classe d'oprateur spciale pour supporter l'indexation correspondance de modles. Voir la Section 11.9,
Classes et familles d'oprateurs ci-dessous. Il est aussi possible d'utiliser des index B-tree pour ILIKE et ~*, mais seulement
si le modle dbute par des caractres non alphabtiques, c'est--dire des caractres non affects par les conversions majuscules/
minuscules.
Les index B-tree peuvent aussi tre utiliss pour rcuprer des donnes tries. Ce n'est pas toujours aussi rapide qu'un simple parcours squentiel suivi d'un tri mais c'est souvent utile.
Les index hash ne peuvent grer que des comparaisons d'galit simple. Le planificateur de requtes considre l'utilisation d'un index hash quand une colonne indexe est implique dans une comparaison avec l'oprateur =. La commande suivante est utilise
pour crer un index hash :
CREATE INDEX nom ON table USING hash (column);

Attention
Les oprations sur les index de hachage ne sont pas traces par les journaux de transactions. Il est donc gnralement ncessaire de les reconstruire avec REINDEX aprs un arrt brutal de la base de donnes si des modifications
n'ont pas t crites. De plus, les modifications dans les index hash ne sont pas rpliques avec la rplication Warm
Standby aprs la sauvegarde de base initiale, donc ces index donneront de mauvaises rponses aux requtes qui les
utilisent. Pour ces raisons, l'utilisation des index hash est actuellement dconseille.
Les index GiST ne constituent pas un unique type d'index, mais plutt une infrastructure l'intrieur de laquelle plusieurs stratgies d'indexage peuvent tre implantes. De cette faon, les oprateurs particuliers avec lesquels un index GiST peut tre utilis
varient en fonction de la stratgie d'indexage (la classe d'oprateur). Par exemple, la distribution standard de PostgreSQL inclut
des classes d'oprateur GiST pour plusieurs types de donnes gomtriques deux dimensions, qui supportent des requtes indexes utilisant ces oprateurs :
<<
&<
&>
>>
<<|
&<|
|&>
|>>
@>
<@
~=
&&
Voir la Section 9.11, Fonctions et oprateurs gomtriques pour connatre la signification de ces oprateurs. De plus, une
condition IS NULL sur une colonne d'index peut tre utilise avec un index GiST. Beaucoup de classes d'oprateur GiST sont
disponibles dans l'ensemble des contrib ou comme projet spar. Pour plus d'informations, voir Chapitre 53, Index GiST.
Les index GiST sont aussi capables d'optimiser des recherches du type voisin-le-plus-proche (nearest-neighbor), comme par
exemple :
SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
qui trouve les dix places les plus proches d'une cible donne. Cette fonctionnalit dpend de nouveau de la classe d'oprateur utilise.
Les index GIN sont des index inverss qui peuvent grer des valeurs contenant plusieurs cls, les tableaux par exemple. Comme
GiST, GIN supporte diffrentes stratgies d'indexation utilisateur. Les oprateurs particuliers avec lesquels un index GIN peut tre
223

Index

utilis varient selon la stratgie d'indexation. Par exemple, la distribution standard de PostgreSQL inclut des classes d'oprateurs
GIN pour des tableaux une dimension qui supportent les requtes indexes utilisant ces oprateurs :
<@
@>
=
&&
Voir Section 9.17, Fonctions et oprateurs de tableaux pour la signification de ces oprateurs. Beaucoup d'autres classes
d'oprateurs GIN sont disponibles dans les modules contrib ou dans des projets spars. Pour plus d'informations, voir Chapitre 54, Index GIN.

11.3. Index multicolonnes


Un index peut porter sur plusieurs colonnes d'une table. Soit, par exemple, une table de la forme :
CREATE TABLE test2 (
majeur int,
mineur int,
nom varchar
);
(cas d'un utilisateur gardant son rpertoire /dev dans une base de donnes...) et que des requtes comme :
SELECT nom FROM test2 WHERE majeur = constante AND mineur = constante;
sont frquemment excutes. Il peut alors tre souhaitable de dfinir un index qui porte sur les deux colonnes majeur et
mineur. Ainsi, par exemple :
CREATE INDEX test2_mm_idx ON test2 (majeur, mineur);
Actuellement, seuls les types d'index B-trees, GiST et GIN supportent les index multicolonnes. 32 colonnes peuvent tre prcises, au maximum. Cette limite peut tre modifie la compilation de PostgreSQL. Voir le fichier pg_config_manual.h.
Un index B-tree multicolonne peut tre utilis avec des conditions de requtes impliquant un sous-ensemble quelconque de colonnes de l'index. L'index est toutefois plus efficace lorsqu'il y a des contraintes sur les premires colonnes (celles de gauche). La
rgle exacte est la suivante : les contraintes d'galit sur les premires colonnes, et toute contrainte d'ingalit sur la premire colonne qui ne possde pas de contrainte d'galit sont utilises pour limiter la partie parcourue de l'index. Les contraintes sur les colonnes droite de ces colonnes sont vrifies dans l'index, et limitent ainsi les visites de la table, mais elles ne rduisent pas la partie de l'index parcourir.
Par exemple, avec un index sur (a, b, c) et une condition de requte WHERE a = 5 AND b >= 42 AND c < 77,
l'index est parcouru partir de la premire entre pour laquelle a = 5 et b = 42 jusqu' la dernire entre pour laquelle a = 5. Les
entres de l'index avec c >= 77 sont sautes, mais elles sont toujours parcourues. En principe, cet index peutt tre utilis pour les
requtes qui ont des contraintes sur b et/ou c sans contrainte sur a -- mais l'index entier doit tre parcouru, donc, dans la plupart
des cas, le planificateur prfre un parcours squentiel de la table l'utilisation de l'index.
Un index GiST multicolonne peut tre utilis avec des conditions de requte qui impliquent un sous-ensemble quelconque de colonnes de l'index. Les conditions sur des colonnes supplmentaires restreignent les entres renvoyes par l'index, mais la condition
sur la premire colonne est la plus importante pour dterminer la part de l'index parcourue. Un index GiST est relativement inefficace si sa premire colonne n'a que quelques valeurs distinctes, mme s'il y a beaucoup de valeurs distinctes dans les colonnes
supplmentaires.
Un index multi-colonnes GIN peut tre utilis avec des conditions de requte qui implique tout sous-ensemble des colonnes de
l'index. Contrairement B-tree ou GiST, la qualit de la recherche dans l'index est identique quelque soit les colonnes de l'index
que la requte utilise
Chaque colonne doit videmment tre utilise avec des oprateurs appropris au type de l'index ; les clauses qui impliquent
d'autres oprateurs ne sont pas pris en compte.
Il est prfrable d'utiliser les index multicolonnes avec parcimonie. Dans la plupart des cas, un index sur une seule colonne est suffisant et prserve espace et temps. Les index de plus de trois colonnes risquent fort d'tre inefficaces, sauf si l'utilisation de cette
table est extrmement stylise. Voir aussi la Section 11.5, Combiner des index multiples pour les discussions sur les mrites
des diffrentes configurations d'index.

11.4. Index et ORDER BY


Au del du simple fait de trouver les lignes renvoyer une requte, un index peut les renvoyer dans un ordre spcifique. Cela
permet de rsoudre une clause ORDER BY sans tape de tri spare. De tous les types d'index actuellement supports par PostgreSQL, seuls les B-tree peuvent produire une sortie trie -- les autres types d'index renvoient les lignes correspondantes dans
224

Index

un ordre imprcis, dpendant de l'implantation.


Le planificateur rpond une clause ORDER BY soit en parcourant un index disponible qui correspond la clause, soit en parcourant la table dans l'ordre physique et en ralisant un tri explicite. Pour une requte qui ncessite de parcourir une fraction importante de la table, le tri explicite est probablement plus rapide que le parcours d'un index car il ncessite moins d'entres/sorties
disque, du fait de son accs squentiel. Les index sont plus utiles lorsqu'il s'agit de ne rcuprer que quelques lignes tre rcupres. ORDER BY combin LIMIT n est un cas spcial trs important : un tri explicite doit traiter toutes les donnes pour identifier les n premire lignes, mais s'il y a un index qui correspond l'ORDER BY, alors les n premires lignes peuvent tre rcupres directement sans qu'il soit ncessaires de parcourir les autres.
Par dfaut, les index B-tree stockent leurs entres dans l'ordre ascendant, valeurs NULL en dernier. Cela signifie que le parcours
avant d'un index sur une colonne x produit une sortie satisfaisant ORDER BY x (ou en plus verbeux ORDER BY x ASC
NULLS LAST). L'index peut aussi tre parcouru en arrire, produisant ainsi une sortie satisfaisant un ORDER BY x DESC (ou
en plus verbeux ORDER BY x DESC NULLS FIRST car NULLS FIRST est la valeur par dfaut pour un ORDER BY
DESC).
L'ordre d'un index B-tree peut tre dfini la cration par l'inclusion des options ASC, DESC, NULLS FIRST, et/ou NULLS
LAST lors de la cration de l'index ; par exemple :
CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST);
CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
Un index stock en ordre ascendant avec les valeurs NULL en premier peut satisfaire soit ORDER BY x ASC NULLS FIRST
soit ORDER BY x DESC NULLS LAST selon la direction du parcours.
On peut s'interroger sur l'intrt de proposer quatre options, alors que deux options associes la possibilit d'un parcours inverse
semblent suffire couvrir toutes les variantes d'ORDER BY. Dans les index mono-colonne, les options sont en effet redondantes,
mais pour un index plusieurs colonnes, elles sont utiles. Si l'on considre un index deux colonnes (x, y), il peut satisfaire
une clause ORDER BY x, y sur un parcours avant, ou ORDER BY x DESC, y DESC sur un parcours inverse. Mais il se
peut que l'application utilise frquemment ORDER BY x ASC, y DESC. Il n'y a pas moyen d'obtenir cet ordre partir d'un index plus simple, mais c'est possible si l'index est dfini comme (x ASC, y DESC) or (x DESC, y ASC).
Les index d'ordre diffrent de celui par dfaut sont visiblement une fonctionnalit trs spcialise, mais ils peuvent parfois tre
l'origine d'acclrations spectaculaires des performances sur certaines requtes. L'intrt de maintenir un tel index dpend de la
frquence des requtes qui ncessitent un tri particulier.

11.5. Combiner des index multiples


Un parcours unique d'index ne peut utiliser que les clauses de la requte qui utilisent les colonnes de l'index avec les oprateurs de
sa classe d'oprateur et qui sont jointes avec AND. Par exemple, tant donn un index sur (a, b), une condition de requte
WHERE a = 5 AND b = 6 peut utiliser l'index, mais une requte WHERE a = 5 OR b = 6 ne peutt pas l'utiliser directement.
Heureusement, PostgreSQL peut combiner plusieurs index (y compris plusieurs utilisations du mme index) pour grer les cas
qui ne peuvent pas tre rsolus par des parcours d'index simples. Le systme peut former des conditions AND et OR sur plusieurs
parcours d'index. Par exemple, une requte comme WHERE x = 42 OR x = 47 OR x = 53 OR x = 99 peut tre divise en quatre parcours distincts d'un index sur x, chaque parcours utilisant une des clauses de la requte. Les rsultats de ces parcours sont alors assembls par OR pour produire le rsultat. Autre exemple, s'il existe des index spars sur x et y, une rsolution
possible d'une requte comme WHERE x = 5 AND y = 6 consiste utiliser chaque index avec la clause de la requte approprie et d'assembler les diffrents rsultats avec un AND pour identifier les lignes rsultantes.
Pour combiner plusieurs index, le systme parcourt chaque index ncessaire et prpare un bitmap en mmoire qui donne
l'emplacement des lignes de table qui correspondent aux conditions de l'index. Les bitmaps sont ensuite assembls avec des oprateurs AND ou OR selon les besoins de la requte. Enfin, les lignes relles de la table sont visites et renvoyes. Elles sont visites
dans l'ordre physique parce c'est ainsi que le bitmap est cr ; cela signifie que l'ordre des index originaux est perdu et que, du
coup, une tape de tri spare est ncessaire si la requte comprend une clause ORDER BY. Pour cette raison, et parce que chaque
parcours d'index supplmentaire ajoute un temps additionnel, le planificateur choisit quelque fois d'utiliser un parcours d'index
simple mme si des index supplmentaires sont disponibles et peuvent tre utiliss.
Le nombre de combinaisons d'index possibles crot paralllement la complexit des applications. Il est alors de la responsabilit
du dveloppeur de la base de dcider des index fournir. Il est quelques fois prfrable de crer des index multi-colonnes, mais il
est parfois prfrable de crer des index spars et de s'appuyer sur la fonctionnalit de combinaison des index.
Par exemple, si la charge inclut un mlange de requtes qui impliquent parfois uniquement la colonne x, parfois uniquement la colonne y et quelques fois les deux colonnes, on peut choisir deux index spars sur x et y et s'appuyer sur la combinaison d'index
pour traiter les requtes qui utilisent les deux colonnes. On peut aussi crer un index multi-colonnes sur (x, y). Cet index est typiquement plus efficace que la combinaison d'index pour les requtes impliquant les deux colonnes mais, comme discut dans la
225

Index

Section 11.3, Index multicolonnes , il est pratiquement inutile pour les requtes n'impliquant que y. Il ne peut donc pas tre le
seul index. Une combinaison de l'index multi-colonnes et d'un index spar sur y est une solution raisonnable. Pour les requtes
qui n'impliquent que x, l'index multi-colonnes peut tre utilis, bien qu'il soit plus large et donc plus lent qu'un index sur x seul.
La dernire alternative consiste crer les trois index, mais cette solution n'est raisonnable que si la table est lue bien plus frquemment qu'elle n'est mise jour et que les trois types de requte sont communs. Si un des types de requte est bien moins courant que les autres, il est prfrable de ne crer que les deux index qui correspondent le mieux aux types communs.

11.6. Index d'unicit


Les index peuvent aussi tre utiliss pour garantir l'unicit des valeurs d'une colonne, ou l'unicit des valeurs combines de plusieurs colonnes.
CREATE UNIQUE INDEX nom ON table (colonne [, ...]);
ce jour, seuls les index B-trees peuvent tre dclars uniques.
Lorsqu'un index est dclar unique, il ne peut exister plusieurs lignes d'une table qui possdent la mme valeur indexe. Les valeurs NULL ne sont pas considres gales. Un index d'unicit multi-colonnes ne rejette que les cas o toutes les colonnes indexes sont gales dans plusieurs lignes.
PostgreSQL cre automatiquement un index d'unicit la dclaration d'une contrainte d'unicit ou d'une cl primaire sur une
table. L'index porte sur les colonnes qui composent la cl primaire ou la contrainte d'unicit (au besoin, il s'agit d'un index multicolonnes). C'est cet index qui assure le mcanisme de vrification de la contrainte.

Note
La mthode la plus approprie pour ajouter une contrainte une table est ALTER TABLE ... ADD
CONSTRAINT. L'utilisation des index pour vrifier les contraintes d'unicit peut tre considre comme un dtail
d'implantation qui ne doit pas tre utilis directement. Il n'est pas ncessaire de crer manuellement un index sur les
colonnes uniques. Cela duplique l'index cr automatiquement.

11.7. Index d'expressions


Une colonne d'index ne correspond pas ncessairement exactement une colonne de la table associe, mais peut tre une fonction
ou une expression scalaire calcule partir d'une ou plusieurs colonnes de la table. Cette fonctionnalit est utile pour obtenir un
accs rapide aux tables en utilisant les rsultat de calculs.
Par exemple, une faon classique de faire des comparaisons indpendantes de la casse est d'utiliser la fonction lower :
SELECT * FROM test1 WHERE lower(col1) = 'valeur';
Si un index a t dfini sur le rsultat de lower(col1), cette requte peut l'utiliser. Un tel index est cr avec la commande :
CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
Si l'index est dclar UNIQUE, il empche la cration de lignes dont les valeurs de la colonne col1 ne diffrent que par la casse,
ainsi que celle de lignes dont les valeurs de la colonne col1 sont identiques. Ainsi, les index d'expressions peuvent tre utiliss
pour appliquer des contraintes qui ne peuvent tre dfinies avec une simple contrainte d'unicit.
Autre exemple. Lorsque des requtes comme :
SELECT * FROM personnes WHERE (prenom || ' ' || nom) = 'Jean Dupont';
sont frquentes, alors il peut tre utile de crer un index comme :
CREATE INDEX personnes_noms ON personnes ((prenom || ' ' || nom));
La syntaxe de la commande CREATE INDEX ncessite normalement de mettre des parenthses autour de l'expression indexe,
comme dans l'exemple prcdent. Les parenthses peuvent tre omises quand l'expression est un simple appel de fonction, comme
dans le premier exemple.
Les expressions d'index sont relativement coteuses calculer car l'expression doit tre recalcule chaque insertion ou mise
jour de ligne. Nanmoins, les expressions d'index ne sont pas recalcules lors d'une recherche par index car elles sont dj stocks
dans l'index. Dans les deux exemples ci-dessus, le systme voit la requte comme un WHERE colonne_indexe =
'constante'. De ce fait, la recherche est aussi rapide que toute autre requte d'index. Ainsi, les index d'expressions sont utiles
lorsque la rapidit de recherche est plus importante que la rapidit d'insertion et de mise jour.

226

Index

11.8. Index partiels


Un index partiel est un index construit sur un sous-ensemble d'une table ; le sous-ensemble est dfini par une expression conditionnelle (appele prdicat de l'index partiel). L'index ne contient des entres que pour les lignes de la table qui satisfont au prdicat. Les index partiels sont une fonctionnalit spcialise, mais ils trouvent leur utilit dans de nombreuses situations.
Une raison majeure l'utilisation d'index partiels est d'viter d'indexer les valeurs courantes. Puisqu'une requte qui recherche une
valeur courante (qui correspond plus de quelques pourcents de toutes les lignes) n'utilise, de toute faon, pas cet index, il ne sert
rien de garder ces lignes dans l'index. Cela rduit la taille de l'index, ce qui acclrera les requtes qui l'utilisent. Cela acclre
aussi nombre d'oprations de mise jour de la table, car l'index n'a pas tre mis jour chaque fois. L'Exemple 11.1, Mettre
en place un index partiel pour exclure des valeurs courantes montre une application possible de cette ide.
Exemple 11.1. Mettre en place un index partiel pour exclure des valeurs courantes

Soit l'enregistrement d'un journal d'accs un serveur web dans une base de donnes. La plupart des accs proviennent de classes
d'adresses IP internes l'organisation, mais certaines proviennent de l'extrieur (des employs connects par modem, par
exemple). Si les recherches par adresses IP concernent essentiellement les accs extrieurs, il est inutile d'indexer les classes
d'adresses IP qui correspondent au sous-rseau de l'organisation.
Si la table ressemble :
CREATE TABLE access_log (
url varchar,
client_ip inet,
...
);
Pour crer un index partiel qui corresponde l'exemple, il faut utiliser une commande comme celle-ci :
CREATE INDEX access_log_client_ip_ix ON access_log (client_ip)
WHERE NOT (client_ip > inet '192.168.100.0' AND
client_ip < inet '192.168.100.255');
Une requte typique qui peut utiliser cet index est :
SELECT *
FROM access_log
WHERE url = '/index.html' AND client_ip = inet '212.78.10.32';
Une requte qui ne peut pas l'utiliser est :
SELECT *
FROM access_log
WHERE client_ip = inet '192.168.100.23';
Ce type d'index partiel ncessite que les valeurs courantes soient prdtermines, de faon ce que ce type d'index soit mieux utilis avec une distribution des donnes qui ne change pas. Les index peuvent tre recrs occasionnellement pour s'adapter aux
nouvelles distributions de donnes, mais cela ajoute de la maintenance.
Une autre utilisation possible d'index partiel revient exclure des valeurs de l'index qui ne correspondent pas aux requtes courantes ; ceci est montr dans l'Exemple 11.2, Mettre en place un index partiel pour exclure les valeurs inintressantes . Cette
mthode donne les mmes avantages que la prcdente mais empche l'accs par l'index aux valeurs sans intrt . videmment,
mettre en place des index partiels pour ce genre de scnarios ncessite beaucoup de soin et d'exprimentation.
Exemple 11.2. Mettre en place un index partiel pour exclure les valeurs inintressantes

Soit une table qui contient des commandes factures et des commandes non factures, avec les commandes non factures qui ne
prennent qu'une petite fraction de l'espace dans la table, et qu'elles sont les plus accdes. Il est possible d'amliorer les performances en crant un index limit aux lignes non factures. La commande pour crer l'index ressemble :
CREATE INDEX index_commandes_nonfacturees ON commandes (no_commande)
WHERE facturee is not true;
La requte suivante utilise cet index :
SELECT * FROM commandes WHERE facturee is not true AND no_commande < 10000;
227

Index

Nanmoins, l'index peut aussi tre utilis dans des requtes qui n'utilisent pas no_commande, comme :
SELECT * FROM commandes WHERE facturee is not true AND montant > 5000.00;
Ceci n'est pas aussi efficace qu'un index partiel sur la colonne montant, car le systme doit lire l'index en entier. Nanmoins, s'il
y a assez peu de commandes non factures, l'utilisation de cet index partiel pour trouver les commandes non factures peut tre
plus efficace.
La requte suivante ne peut pas utiliser cet index :
SELECT * FROM commandes WHERE no_commande = 3501;
La commande 3501 peut faire partie des commandes factures ou non factures.
L'Exemple 11.2, Mettre en place un index partiel pour exclure les valeurs inintressantes illustre aussi le fait que la colonne indexe et la colonne utilise dans le prdicat ne sont pas ncessairement les mmes. PostgreSQL supporte tous les prdicats sur
les index partiels, tant que ceux-ci ne portent que sur des champs de la table indexe. Nanmoins, il faut se rappeler que le prdicat
doit correspondre aux conditions utilises dans les requtes qui sont supposes profiter de l'index. Pour tre prcis, un index partiel
ne peut tre utilis pour une requte que si le systme peut reconnatre que la clause WHERE de la requte implique mathmatiquement le prdicat de l'index. PostgreSQL n'a pas de mthode sophistique de dmonstration de thorme pour reconnatre que
des expressions apparemment diffrentes sont mathmatiquement quivalentes. (Non seulement une telle mthode gnrale de dmonstration serait extrmement complexe crer mais, en plus, elle serait probablement trop lente pour tre d'une quelconque utilit). Le systme peut reconnatre des implications d'ingalits simples, par exemple x < 1 implique x < 2 ; dans les autres
cas, la condition du prdicat doit correspondre exactement une partie de la clause WHERE de la requte, sans quoi l'index ne peut
pas tre considr utilisable. La correspondance prend place lors de l'excution de la planification de la requte, pas lors de
l'excution. ce titre, les clauses de requtes paramtres ne fonctionnent pas avec un index partiel. Par exemple, une requte
prpare avec un paramtre peut indiquer x < ? qui n'implique jamais x < 2 pour toutes les valeurs possibles du paramtre.
Un troisime usage possible des index partiels ne ncessite pas que l'index soit utilis dans des requtes. L'ide ici est de crer un
index d'unicit sur un sous-ensemble de la table, comme dans l'Exemple 11.3, Mettre en place un index d'unicit partiel . Cela
permet de mettre en place une unicit parmi le sous-ensemble des lignes de la table qui satisfont au prdicat, sans contraindre les
lignes qui n'y satisfont pas.
Exemple 11.3. Mettre en place un index d'unicit partiel

Soit une table qui dcrit des rsultats de tests. On souhaite s'assurer qu'il n'y a qu'une seule entre succs (succes) pour chaque
combinaison de sujet et de rsultat, alors qu'il peut y avoir un nombre quelconque d'entres echec . Une faon de procder :
CREATE TABLE tests (
sujet text,
resultat text,
succes boolean,
...
);
CREATE UNIQUE INDEX contrainte_tests_reussis ON tests (sujet, resultat)
WHERE succes;
C'est une mthode trs efficace quand il y a peu de tests russis et beaucoup de tests en chec.
Enfin, un index partiel peut aussi tre utilis pour surcharger les choix de plan d'excution de requte du systme. De plus, des
jeux de donnes distribution particulire peuvent inciter le systme utiliser un index alors qu'il ne devrait pas. Dans ce cas, on
peut mettre en place l'index de telle faon qu'il ne soit pas utilis pour la requte qui pose problme. Normalement, PostgreSQL
fait des choix d'usage d'index raisonnables. Par exemple, il les vite pour rechercher les valeurs communes, si bien que l'exemple
prcdent n'conomise que la taille de l'index, il n'est pas ncessaire pour viter l'utilisation de l'index. En fait, les choix de plan
d'excution incorrects doivent tre traits comme des bogues, et tre transmis l'quipe de dveloppement.
Mettre en place un index partiel indique une connaissance au moins aussi tendue que celle de l'analyseur de requtes, en particulier, savoir quand un index peut tre profitable. Une telle connaissance ncessite de l'exprience et une bonne comprhension du
fonctionnement des index de PostgreSQL. Dans la plupart des cas, les index partiels ne reprsentent pas un gros gain par rapport aux index classiques.
Plus d'informations sur les index partiels est disponible dans Stonebraker, M, 1989b, olson93 et Seshardri, 1995.

11.9. Classes et familles d'oprateurs


Une dfinition d'index peut indiquer une classe d'oprateurs pour chaque colonne de l'index.
228

Index

CREATE INDEX nom ON table (colonne classe_operateur

[options de tri][, ...]);

La classe d'oprateurs identifie les oprateurs que l'index doit utiliser sur cette colonne. Par exemple, un index B-tree sur une colonne de type int4 utilise la classe int4_ops. Cette classe d'oprateurs comprend des fonctions de comparaison pour les valeurs
de type int4. En pratique, la classe d'oprateurs par dfaut pour le type de donnes de la colonne est gnralement suffisante. Les
classes d'oprateurs sont utiles pour certains types de donnes, pour lesquels il peut y avoir plus d'un comportement utile de
l'index. Par exemple, une donne de type nombre complexe peut tre classe par sa valeur absolue, ou par sa partie entire. Cela
peut s'obtenir en dfinissant deux classes d'oprateurs pour ce type de donnes et en slectionnant la bonne classe la cration de
l'index. La classe d'oprateur dtermine l'ordre de tri basique (qui peut ensuite tre modifi en ajoutant des options de tri comme
COLLATE, ASC/DESC et/ou NULLS FIRST/NULLS LAST).
Il y a quelques classes d'oprateurs en plus des classes par dfaut :

Les classes d'oprateurs text_pattern_ops, varchar_pattern_ops et bpchar_pattern_ops supportent les index B-tree sur les types text, varchar et char, respectivement. la diffrence des classes d'oprateurs par dfaut, les valeurs
sont compares strictement caractre par caractre plutt que suivant les rgles de tri spcifiques la localisation. Cela rend
ces index utilisables pour des requtes qui utilisent des recherches sur des motifs (LIKE ou des expressions rgulires POSIX)
quand la base de donnes n'utilise pas la locale standard C . Par exemple, on peut indexer une colonne varchar comme ceci :
CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
Il faut crer un index avec la classe d'oprateurs par dfaut pour que les requtes qui utilisent une comparaison <, <=, > ou >=
ordinaire utilisent un index. De telles requtes ne peuvent pas utiliser les classes d'oprateurs xxx_pattern_ops. Nanmoins, des comparaisons d'galit ordinaires peuvent utiliser ces classes d'oprateur. Il est possible de crer plusieurs index sur
la mme colonne avec diffrentes classes d'oprateurs. Si la locale C est utilise, les classes d'oprateur xxx_pattern_ops
ne sont pas ncessaires, car un index avec une classe d'oprateurs par dfaut est utilisable pour les requtes de correspondance
de modles dans la locale C.

Les requtes suivantes montrent les classes d'oprateurs prdfinies :


SELECT am.amname AS index_method,
opc.opcname AS opclass_name
FROM pg_am am, pg_opclass opc
WHERE opc.opcmethod = am.oid
ORDER BY index_method, opclass_name;
Une classe d'oprateurs n'est qu'un sous-ensemble d'une structure plus large appele famille d'oprateurs. Dans les cas o plusieurs types de donnes ont des comportements similaires, il est frquemment utile de dfinir des oprateurs identiques pour plusieurs types de donnes et d'autoriser leur utilisation avec des index. Pour cela, les classes d'oprateur de chacun de ces types
doivent tre groups dans la mme famille d'oprateurs. Les oprateurs inter-types sont membres de la famille, mais ne sont pas
associs avec une seule classe de la famille.
Cette requte affiche toutes les familles d'oprateurs dfinies et tous les oprateurs inclus dans chaque famille :
SELECT am.amname AS index_method,
opf.opfname AS opfamily_name,
amop.amopopr::regoperator AS opfamily_operator
FROM pg_am am, pg_opfamily opf, pg_amop amop
WHERE opf.opfmethod = am.oid AND
amop.amopfamily = opf.oid
ORDER BY index_method, opfamily_name, opfamily_operator;

11.10. Index et collationnements


Un index peut supporter seulement un collationnement par colonne d'index. Si plusieurs collationnements ont un intrt, plusieurs
index pourraient tre ncessaires.
Regardez ces requtes :
CREATE TABLE test1c (
id integer,
content varchar COLLATE "x"
);
CREATE INDEX test1c_content_index ON test1c (content);
229

Index

L'index utilise automatiquement le collationnement de la colonne sous-jacente. Donc une requte de la forme
SELECT * FROM test1c WHERE content > constant;
peut utiliser l'index car la comparaison utilisera par dfaut le collationnement de la colonne. Nanmoins, cet index ne peut pas acclrer les requtes qui impliquent d'autres collationnements. Donc, pour des requtes de cette forme
SELECT * FROM test1c WHERE content > constant COLLATE "y";
un index supplmentaire, supportant le collationnement "y" peut tre ajout ainsi :
CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y");

11.11. Examiner l'utilisation des index


Bien que les index de PostgreSQL n'aient pas besoin de maintenance ou d'optimisation, il est important de s'assurer que les index sont effectivement utiliss sur un systme en production. On vrifie l'utilisation d'un index pour une requte particulire avec
la commande EXPLAIN(7). Son utilisation dans notre cas est explique dans la Section 14.1, Utiliser EXPLAIN . Il est aussi
possible de rassembler des statistiques globales sur l'utilisation des index sur un serveur en cours de fonctionnement, comme dcrit
dans la Section 27.2, Le rcuprateur de statistiques .
Il est difficile de donner une procdure gnrale pour dterminer les index crer. Plusieurs cas typiques ont t cits dans les
exemples prcdents. Une bonne dose d'exprimentation est souvent ncessaire dans de nombreux cas. Le reste de cette section
donne quelques pistes.

La premire chose faire est de lancer ANALYZE(7). Cette commande collecte les informations sur la distribution des valeurs dans la table. Cette information est ncessaire pour estimer le nombre de lignes retournes par une requte. L'optimiseur
de requtes en a besoin pour donner des cots ralistes aux diffrents plans de requtes possibles. En l'absence de statistiques
relles, le systme utilise quelques valeurs par dfaut, qui ont toutes les chances d'tre inadaptes. Examiner l'utilisation des index par une application sans avoir lanc ANALYZE au pralable est, de ce fait, peine perdue. Voir Section 23.1.3,
Maintenir les statistiques du planificateur et Section 23.1.5, Le dmon auto-vacuum pour plus d'informations.

Utiliser des donnes relles pour l'exprimentation. Utiliser des donnes de test pour mettre en place des index permet de trouver les index utiles pour les donnes de test, mais c'est tout.
Il est particulirement nfaste d'utiliser des jeux de donnes trs rduits. Alors qu'une requte slectionnant 1000 lignes parmi
100000 peut utiliser un index, il est peu probable qu'une requte slectionnant 1 ligne dans une table de 100 le fasse, parce que
les 100 lignes tiennent probablement dans une seule page sur le disque, et qu'il n'y a aucun plan d'excution qui puisse aller
plus vite que la lecture d'une seule page.
tre vigilant en crant des donnes de test. C'est souvent invitable quand l'application n'est pas encore en production. Des valeurs trs similaires, compltement alatoires, ou insres dj tries peuvent modifier la distribution des donnes et fausser les
statistiques.

Quand les index ne sont pas utiliss, il peut tre utile pour les tests de forcer leur utilisation. Certains paramtres d'excution
du serveur peuvent interdire certains types de plans (voir la Section 18.7.1, Configuration de la mthode du planificateur ).
Par exemple, en interdisant les lectures squentielles de tables enable_seqscan) et les jointures boucles imbriques
(enable_nestloop), qui sont les deux plans les plus basiques, on force le systme utiliser un plan diffrent. Si le systme continue nanmoins choisir une lecture squentielle ou une jointure boucles imbriques, alors il y a probablement une
raison plus fondamentale qui empche l'utilisation de l'index ; la condition peut, par exemple, ne pas correspondre l'index.
(Les sections prcdentes expliquent quelles sortes de requtes peuvent utiliser quelles sortes d'index.)

Si l'index est effectivement utilis en forant son utilisation, alors il y a deux possibilits : soit le systme a raison et
l'utilisation de l'index est effectivement inapproprie, soit les cots estims des plans de requtes ne refltent pas la ralit. Il
faut alors comparer la dure de la requte avec et sans index. La commande EXPLAIN ANALYZE peut tre utile pour cela.

S'il apparat que les estimations de cots sont fausses, il y a de nouveau deux possibilits. Le cot total est calcul partir du
cot par ligne de chaque nud du plan, multipli par l'estimation de slectivit du nud de plan. Le cot estim des nuds de
plan peut tre ajust avec des paramtres d'excution (dcrits dans la Section 18.7.2, Constantes de cot du planificateur ).
Une estimation de slectivit inadapte est due des statistiques insuffisantes. Il peut tre possible de les amliorer en optimisant les paramtres de collecte de statistiques. Voir ALTER TABLE(7).
Si les cots ne peuvent tre ajusts une meilleure reprsentation de la ralit, alors il faut peut-tre forcer l'utilisation de
l'index explicitement. Il peut aussi s'avrer utile de contacter les dveloppeurs de PostgreSQL afin qu'ils examinent le problme.
230

Chapitre 12. Recherche plein texte


12.1. Introduction
La recherche plein texte (ou plus simplement la recherche de texte) permet de slectionner des documents en langage naturel qui
satisfont une requte et, en option, de les trier par intrt suivant cette requte. Le type le plus frquent de recherche concerne la
rcupration de tous les documents contenant les termes de recherche indiqus et de les renvoyer dans un ordre dpendant de
leur similarit par rapport la requte. Les notions de requte et de similarit peuvent beaucoup varier et dpendent de
l'application relle. La recherche la plus simple considre une requte comme un ensemble de mots et la similarit
comme la frquence des mots de la requte dans le document.
Les oprateurs de recherche plein texte existent depuis longtemps dans les bases de donnes. PostgreSQL dispose des oprateurs ~, ~*, LIKE et ILIKE pour les types de donnes texte, mais il lui manque un grand nombre de proprits essentielles requises par les systmes d'information modernes :

Aucun support linguistique, mme pour l'anglais. Les expressions rationnelles ne sont pas suffisantes car elles ne peuvent
pas grer facilement les mots drives, par exemple satisfait et satisfaire. Vous pouvez laisser passer des documents qui contiennent satisfait bien que vous souhaiteriez quand mme les trouver avec une recherche sur satisfaire. Il est possible d'utiliser OR pour rechercher plusieurs formes drives mais cela devient complexe et augmente le
risque d'erreur (certains mots peuvent avoir des centaines de variantes).
Ils ne fournissent aucun classement (score) des rsultats de la recherche, ce qui les rend inefficaces quand des centaines de
documents correspondants sont trouvs.
Ils ont tendance tre lent car les index sont peu supports, donc ils doivent traiter tous les documents chaque recherche.

L'indexage pour la recherche plein texte permet au document d'tre pr-trait et qu'un index de ce pr-traitement soit sauvegard
pour une recherche ultrieure plus rapide. Le pr-traitement inclut :
Analyse des documents en jetons. Il est utile d'identifier les diffrentes classes de jetons, c'est--dire nombres, mots, mots
complexes, adresses email, pour qu'ils puissent tre traits diffremment. En principe, les classes de jeton dpendent de
l'application mais, dans la plupart des cas, utiliser un ensemble prdfinie de classes est adquat. PostgreSQL utilise un
analyseur pour raliser cette tape. Un analyseur standard est fourni, mais des analyseurs personnaliss peuvent tre crits
pour des besoins spcifiques.
Conversion des jetons en lexemes. Un lexeme est une chane, identique un jeton, mais elle a t normalise pour que diffrentes formes du mme mot soient dcouvertes. Par exemple, la normalisation inclut pratiquement toujours le remplacement
des majuscules par des minuscules, ainsi que la suppression des suffixes (comme s ou es en anglais). Ceci permet aux recherches de trouver les variantes du mme mot, sans avoir besoin de saisir toutes les variantes possibles. De plus, cette tape
limine typiquement les termes courants, qui sont des mots si courants qu'il est inutile de les rechercher. Donc, les jetons
sont des fragments bruts du document alors que les lexemes sont des mots supposs utiles pour l'indexage et la recherche.
PostgreSQL utilise des dictionnaires pour raliser cette tape. Diffrents dictionnaires standards sont fournis et des dictionnaires personnaliss peuvent tre crs pour des besoins spcifiques.
Stockage des documents pr-traits pour optimiser la recherche . Chaque document peut tre reprsent comme un tableau
tri de lexemes normaliss. Avec ces lexemes, il est souvent souhaitable de stocker des informations de position utiliser
pour obtenir un score de proximit, pour qu'un document qui contient une rgion plus dense des mots de la requte se
voit affect un score plus important qu'un document qui en a moins.
Les dictionnaires autorisent un contrle fin de la normalisation des jetons. Avec des dictionnaires appropris, vous pouvez :

Dfinir les termes courants qui ne doivent pas tre indexs.


tablir une liste des synonymes pour un simple mot en utilisant Ispell.
tablir une correspondance entre des phrases et un simple mot en utilisant un thsaurus.
tablir une correspondance entre diffrentes variations d'un mot et une forme canonique en utilisant un dictionnaire Ispell.
tablir une correspondance entre diffrentes variations d'un mot et une forme canonique en utilisant les rgles du stemmer
Snowball.

Un type de donnes tsvector est fourni pour stocker les documents pr-traits, avec un type tsquery pour reprsenter les requtes
traites (Section 8.11, Types de recherche plein texte ). Il existe beaucoup de fonctions et d'oprateurs disponibles pour ces
types de donnes (Section 9.13, Fonctions et oprateurs de la recherche plein texte ), le plus important tant l'oprateur de
correspondance @@, dont nous parlons dans la Section 12.1.2, Correspondance de base d'un texte . Les recherches plein texte
peuvent tre acclres en utilisant des index (Section 12.9, Types d'index GiST et GIN ).

231

Recherche plein texte

12.1.1. Qu'est-ce qu'un document ?


Un document est l'unit de recherche dans un systme de recherche plein texte, par exemple un article de magazine ou un message
email. Le moteur de recherche plein texte doit tre capable d'analyser des documents et de stocker les associations de lexemes
(mots cls) avec les documents parents. Ensuite, ces associations seront utilises pour rechercher les documents contenant des
mots de la requte.
Pour les recherches dans PostgreSQL, un document est habituellement un champ texte l'intrieur d'une ligne d'une table de la
base ou une combinaison (concatnation) de champs, parfois stocks dans diffrentes tables ou obtenus dynamiquement. En
d'autres termes, un document peut tre construit partir de diffrentes parties pour l'indexage et il peut ne pas tre stock quelque
part. Par exemple :
SELECT titre || ' ' ||
FROM messages
WHERE mid = 12;

auteur || ' ' ||

resume || ' ' || corps AS document

SELECT m.titre || ' ' || m.auteur || ' ' || m.resume || ' ' || d.corps AS document
FROM messages m, docs d
WHERE mid = did AND mid = 12;

Note
En fait, dans ces exemples de requtes, coalesce devrait tre utilis pour empcher un rsultat NULL pour le document entier cause d'une seule colonne NULL.
Une autre possibilit est de stocker les documents dans de simples fichiers texte du systme de fichiers. Dans ce cas, la base est
utilise pour stocker l'index de recherche plein texte et pour excuter les recherches, et un identifiant unique est utilis pour retrouver le document sur le systme de fichiers. Nanmoins, retrouver les fichiers en dehors de la base demande les droits d'un superutilisateur ou le support de fonctions spciales, donc c'est habituellement moins facile que de conserver les donnes dans PostgreSQL. De plus, tout conserver dans la base permet un accs simple aux mta-donnes du document pour aider l'indexage et
l'affichage.
Dans le but de la recherche plein texte, chaque document doit tre rduit au format de pr-traitement, tsvector. La recherche et le
calcul du score sont raliss entirement partir de la reprsentation tsvector d'un document -- le texte original n'a besoin d'tre retrouv que lorsque le document a t slectionn pour tre montr l'utilisateur. Nous utilisons souvent tsvector pour le document
mais, bien sr, il ne s'agit que d'une reprsentation compacte du document complet.

12.1.2. Correspondance de base d'un texte


La recherche plein texte dans PostgreSQL est base sur l'oprateur de correspondance @@, qui renvoie true si un tsvector
(document) correspond un tsquery (requte). Peu importe le type de donnes indiqu en premier :
SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat & rat'::tsquery;
?column?
---------t
SELECT 'fat & cow'::tsquery @@ 'a fat cat sat on a mat and ate a fat rat'::tsvector;
?column?
---------f
Comme le suggre l'exemple ci-dessus, un tsquery n'est pas un simple texte brut, pas plus qu'un tsvector ne l'est. Un tsquery
contient des termes de recherche qui doivent dj tre des lexemes normaliss, et peut combiner plusieurs termes en utilisant les
oprateurs AND, OR et NOT. (Pour les dtails, voir la Section 8.11, Types de recherche plein texte .) Les fonctions
to_tsquery et plainto_tsquery sont utiles pour convertir un texte crit par un utilisateur dans un tsquery correct, par
exemple en normalisant les mots apparaissant dans le texte. De faon similaire, to_tsvector est utilis pour analyser et normaliser un document. Donc, en pratique, une correspondance de recherche ressemblerait plutt ceci :
SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat');
?column?
---------t
232

Recherche plein texte

Observez que cette correspondance ne russit pas si elle est crite ainsi :
SELECT 'fat cats ate fat rats'::tsvector @@ to_tsquery('fat & rat');
?column?
---------f
car ici aucune normalisation du mot rats n'interviendra. Les lments d'un tsvector sont des lexemes, qui sont supposs dj normaliss, donc rats ne correspond pas rat.
L'oprateur @@ supporte aussi une entre de type text, permettant l'oubli de conversions explicites de text vers tsvector ou tsquery
dans les cas simples. Les variantes disponibles sont :
tsvector @@ tsquery
tsquery @@ tsvector
text @@ tsquery
text @@ text
Nous avons dj vu les deux premires. La forme text @@ tsquery est quivalent to_tsvector(x) @@ y. La forme text @@
text est quivalente to_tsvector(x) @@ plainto_tsquery(y).

12.1.3. Configurations
Les exemples ci-dessus ne sont que des exemples simples de recherche plein texte. Comme mentionn prcdemment, la recherche plein texte permet de faire beaucoup plus : ignorer l'indexation de certains mots (termes courants), traiter les synonymes
et utiliser une analyse sophistique, c'est--dire une analyse base sur plus qu'un espace blanc. Ces fonctionnalits sont contrles
par les configurations de recherche plein texte. PostgreSQL arrive avec des configurations prdfinies pour de nombreux langages et vous pouvez facilement crer vos propres configurations (la commande \dF de psql affiche toutes les configurations disponibles).
Lors de l'installation, une configuration approprie est slectionne et default_text_search_config est configur dans postgresql.conf pour qu'elle soit utilise par dfaut. Si vous utilisez la mme configuration de recherche plein texte pour le cluster entier, vous pouvez utiliser la valeur de postgresql.conf. Pour utiliser diffrentes configurations dans le cluster mais avec la
mme configuration pour une base, utilisez ALTER DATABASE ... SET. Sinon, vous pouvez configurer default_text_search_config dans chaque session.
Chaque fonction de recherche plein texte qui dpend d'une configuration a un argument regconfig en option, pour que la configuration utilise puisse tre prcise explicitement. default_text_search_config est seulement utilis quand cet argument
est omis.
Pour rendre plus facile la construction de configurations de recherche plein texte, une configuration est construite partir d'objets
de la base de donnes. La recherche plein texte de PostgreSQL fournit quatre types d'objets relatifs la configuration :

Les analyseurs de recherche plein texte cassent les documents en jetons et classifient chaque jeton (par exemple, un mot ou un
nombre).
Les dictionnaires de recherche plein texte convertissent les jetons en une forme normalise et rejettent les termes courants.
Les modles de recherche plein texte fournissent les fonctions ncessaires aux dictionnaires. (Un dictionnaire spcifie uniquement un modle et un ensemble de paramtres pour ce modle.)
Les configurations de recherche plein texte slectionnent un analyseur et un ensemble de dictionnaires utiliser pour normaliser les jetons produit par l'analyseur.

Les analyseurs de recherche plein texte et les modles sont construits partir de fonctions bas niveau crites en C ; du coup, le dveloppement de nouveaux analyseurs ou modles ncessite des connaissances en langage C, et les droits superutilisateur pour les
installer dans une base de donnes. (Il y a des exemples d'analyseurs et de modles en addon dans la partie contrib/ de la distribution PostgreSQL.) Comme les dictionnaires et les configurations utilisent des paramtres et se connectent aux analyseurs et
modles, aucun droit spcial n'est ncessaire pour crer un nouveau dictionnaire ou une nouvelle configuration. Les exemples de
cration de dictionnaires et de configurations personnaliss seront prsents plus tard dans ce chapitre.

12.2. Tables et index


Les exemples de la section prcdente illustrent la correspondance plein texte en utilisant des chanes simples. Cette section
montre comment rechercher les donnes de la table, parfois en utilisant des index.

12.2.1. Rechercher dans une table


233

Recherche plein texte

Il est possible de faire des recherches plein texte sans index. Une requte qui ne fait qu'afficher le champ title de chaque ligne
contenant le mot friend dans son champ body ressemble ceci :
SELECT title
FROM pgweb
WHERE to_tsvector('english', body) @@ to_tsquery('english', 'friend');
Ceci trouve aussi les mots relatifs comme friends et friendly car ils ont tous la mme racine, le mme lexeme normalis.
La requte ci-dessus spcifie que la configuration english doit tre utilise pour analyser et normaliser les chanes. Nous pouvons aussi omettre les paramtres de configuration :
SELECT title
FROM pgweb
WHERE to_tsvector(body) @@ to_tsquery('friend');
Cette requte utilisera l'ensemble de configuration indiqu par default_text_search_config.
Un exemple plus complexe est de slectionner les dix documents les plus rcents qui contiennent les mots create et table
dans les champs title ou body :
SELECT title
FROM pgweb
WHERE to_tsvector(title || ' ' || body) @@ to_tsquery('create & table')
ORDER BY last_mod_date DESC LIMIT 10;
Pour plus de claret, nous omettons les appels la fonction coalesce qui est ncessaire pour rechercher les lignes contenant
NULL dans un des deux champs.
Bien que ces requtes fonctionnent sans index, la plupart des applications trouvent cette approche trop lente, sauf peut-tre pour
des recherches occasionnelles. Une utilisation pratique de la recherche plein texte rclame habituellement la cration d'un index.

12.2.2. Crer des index


Nous pouvons crer un index GIN (Section 12.9, Types d'index GiST et GIN ) pour acclrer les recherches plein texte :
CREATE INDEX pgweb_idx ON pgweb USING gin(to_tsvector('english', body));
Notez que la version deux arguments de to_tsvector est utilise. Seules les fonctions de recherche plein texte qui spcifient
un nom de configuration peuvent tre utilises dans les index sur des expressions (Section 11.7, Index d'expressions ). Ceci est
d au fait que le contenu de l'index ne doit pas tre affect par default_text_search_config. Dans le cas contraire, le contenu de
l'index peut devenir incohrent parce que diffrentes entres pourraient contenir des tsvector crs avec diffrentes configurations
de recherche plein texte et qu'il ne serait plus possible de deviner quelle configuration fait rfrence une entre. Il serait impossible de sauvegarder et restaurer correctement un tel index.
Comme la version deux arguments de to_tsvector a t utilise dans l'index ci-dessus, seule une rfrence de la requte qui
utilise la version deux arguments de to_tsvector avec le mme nom de configuration utilise cet index. C'est--dire que
WHERE to_tsvector('english', body) @@ 'a & b' peut utiliser l'index, mais WHERE to_tsvector(body)
@@ 'a & b' ne le peut pas. Ceci nous assure qu'un index est seulement utilis avec la mme configuration que celle utilise
pour crer les entres de l'index.
Il est possible de configurer des index avec des expressions plus complexes o le nom de la configuration est indiqu dans une
autre colonne. Par exemple :
CREATE INDEX pgweb_idx ON pgweb USING gin(to_tsvector(config_name, body));
o config_name est une colonne de la table pgweb. Ceci permet l'utilisation de configuration mixe dans le mme index tout en
enregistrant la configuration utilise pour chaque entre d'index. Ceci est utile dans le cas d'une bibliothque de documents dans
diffrentes langues. Encore une fois, les requtes voulant utiliser l'index doivent tre crites pour correspondre l'index, donc
WHERE to_tsvector(config_name, body) @@ 'a & b'.
Les index peuvent mme concatner des colonnes :
CREATE INDEX pgweb_idx ON pgweb USING gin(to_tsvector('english', title || ' ' ||
body));

234

Recherche plein texte

Une autre approche revient crer une colonne tsvector spare pour contenir le rsultat de to_tsvector. Cet exemple est une
concatnation de title et body, en utilisant coalesce pour s'assurer qu'un champ est toujours index mme si l'autre vaut
NULL :
ALTER TABLE pgweb ADD COLUMN textsearchable_index_col tsvector;
UPDATE pgweb SET textsearchable_index_col =
to_tsvector('english', coalesce(title,'') || ' ' || coalesce(body,''));
Puis nous crons un index GIN pour acclrer la recherche :
CREATE INDEX textsearch_idx ON pgweb USING gin(textsearchable_index_col);
Maintenant, nous sommes prt pour des recherches plein texte rapides :
SELECT title
FROM pgweb
WHERE textsearchable_index_col @@ to_tsquery('create & table')
ORDER BY last_mod_date DESC
LIMIT 10;
Lors de l'utilisation d'une colonne spare pour stocker la reprsentation tsvector, il est ncessaire d'ajouter un trigger pour obtenir
une colonne tsvector jour tout moment suivant les modifications de title et body. La Section 12.4.3, Triggers pour les
mises jour automatiques explique comment le faire.
Un avantage de l'approche de la colonne spare sur un index par expression est qu'il n'est pas ncessaire de spcifier explicitement la configuration de recherche plein texte dans les requtes pour utiliser l'index. Comme indiqu dans l'exemple ci-dessus, la
requte peut dpendre de default_text_search_config. Un autre avantage est que les recherches seront plus rapides car
il n'est plus ncessaire de refaire des appels to_tsvector pour vrifier la correspondance de l'index. (Ceci est plus important
lors de l'utilisation d'un index GiST par rapport un index GIN ; voir la Section 12.9, Types d'index GiST et GIN .) Nanmoins, l'approche de l'index par expression est plus simple configurer et elle rclame moins d'espace disque car la reprsentation
tsvector n'est pas rellement stocke.

12.3. Contrler la recherche plein texte


Pour implmenter la recherche plein texte, une fonction doit permettre la cration d'un tsvector partir d'un document et la cration d'un tsquery partir de la requte d'un utilisateur. De plus, nous avons besoin de renvoyer les rsultats dans un ordre utile,
donc nous avons besoin d'une fonction de comparaison des documents suivant leur adquation la recherche. Il est aussi important de pouvoir afficher joliment les rsultats. PostgreSQL fournit un support pour toutes ces fonctions.

12.3.1. Analyser des documents


PostgreSQL fournit la fonction to_tsvector pour convertir un document vers le type de donnes tsvector.
to_tsvector([ config regconfig, ] document text) returns tsvector
to_tsvector analyse un document texte et le convertit en jetons, rduit les jetons en des lexemes et renvoie un tsvector qui
liste les lexemes avec leur position dans le document. Ce dernier est trait suivant la configuration de recherche plein texte spcifie ou celle par dfaut. Voici un exemple simple :
SELECT to_tsvector('english', 'a fat cat sat on a mat - it ate a fat rats');
to_tsvector
----------------------------------------------------'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4
Dans l'exemple ci-dessus, nous voyons que le tsvector rsultant ne contient pas les mots a, on et it, le mot rats est devenu rat
et le signe de ponctuation - a t ignor.
En interne, la fonction to_tsvector appelle un analyseur qui casse le texte en jetons et affecte un type chaque jeton. Pour
chaque jeton, une liste de dictionnaires (Section 12.6, Dictionnaires ) est consulte, liste pouvant varier suivant le type de jeton.
Le premier dictionnaire qui reconnat le jeton met un ou plusieurs lexemes pour reprsenter le jeton. Par exemple, rats devient
rat car un des dictionnaires sait que le mot rats est la forme pluriel de rat. Certains mots sont reconnus comme des termes
courants (Section 12.6.1, Termes courants ), ce qui fait qu'ils sont ignors car ils surviennent trop frquemment pour tre utile
235

Recherche plein texte

dans une recherche. Dans notre exemple, il s'agissait de a, on et it. Si aucun dictionnaire de la liste ne reconnat le jeton, il est
aussi ignor. Dans cet exemple, il s'agit du signe de ponctuation - car il n'existe aucun dictionnaire affect ce type de jeton
(Space symbols), ce qui signifie que les jetons espace ne seront jamais indexs. Le choix de l'analyseur, des dictionnaires et
des types de jetons indexer est dtermin par la configuration de recherche plein texte slectionn (Section 12.7, Exemple de
configuration ). Il est possible d'avoir plusieurs configurations pour la mme base, et des configurations prdfinies sont disponibles pour diffrentes langues. Dans notre exemple, nous avons utilis la configuration par dfaut, savoir english pour
l'anglais.
La fonction setweight peut tre utilis pour ajouter un label aux entres d'un tsvector avec un poids donn. Ce poids consiste
en une lettre : A, B, C ou D. Elle est utilise typiquement pour marquer les entres provenant de diffrentes parties d'un document,
comme le titre et le corps. Plus tard, cette information peut tre utilise pour modifier le score des rsultats.
Comme to_tsvector(NULL) renvoie NULL, il est recommand d'utiliser coalesce quand un champ peut tre NULL. Voici
la mthode recommande pour crer un tsvector partir d'un document structur :
UPDATE tt SET ti =
setweight(to_tsvector(coalesce(title,'')), 'A')
||
setweight(to_tsvector(coalesce(keyword,'')), 'B') ||
setweight(to_tsvector(coalesce(abstract,'')), 'C') ||
setweight(to_tsvector(coalesce(body,'')), 'D');
Ici nous avons utilis setweight pour ajouter un label au source de chaque lexeme dans le tsvector final, puis assembl les valeurs tsvector en utilisant l'oprateur de concatnation des tsvector, ||. (La Section 12.4.1, Manipuler des documents donne
des dtails sur ces oprations.)

12.3.2. Analyser des requtes


PostgreSQL fournit les fonctions to_tsquery et plainto_tsquery pour convertir une requte dans le type de donnes
tsquery. to_tsquery offre un accs d'autres fonctionnalits que plainto_tsquery mais est moins indulgent sur ses arguments.
to_tsquery([ config regconfig, ] querytext text) returns tsquery
to_tsquery cre une valeur tsquery partir de querytext qui doit contenir un ensemble de jetons individuels spars par les
oprateurs boolens & (AND), | (OR) et ! (NOT). Ces oprateurs peuvent tre groups en utilisant des parenthses. En d'autres
termes, les arguments de to_tsquery doivent dj suivre les rgles gnrales pour un tsquery comme dcrit dans la Section 8.11, Types de recherche plein texte . La diffrence est que, alors qu'un tsquery basique prend les jetons bruts,
to_tsquery normalise chaque jeton en un lexeme en utilisant la configuration spcifie ou par dfaut, et annule tout jeton qui
est un terme courant d'aprs la configuration. Par exemple :
SELECT to_tsquery('english', 'The & Fat & Rats');
to_tsquery
--------------'fat' & 'rat'
Comme une entre tsquery basique, des poids peuvent tre attachs chaque lexeme restreindre pour tablir une correspondance
avec seulement des lexemes tsvector de ces poids. Par exemple :
SELECT to_tsquery('english', 'Fat | Rats:AB');
to_tsquery
-----------------'fat' | 'rat':AB
De plus, * peut tre attach un lexeme pour demander la correspondance d'un prfixe :
SELECT to_tsquery('supern:*A & star:A*B');
to_tsquery
-------------------------'supern':*A & 'star':*AB
Un tel lexeme correspondra tout mot dans un tsvector qui commence par la chane indique.
to_tsquery peut aussi accepter des phrases avec des guillemets simples. C'est utile quand la configuration inclut un dictionnaire thsaurus qui peut se dclencher sur de telles phrases. Dans l'exemple ci-dessous, un thsaurus contient la rgle supernovae stars : sn :
236

Recherche plein texte

SELECT to_tsquery('''supernovae stars'' & !crab');


to_tsquery
--------------'sn' & !'crab'
sans guillemets, to_tsquery gnre une erreur de syntaxe pour les jetons qui ne sont pas spars par un oprateur AND ou OR.
plainto_tsquery([ config regconfig, ] querytext text) returns tsquery
plainto_tsquery transforme le texte non format querytext en tsquery. Le texte est analys et normalis un peu comme
pour to_tsvector, ensuite l'oprateur boolen & (AND) est insr entre les mots restants.
Exemple :
SELECT plainto_tsquery('english', 'The Fat Rats');
plainto_tsquery
----------------'fat' & 'rat'
Notez que plainto_tsquery ne peut pas reconnatre un oprateur boolen, des labels de poids en entre ou des labels de correspondance de prfixe :
SELECT plainto_tsquery('english', 'The Fat & Rats:C');
plainto_tsquery
--------------------'fat' & 'rat' & 'c'
Ici, tous les symboles de ponctuation ont t annuls car ce sont des symboles espace.

12.3.3. Ajouter un score aux rsultats d'une recherche


Les tentatives de score pour mesurer l'adquation des documents se font par rapport une certaine requte. Donc, quand il y a
beaucoup de correspondances, les meilleurs doivent tre montrs en premier. PostgreSQL fournit deux fonctions prdfinies de
score, prennant en compte l'information lexicale, la proximit et la structure ; en fait, elles considrent le nombre de fois o les
termes de la requte apparaissent dans le document, la proximit des termes de la recherche avec ceux de la requte et l'importance
du passage du document o se trouvent les termes du document. Nanmoins, le concept d'adquation pourrait demander plus
d'informations pour calculer le score, par exemple la date et l'heure de modification du document. Les fonctions internes de calcul
de score sont seulement des exemples. Vous pouvez crire vos propres fonctions de score et/ou combiner leur rsultats avec des
facteurs supplmentaires pour remplir un besoin spcifique.
Les deux fonctions de score actuellement disponibles sont :

ts_rank([ weights float4[], ] vector tsvector,


query tsquery [, normalization integer ]) returns float4
Calcule un score sur les vecteurs en se basant sur la frquence des lexemes correspondants la recherche.
ts_rank_cd([ weights float4[], ] vector tsvector, query tsquery [,
normalization integer ]) returns float4
Cette fonction calcule le score de la densit de couverture pour le vecteur du document et la requte donns, comme dcrit
dans l'article de Clarke, Cormack et Tudhope, Relevance Ranking for One to Three Term Queries , article paru dans le
journal Information Processing and Management en 1999.
Cette fonction ncessite des informations de position. Du coup, elle ne fonctionne pas sur des valeurs tsvector strippes -elle renvoie toujours zro.
Pour ces deux fonctions, l'argument optionnel des poids offre la possibilit d'impacter certains mots plus ou moins suivant la
faon dont ils sont marqus. Le tableau de poids indique quel point chaque catgorie de mots est marque. Dans l'ordre :

237

Recherche plein texte

{poids-D, poids-C, poids-B, poids-A}


Si aucun poids n'est fourni, alors ces valeurs par dfaut sont utilises :
{0.1, 0.2, 0.4, 1.0}
Typiquement, les poids sont utiliss pour marquer les mots compris dans des aires spciales du document, comme le titre ou le rsum initial, pour qu'ils puissent tre traits avec plus ou moins d'importance que les mots dans le corps du document.
Comme un document plus long a plus de chance de contenir un terme de la requte, il est raisonnable de prendre en compte la
taille du document, par exemple un document de cent mots contenant cinq fois un mot de la requte est probablement plus intressant qu'un document de mille mots contenant lui-aussi cinq fois un mot de la requte. Les deux fonctions de score prennent une
option normalization, de type integer, qui prcise si la longueur du document doit impacter son score. L'option contrle plusieurs comportements, donc il s'agit d'un masque de bits : vous pouvez spcifier un ou plusieurs comportements en utilisant | (par
exemple, 2|4).

0 (valeur par dfaut) ignore la longueur du document


1 divise le score par 1 + le logarithme de la longueur du document
2 divise le score par la longueur du document
4 divise le score par "mean harmonic distance between extents" (ceci est implment seulement par ts_rank_cd)
8 divise le score par le nombre de mots uniques dans le document
16 divise le score par 1 + le logarithme du nombre de mots uniques dans le document
32 divise le score par lui-mme + 1

Si plus d'un bit de drapeau est indiqu, les transformations sont appliques dans l'ordre indiqu.
Il est important de noter que les fonctions de score n'utilisent aucune information globale donc il est impossible de produire une
normalisation de 1% ou 100%, comme c'est parfois demand. L'option de normalisation 32 (score/(score+1)) peut
s'appliquer pour chelonner tous les scores dans une chelle de zro un mais, bien sr, c'est une petite modification cosmtique,
donc l'ordre des rsultats ne changera pas.
Voici un exemple qui slectionne seulement les dix correspondances de meilleur score :
SELECT title, ts_rank_cd(textsearch, query) AS rank
FROM apod, to_tsquery('neutrino|(dark & matter)') query
WHERE query @@ textsearch
ORDER BY rank DESC
LIMIT 10;
title
|
rank
-----------------------------------------------+---------Neutrinos in the Sun
|
3.1
The Sudbury Neutrino Detector
|
2.4
A MACHO View of Galactic Dark Matter
| 2.01317
Hot Gas and Dark Matter
| 1.91171
The Virgo Cluster: Hot Plasma and Dark Matter | 1.90953
Rafting for Solar Neutrinos
|
1.9
NGC 4650A: Strange Galaxy and Dark Matter
| 1.85774
Hot Gas and Dark Matter
|
1.6123
Ice Fishing for Cosmic Neutrinos
|
1.6
Weak Lensing Distorts the Universe
| 0.818218
Voici le mme exemple en utilisant un score normalis :
SELECT title, ts_rank_cd(textsearch, query, 32 /* rank/(rank+1) */ ) AS rank
FROM apod, to_tsquery('neutrino|(dark & matter)') query
WHERE query @@ textsearch
ORDER BY rank DESC
LIMIT 10;
title
|
rank
-----------------------------------------------+------------------Neutrinos in the Sun
| 0.756097569485493
The Sudbury Neutrino Detector
| 0.705882361190954
A MACHO View of Galactic Dark Matter
| 0.668123210574724
Hot Gas and Dark Matter
| 0.65655958650282
The Virgo Cluster: Hot Plasma and Dark Matter | 0.656301290640973
Rafting for Solar Neutrinos
| 0.655172410958162
NGC 4650A: Strange Galaxy and Dark Matter
| 0.650072921219637
Hot Gas and Dark Matter
| 0.617195790024749
238

Recherche plein texte

Ice Fishing for Cosmic Neutrinos


Weak Lensing Distorts the Universe

| 0.615384618911517
| 0.450010798361481

Le calcul du score peut consommer beaucoup de ressources car il demande de consulter le tsvector de chaque document correspondant, ce qui est trs consommateur en entres/sorties et du coup lent. Malheureusement, c'est presque impossible viter car
les requtes intressantes ont un grand nombre de correspondances.

12.3.4. Surligner les rsultats


Pour prsenter les rsultats d'une recherche, il est prfrable d'afficher une partie de chaque document et en quoi cette partie
concerne la requte. Habituellement, les moteurs de recherche affichent des fragments du document avec des marques pour les
termes recherchs. PostgreSQL fournit une fonction ts_headline qui implmente cette fonctionnalit.
ts_headline([ config regconfig, ] document text, query tsquery [, options text ])
returns text
ts_headline accepte un document avec une requte et renvoie un rsum du document. Les termes de la requte sont surligns
dans les extractions. La configuration utiliser pour analyser le document peut tre prcise par config ; si config est omis, le
paramtre default_text_search_config est utilis.
Si une chane options est spcifie, elle doit consister en une liste de une ou plusieurs paires option=valeur spares par
des virgules. Les options disponibles sont :

StartSel, StopSel : les chanes qui permettent de dlimiter les mots de la requte parmi le reste des mots. Vous devez
mettre ces chanes entre guillemets doubles si elles contiennent des espaces ou des virgules.
MaxWords, MinWords : ces nombres dterminent les limites minimum et maximum des rsums afficher.
ShortWord : les mots de cette longueur et les mots plus petits seront supprims au dbut et la fin d'un rsum. La valeur
par dfaut est de trois pour liminer les articles anglais communs.
HighlightAll : boolen ; si true, le document complet sera utilis pour le surlignage, en ignorant les trois paramtres
prcdents.
MaxFragments : nombre maximum d'extraits ou de fragments de texte afficher. La valeur par dfaut, 0, slectionne une
mthode de gnration d'extraits qui n'utilise pas les fragments. Une valeur positive et non nulle slectionne la gnration
d'extraits base sur les fragments. Cette mthode trouve les fragments de texte avec autant de mots de la requte que possible
et restreint ces fragments autour des mots de la requte. Du coup, les mots de la requte se trouvent au milieu de chaque fragment et ont des mots de chaque ct. Chaque fragment sera au plus de MaxWords et les mots auront une longueur maximum
de ShortWord. Si tous les mots de la requte ne sont pas trouvs dans le document, alors un seul fragment de MinWords
sera affich.
FragmentDelimiter : quand plus d'un fragment est affich, alors les fragments seront spars par ce dlimiteur.

Toute option omise recevra une valeur par dfaut :


StartSel=<b>, StopSel=</b>,
MaxWords=35, MinWords=15, ShortWord=3, HighlightAll=FALSE,
MaxFragments=0, FragmentDelimiter=" ... "
Par exemple :
SELECT ts_headline('english',
'The most common type of search
is to find all documents containing given query terms
and return them in order of their similarity to the
query.',
to_tsquery('query & similarity'));
ts_headline
-----------------------------------------------------------containing given <b>query</b> terms
and return them in order of their <b>similarity</b> to the
<b>query</b>.
SELECT ts_headline('english',
'The most common type of search
is to find all documents containing given query terms
and return them in order of their similarity to the
query.',
239

Recherche plein texte

to_tsquery('query & similarity'),


'StartSel = <, StopSel = >');
ts_headline
------------------------------------------------------containing given <query> terms
and return them in order of their <similarity> to the
<query>.
ts_headline utilise le document original, pas un rsum tsvector, donc elle peut tre lente et doit tre utilise avec parcimonie
et attention. Une erreur typique est d'appeler ts_headline pour chaque document correspondant quand seuls dix documents
sont afficher. Les sous-requtes SQL peuvent aider ; voici un exemple :
SELECT id, ts_headline(body, q), rank
FROM (SELECT id, body, q, ts_rank_cd(ti, q) AS rank
FROM apod, to_tsquery('stars') q
WHERE ti @@ q
ORDER BY rank DESC
LIMIT 10) AS foo;

12.4. Fonctionnalits supplmentaires


Cette section dcrit des fonctions et oprateurs supplmentaires qui sont utiles en relation avec la recherche plein texte.

12.4.1. Manipuler des documents


La Section 12.3.1, Analyser des documents a montr comment des documents en texte brut peuvent tre convertis en valeurs
tsvector. PostgreSQL fournit aussi des fonctions et des oprateurs pouvant tre utiliss pour manipuler des documents qui sont
dj au format tsvector.

tsvector || tsvector
L'oprateur de concatnation tsvector renvoie un vecteur qui combine les lexemes et des informations de position pour les
deux vecteurs donns en argument. Les positions et les labels de poids sont conservs lors de la concatnation. Les positions
apparaissant dans le vecteur droit sont dcals par la position la plus large mentionne dans le vecteur gauche, pour que le rsultat soit pratiquement quivalent au rsultat du traitement de to_tsvector sur la concatnation des deux documents originaux. (L'quivalence n'est pas exacte car tout terme courant supprim de la fin de l'argument gauche n'affectera pas le rsultat alors qu'ils auraient affect les positions des lexemes dans l'argument droit si la concatnation de texte avait t utilise.)
Un avantage de l'utilisation de la concatnation au format vecteur, plutt que la concatnation de texte avant d'appliquer
to_tsvector, est que vous pouvez utiliser diffrentes configurations pour analyser les diffrentes sections du document.
De plus, comme la fonction setweight marque tous les lexemes du secteur donn de la mme faon, il est ncessaire
d'analyser le texte et de lancer setweight avant la concatnation si vous voulez des labels de poids diffrents sur les diffrentes parties du document.
setweight(vector tsvector, weight "char") returns tsvector
Cette fonction renvoie une copie du vecteur en entre pour chaque position de poids weight, soit A, soit B, soit C soit D. (D
est la valeur par dfaut pour les nouveaux vecteurs et, du coup, n'est pas affich en sortie.) Ces labels sont conservs quand les
vecteurs sont concatns, permettant aux mots des diffrentes parties d'un document de se voir attribuer un poids diffrent par
les fonctions de score.
Notez que les labels de poids s'appliquent seulement aux positions, pas aux lexemes. Si le vecteur en entre se voit supprimer
les positions, alors setweight ne pourra rien faire.
length(vector tsvector) returns integer
Renvoie le nombre de lexemes enregistrs dans le vecteur.

240

Recherche plein texte

strip(vector tsvector) returns tsvector


Renvoie un vecteur qui liste les mmes lexemes que le vecteur donn mais il manquera les informations de position et de
poids. Alors que le vecteur renvoy est bien moins utile qu'un vecteur normal pour calculer le score, il est habituellement bien
plus petit.

12.4.2. Manipuler des requtes


La Section 12.3.2, Analyser des requtes a montr comment des requtes texte peuvent tre converties en valeurs de type tsquery. PostgreSQL fournit aussi des fonctions et des oprateurs pouvant tre utiliss pour manipuler des requtes qui sont dj
de la forme tsquery.

tsquery && tsquery


Renvoie une combinaison AND des deux requtes donnes.
tsquery || tsquery
Renvoie une combinaison OR des deux requtes donnes.
!! tsquery
Renvoie la ngation (NOT) de la requte donne.
numnode(query tsquery) returns integer
Renvoie le nombre de nuds (lexemes et oprateurs) dans un tsquery. Cette fonction est utile pour dterminer si la requte
(query) a un sens (auquel cas elle renvoie > 0) ou s'il ne contient que des termes courants (auquel cas elle renvoie 0).
Exemples :
SELECT numnode(plainto_tsquery('the any'));
NOTICE: query contains only stopword(s) or doesn't contain lexeme(s), ignored
numnode
--------0
SELECT numnode('foo & bar'::tsquery);
numnode
--------3

querytree(query tsquery) returns text


Renvoie la portion d'un tsquery qui peut tre utilis pour rechercher dans un index.Cette fonction est utile pour dtecter les requtes qui ne peuvent pas utiliser un index, par exemple celles qui contiennent des termes courants ou seulement des ngations de termes. Par exemple :
SELECT querytree(to_tsquery('!defined'));
querytree
-----------

12.4.2.1. R-criture des requtes


241

Recherche plein texte

La famille de fonctions ts_rewrite cherche dans un tsquery donn les occurrences d'une sous-requte cible et remplace chaque
occurrence avec une autre sous-requte de substitution. En fait, cette opration est une version spcifique tsquery d'un remplacement de sous-chane. Une combinaison cible et substitut peut tre vu comme une rgle de r-criture de la requte. Un ensemble
de rgles de r-criture peut tre une aide puissante la recherche. Par exemple, vous pouvez tendre la recherche en utilisant des
synonymes (new york, big apple, nyc, gotham) ou restreindre la recherche pour diriger l'utilisateur vers des thmes en
vogue. Cette fonctionnalit n'est pas sans rapport avec les thsaurus (Section 12.6.4, Dictionnaire thsaurus ). Nanmoins, vous
pouvez modifier un ensemble de rgles de r-criture directement, sans r-indexer, alors que la mise jour d'un thsaurus ncessite un r-indexage pour tre pris en compte.

ts_rewrite (query tsquery, target tsquery, substitute tsquery) returns tsquery


Cette forme de ts_rewrite applique simplement une seule rgle de r-criture : target est remplac par substitute
partout o il apparat dans query. Par exemple :
SELECT ts_rewrite('a & b'::tsquery, 'a'::tsquery, 'c'::tsquery);
ts_rewrite
-----------'b' & 'c'

ts_rewrite (query tsquery, select text) returns tsquery


Cette forme de ts_rewrite accepte une query de dbut et une commande SQL select, qui est fournie comme une
chane de caractres. select doit renvoyer deux colonnes de type tsquery. Pour chaque ligne de rsultats du select, les
occurrences de la valeur de la premire colonne (la cible) sont remplaces par la valeur de la deuxime colonne (le substitut)
dans la valeur actuelle de query. Par exemple :
CREATE TABLE aliases (t tsquery PRIMARY KEY, s tsquery);
INSERT INTO aliases VALUES('a', 'c');
SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases');
ts_rewrite
-----------'b' & 'c'
Notez que, quand plusieurs rgles de r-criture sont appliques de cette faon, l'ordre d'application peut tre important ;
donc, en pratique, vous voudrez que la requte source utilise ORDER BY avec un ordre prcis.
Considrons un exemple rel pour l'astronomie. Nous tendons la requte supernovae en utilisant les rgles de r-criture par
la table :
CREATE TABLE aliases (t tsquery primary key, s tsquery);
INSERT INTO aliases VALUES(to_tsquery('supernovae'), to_tsquery('supernovae|sn'));
SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT * FROM aliases');
ts_rewrite
--------------------------------'crab' & ( 'supernova' | 'sn' )
Nous pouvons modifier les rgles de r-criture simplement en mettant jour la table :
UPDATE aliases SET s = to_tsquery('supernovae|sn & !nebulae') WHERE t =
to_tsquery('supernovae');
SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT * FROM aliases');
ts_rewrite
--------------------------------------------'crab' & ( 'supernova' | 'sn' & !'nebula' )
La r-criture peut tre lente quand il y a beaucoup de rgles de r-criture car elle vrifie l'intrt de chaque rgle. Pour filtrer les
rgles qui ne sont pas candidates de faon vidente, nous pouvons utiliser les oprateurs de contenant pour le type tsquery. Dans
242

Recherche plein texte

l'exemple ci-dessous, nous slectionnons seulement les rgles qui peuvent correspondre avec la requte originale :
SELECT ts_rewrite('a & b'::tsquery,
'SELECT t,s FROM aliases WHERE ''a & b''::tsquery @> t');
ts_rewrite
-----------'b' & 'c'

12.4.3. Triggers pour les mises jour automatiques


Lors de l'utilisation d'une colonne spare pour stocker la reprsentation tsvector de vos documents, il est ncessaire de crer un
trigger pour mettre jour la colonne tsvector quand le contenu des colonnes document change. Deux fonctions trigger intgres
sont disponibles pour cela, mais vous pouvez aussi crire la vtre.
tsvector_update_trigger(tsvector_column_name, config_name, text_column_name [, ...
])
tsvector_update_trigger_column(tsvector_column_name, config_column_name,
text_column_name [, ... ])
Ces fonctions trigger calculent automatiquement une colonne tsvector partir d'une ou plusieurs colonnes texte sous le contrle
des paramtres spcifis dans la commande CREATE TRIGGER. Voici un exemple de leur utilisation :
CREATE TABLE messages (
title
text,
body
text,
tsv
tsvector
);
CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
ON messages FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(tsv, 'pg_catalog.english', title, body);
INSERT INTO messages VALUES('title here', 'the body text is here');
SELECT * FROM messages;
title
|
body
|
tsv
------------+-----------------------+---------------------------title here | the body text is here | 'bodi':4 'text':5 'titl':1
SELECT title, body FROM messages WHERE tsv @@ to_tsquery('title & body');
title
|
body
------------+----------------------title here | the body text is here
Aprs avoir cr ce trigger, toute modification dans title ou body sera automatiquement reflte dans tsv, sans que
l'application n'ait s'en soucier.
Le premier argument du trigger doit tre le nom de la colonne tsvector mettre jour. Le second argument spcifie la configuration de recherche plein texte utiliser pour raliser la conversion. Pour tsvector_update_trigger, le nom de la configuration est donn en deuxime argument du trigger. Il doit tre qualifi du nom du schma comme indiqu ci-dessus pour que le comportement du trigger ne change pas avec les modifications de search_path. Pour tsvector_update_trigger_column,
le deuxime argument du trigger est le nom d'une autre colonne de table qui doit tre du type regconfig. Ceci permet une slection
par ligne de la configuration faire. Les arguments restant sont les noms des colonnes texte (de type text, varchar ou char). Elles
sont inclus dans le document suivant l'ordre donn. Les valeurs NULL sont ignores (mais les autres colonnes sont toujours indexes).
Une limitation des triggers internes est qu'ils traitent les colonnes de faon identique. Pour traiter les colonnes diffremment -- par
exemple pour donner un poids plus important au titre qu'au corps -- il est ncessaire d'crire un trigger personnalis. Voici un
exemple utilisant PL/pgSQL comme langage du trigger :
CREATE FUNCTION messages_trigger() RETURNS trigger AS $$
begin
new.tsv :=
setweight(to_tsvector('pg_catalog.english', coalesce(new.title,'')), 'A') ||
243

Recherche plein texte

setweight(to_tsvector('pg_catalog.english', coalesce(new.body,'')), 'D');


return new;
end
$$ LANGUAGE plpgsql;
CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
ON messages FOR EACH ROW EXECUTE PROCEDURE messages_trigger();
Gardez en tte qu'il est important de spcifier explicitement le nom de la configuration lors de la cration de valeurs tsvector dans
des triggers, pour que le contenu de la colonne ne soit pas affect par des modifications de default_text_search_config.
Dans le cas contraire, des problmes surviendront comme des rsultats de recherche changeant aprs une sauvegarde/restauration.

12.4.4. Rcuprer des statistiques sur les documents


La fonction ts_stat est utile pour vrifier votre configuration et pour trouver des candidats pour les termes courants.
ts_stat(sqlquery text, [ weights text, ]
OUT word text, OUT ndoc integer,
OUT nentry integer) returns setof record
sqlquery est une valeur de type texte contenant une requte SQL qui doit renvoyer une seule colonne tsvector. ts_stat excute la requte et renvoie des statistiques sur chaque lexeme (mot) contenu dans les donnes tsvector. Les colonnes renvoyes
sont :

word text -- la valeur d'un lexeme


ndoc integer -- le nombre de documents (tsvector) o le mot se trouve
nentry integer -- le nombre total d'occurrences du mot

Si weights est prcis, seules les occurrences d'un de ces poids sont comptabilises.
Par exemple, pour trouver les dix mots les plus frquents dans un ensemble de document :
SELECT * FROM ts_stat('SELECT vector FROM apod')
ORDER BY nentry DESC, ndoc DESC, word
LIMIT 10;
De la mme faon, mais en ne comptant que les occurrences de poids A ou B :
SELECT * FROM ts_stat('SELECT vector FROM apod', 'ab')
ORDER BY nentry DESC, ndoc DESC, word
LIMIT 10;

12.5. Analyseurs
Les analyseurs de recherche plein texte sont responsable du dcoupage d'un document brut en jetons et d'identifier le type des jetons. L'ensemble des types possibles est dfini par l'analyseur lui-mme. Notez qu'un analyseur ne modifie pas le texte -- il identifie les limites plausibles des mots. Comme son domaine est limit, il est moins important de pouvoir construire des analyseurs personnaliss pour une application. Actuellement, PostgreSQL fournit un seul analyseur interne qui s'est rvl utile pour un ensemble vari d'applications.
L'analyseur interne est nomm pg_catalog.default. Il reconnait 23 types de jeton, dont la liste est disponible dans Tableau 12.1, Types de jeton de l'analyseur par dfaut .
Tableau 12.1. Types de jeton de l'analyseur par dfaut

Alias

Description

Exemple

asciiword

Mot, toute lettre ASCII

elephant

word

Mot, toute lettre

maana

numword

Mot, lettres et chiffres

beta1

asciihword

Mot compos, en ASCII

up-to-date

hword

Mot compos, toutes les lettres

lgico-matemtica

244

Recherche plein texte

Alias

Description

Exemple

numhword

Mot compos, lettre et chiffre

postgresql-beta1

hword_asciipart

Partie d'un mot compos, en ASCII

postgresql dans le contexte postgresql-beta1

hword_part

Partie d'un mot compos, toutes les lettres lgico ou matemtica dans le
contexte lgico-matemtica

hword_numpart

Partie d'un mot compos, lettres et beta1 dans le contexte postgresql-bechiffres


ta1

email

Adresse email

foo@example.com

protocol

En-tte de protocole

http://

url

URL

example.com/stuff/index.html

host

Hte

example.com

url_path

Chemin URL

/stuff/index.html,
contexte d'une URL

file

Fichier ou chemin

/usr/local/foo.txt, en dehors du
contexte d'une URL

sfloat

Notation scientifique

-1.234e56

float

Notation dcimale

-1.234

int

Entier sign

-1234

uint

Entier non sign

1234

version

Numro de version

8.3.0

tag

Balise XML

<a href="dictionaries.html">

entity

Entit XML

&amp;

blank

Symboles espaces

(tout espace blanc, ou signe de ponctuation non reconnu autrement)

dans

le

Note
La notion de l'analyseur d'une lettre est dtermine par la configuration de la locale sur la base de donnes, spcifiquement par lc_ctype. Les mots contenant seulement des lettres ASCII basiques sont reports comme un
type de jeton spar car il est parfois utile de les distinguer. Dans la plupart des langues europennes, les types de
jeton word et asciiword doivent toujours tre traits de la mme faon.
email ne supporte pas tous les caractres email valides tels qu'ils sont dfinis par la RFC 5322. Spcifiquement, les seuls caractres non-alphanumriques supports sont le point, le tiret et le tiret bas.
Il est possible que l'analyseur produise des jetons qui concident partir du mme texte. Comme exemple, un mot compos peut
tre report la fois comme un mot entier et pour chaque composante :
SELECT alias, description, token FROM ts_debug('foo-bar-beta1');
alias
|
description
|
token
-----------------+------------------------------------------+--------------numhword
| Hyphenated word, letters and digits
| foo-bar-beta1
hword_asciipart | Hyphenated word part, all ASCII
| foo
blank
| Space symbols
| hword_asciipart | Hyphenated word part, all ASCII
| bar
blank
| Space symbols
| hword_numpart
| Hyphenated word part, letters and digits | beta1
Ce comportement est souhaitable car il autorise le bon fonctionnement de la recherche sur le mot compos et sur les composants.
Voici un autre exemple instructif :
SELECT alias, description, token FROM ts_debug('http://example.com/stuff/index.html');
alias
| description |
token
----------+---------------+-----------------------------protocol | Protocol head | http://
245

Recherche plein texte

url
| URL
host
| Host
url_path | URL path

| example.com/stuff/index.html
| example.com
| /stuff/index.html

12.6. Dictionnaires
Les dictionnaires sont utiliss pour liminer des mots qui ne devraient pas tre considrs dans une recherche (termes courants), et
pour normaliser des mots pour que des formes drives de ce mme mot tablissent une correspondance. Un mot normalis avec
succs est appel un lexeme. En dehors d'amliorer la qualit de la recherche, la normalisation et la suppression des termes courants rduisent la taille de la reprsentation d'un document en tsvector, et donc amliorent les performances. La normalisation n'a
pas toujours une signification linguistique et dpend habituellement de la smantique de l'application.
Quelques exemples de normalisation :

Linguistique - les dictionnaires ispell tentent de rduire les mots en entre en une forme normalise ; les dictionnaires stemmer
suppriment la fin des mots
Les URL peuvent tre rduites pour tablir certaines correspondance :

http://www.pgsql.ru/db/mw/index.html
http://www.pgsql.ru/db/mw/
http://www.pgsql.ru/db/../db/mw/index.html

Les noms de couleur peuvent tre remplacs par leur valeur hexadcimale, par exemple red, green, blue, magenta
-> FF0000, 00FF00, 0000FF, FF00FF
En cas d'indexation de nombre, nous pouvons supprimer certains chiffres fraction pour rduire les nombres possibles, donc
par exemple 3.14159265359, 3.1415926, 3.14 seront identiques aprs normalisation si seuls deux chiffres sont conservs aprs
le point dcimal.

Un dictionnaire est un programme qui accepte un jeton en entre et renvoie :

un tableau de lexemes si le jeton en entre est connu dans le dictionnaire (notez qu'un jeton peut produire plusieurs lexemes)
un unique lexeme avec le drapeau TSL_FILTER configur, pour remplacer le jeton original avec un nouveau jeton passer
aux dictionnaires suivants (un dictionnaire de ce type est appel un dictionnaire filtrant)
un tableau vide si le dictionnaire connat le jeton mais que ce dernier est un terme courant
NULL si le dictionnaire n'a pas reconnu le jeton en entre

PostgreSQL fournit des dictionnaires prdfinis pour de nombreuses langues. Il existe aussi plusieurs modles prdfinis qui
peuvent tre utiliss pour crer de nouveaux dictionnaires avec des paramtres personnaliss. Chaque modle prdfini de dictionnaire est dcrit ci-dessous. Si aucun modle ne convient, il est possible d'en crer de nouveaux ; voir le rpertoire contrib/ de
PostgreSQL pour des exemples.
Une configuration de recherche plein texte lie un analyseur avec un ensemble de dictionnaires pour traiter les jetons en sortie de
l'analyseur. Pour chaque type de jeton que l'analyseur peut renvoyer, une liste spare de dictionnaires est indique par la configuration. Quand un jeton de ce type est trouve par l'analyseur, chaque dictionnaire de la liste est consult jusqu' ce qu'un dictionnaire le reconnaisse comme un mot connu. S'il est identifi comme un terme courant ou si aucun dictionnaire ne le reconnait, il sera ignor et non index. Normalement, le premier dictionnaire qui renvoie une sortie non NULL dtermine le rsultat et tout dictionnaire restant n'est pas consult ; par contre, un dictionnaire filtrant peut remplacer le mot donn avec un autre mot qui est ensuite pass aux dictionnaires suivants.
La rgle gnrale pour la configuration de la liste des dictionnaires est de placer en premier les dictionnaires les plus prcis, les
plus spcifiques, puis les dictionnaires gnralistes, en finissant avec un dictionnaire le plus gnral possible, comme par exemple
un stemmer Snowball ou simple, qui reconnait tout. Par exemple, pour une recherche en astronomie (configuration
astro_en), vous pouvez lier le type de jeton asciiword (mot ASCII) vers un dictionnaire des synonymes des termes de
l'astronomie, un dictionnaire anglais gnraliste et un stemmer Snowball anglais :
ALTER TEXT SEARCH CONFIGURATION astro_en
ADD MAPPING FOR asciiword WITH astrosyn, english_ispell, english_stem;
Un dictionnaire filtrant peut tre plac n'importe o dans la liste. Cependant, le placer la fin n'a aucun intrt. Les dictionnaires
filtrants sont utiles pour normaliser partiellement les mots, ce qui permet de simplifier la tche aux dictionnaires suivants. Par
exemple, un dictionnaire filtrant peut tre utilis pour supprimer les accents des lettres accentus. C'est ce que fait le module unaccent.

12.6.1. Termes courants


246

Recherche plein texte

Les termes courants sont des mots trs courants, apparaissant dans pratiquement chaque document et n'ont donc pas de valeur discriminatoire. Du coup, ils peuvent tre ignors dans le contexte de la recherche plein texte. Par exemple, tous les textes anglais
contiennent des mots comme a et the, donc il est inutile de les stocker dans un index. Nanmoins, les termes courants n'affectent
pas les positions dans tsvector, ce qui affecte le score :
SELECT to_tsvector('english','in the list of stop words');
to_tsvector
---------------------------'list':3 'stop':5 'word':6
Les positions 1, 2, 4 manquantes sont des aux termes courants. Les scores calculs pour les documents avec et sans termes courants sont vraiment diffrents :
SELECT ts_rank_cd (to_tsvector('english','in the list of stop words'), to_tsquery('list
& stop'));
ts_rank_cd
-----------0.05
SELECT ts_rank_cd (to_tsvector('english','list stop words'), to_tsquery('list &
stop'));
ts_rank_cd
-----------0.1
C'est au dictionnaire de savoir comment traiter les mots courants. Par exemple, les dictionnaires Ispell normalisent tout d'abord
les mots puis cherchent les termes courants alors que les stemmers Snowball vrifient d'abord leur liste de termes courants. La
raison de leur comportement diffrent est qu'ils tentent de rduire le bruit.

12.6.2. Dictionnaire simple


Le modle du dictionnaire simple opre en convertissant le jeton en entre en minuscule puis en vrifiant s'il fait partie de la
liste des mots courants qu'il a sur fichier. S'il est trouv dans ce fichier, un tableau vide est renvoy. Le jeton sera alors ignor.
Dans le cas contraire, la forme minuscule du mot est renvoy en tant que lexeme normalis. Autrement, le dictionnaire peut tre
configur pour rapporter les termes courants comme tant non reconnus, ce qui permet de les passer au prochain dictionnaire de la
liste.
Voici un exemple d'une dfinition de dictionnaire utilisant le modle simple :
CREATE TEXT SEARCH DICTIONARY public.simple_dict (
TEMPLATE = pg_catalog.simple,
STOPWORDS = english
);
Dans ce cas, english est le nom de base du fichier contenant les termes courants. Le nom complet du fichier sera donc
$SHAREDIR/tsearch_data/english.stop, o $SHAREDIR est le rpertoire des donnes partages de l'installation de
PostgreSQL (souvent /usr/local/share/postgresql mais utilisez pg_config --sharedir pour vous en assurer). Le format du fichier est une simple liste de mots, un mot par ligne. Les lignes vides et les espaces en fin de mot sont ignors. Les mots
en majuscule sont basculs en minuscule, mais aucun autre traitement n'est ralis sur le contenu de ce fichier.
Maintenant, nous pouvons tester notre dictionnaire :
SELECT ts_lexize('public.simple_dict','YeS');
ts_lexize
----------{yes}
SELECT ts_lexize('public.simple_dict','The');
ts_lexize
----------{}
Nous pouvons aussi choisir de renvoyer NULL la place du mot en minuscule s'il n'est pas trouv dans le fichier des termes courants. Ce comportement est slectionn en configurant le paramtre Accept du dictionnaire false. En continuant l'exemple :

247

Recherche plein texte

ALTER TEXT SEARCH DICTIONARY public.simple_dict ( Accept = false );


SELECT ts_lexize('public.simple_dict','YeS');
ts_lexize
----------SELECT ts_lexize('public.simple_dict','The');
ts_lexize
----------{}
Avec le paramtrage par dfaut d'Accept ( savoir, true), il est prfrable de placer un dictionnaire simple la fin de la liste
des dictionnaires. Accept = false est seulement utile quand il y a au moins un dictionnaire aprs celui-ci.

Attention
La plupart des types de dictionnaires se basent sur des fichiers de configuration, comme les fichiers de termes courants. Ces fichiers doivent tre dans l'encodage UTF-8. Ils seront traduit vers l'encodage actuelle de la base de donnes, si elle est diffrente, quand ils seront lus.

Attention
Habituellement, une session lira un fichier de configuration du dictionnaire une seule fois, lors de la premire utilisation. Si vous modifiez un fichier de configuration et que vous voulez forcer la prise en compte des modifications
par les sessions en cours, excutez une commande ALTER TEXT SEARCH DICTIONARY sur le dictionnaire.
Cela peut tre une mise jour vide , donc sans rellement modifier des valeurs.

12.6.3. Dictionnaire des synonymes


Ce modle de dictionnaire est utilis pour crer des dictionnaires qui remplacent un mot par un synonyme. Les phrases ne sont pas
supportes (utilisez le modle thsaurus pour cela, Section 12.6.4, Dictionnaire thsaurus ). Un dictionnaire des synonyme peut
tre utilis pour contourner des problmes linguistiques, par exemple pour empcher un dictionnaire stemmer anglais de rduire le
mot Paris en 'pari'. Il suffit d'avoir une ligne Paris paris dans le dictionnaire des synonymes et de le placer avant le dictionnaire english_stem. Par exemple :
SELECT * FROM ts_debug('english', 'Paris');
alias
|
description
| token | dictionaries | dictionary | lexemes
-----------+-----------------+-------+----------------+--------------+--------asciiword | Word, all ASCII | Paris | {english_stem} | english_stem | {pari}
CREATE TEXT SEARCH DICTIONARY my_synonym (
TEMPLATE = synonym,
SYNONYMS = my_synonyms
);
ALTER TEXT SEARCH CONFIGURATION english
ALTER MAPPING FOR asciiword WITH my_synonym, english_stem;
SELECT * FROM ts_debug('english', 'Paris');
alias
|
description
| token |
dictionaries
| dictionary | lexemes
-----------+-----------------+-------+---------------------------+------------+--------asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {paris}
Le seul paramtre requis par le modle synonym est SYNONYMS, qui est le nom de base de son fichier de configuration -my_synonyms
dans
l'exemple
ci-dessus.
Le
nom
complet
du
fichier
sera
$SHAREDIR/tsearch_data/my_synonyms.syn (o $SHAREDIR correspond au rpertoire des donnes partages de
l'installation de PostgreSQL). Le format du fichier est une ligne par mot substituer, avec le mot suivi par son synonyme spar
par un espace blanc. Les lignes vierges et les espaces aprs les mots sont ignors, les lettres majuscules sont mises en minuscules.
Le modle synonym a aussi un paramtre optionnel, appel CaseSensitive, qui vaut par dfaut false. Quand CaseSensitive vaut false, les mots dans le fichier des synonymes sont mis en minuscule, comme les jetons en entre. Quand il vaut
vrai, les mots et les jetons ne sont plus mis en minuscule, mais compars tels quels..
248

Recherche plein texte

Un astrisque (*) peut tre plac la fin d'un synonyme dans le fichier de configuration. Ceci indique que le synonyme est un prfixe. L'astrisque est ignor quand l'entre est utilise dans to_tsvector(), mais quand il est utilis dans to_tsquery(), le
rsultat sera un lment de la requte avec le marqueur de correspondance du prfixe (voir Section 12.3.2, Analyser des requtes ). Par exemple, supposons que nous avons ces entres dans $SHAREDIR/tsearch_data/synonym_sample.syn :
postgres
postgresql
postgre pgsql
gogle
googl
indices index*

pgsql
pgsql

Alors nous obtiendrons les rsultats suivants :


mydb=# CREATE TEXT SEARCH DICTIONARY syn (template=synonym, synonyms='synonym_sample');
mydb=# SELECT ts_lexize('syn','indices');
ts_lexize
----------{index}
(1 row)
mydb=# CREATE TEXT SEARCH CONFIGURATION tst (copy=simple);
mydb=# ALTER TEXT SEARCH CONFIGURATION tst ALTER MAPPING FOR asciiword WITH syn;
mydb=# SELECT to_tsvector('tst','indices');
to_tsvector
------------'index':1
(1 row)
mydb=# SELECT to_tsquery('tst','indices');
to_tsquery
-----------'index':*
(1 row)
mydb=# SELECT 'indexes are very useful'::tsvector;
tsvector
--------------------------------'are' 'indexes' 'useful' 'very'
(1 row)
mydb=# SELECT 'indexes are very useful'::tsvector @@ to_tsquery('tst','indices');
?column?
---------t
(1 row)

12.6.4. Dictionnaire thsaurus


Un dictionnaire thsaurus (parfois abrvi en TZ) est un ensemble de mots qui incluent des informations sur les relations des mots
et des phrases, par exemple des termes plus lointains (BT), plus proches (NT), des termes prfrs, des termes non aims, des
termes en relation, etc.
De faon simple, un dictionnaire thsaurus remplace tous les termes par des termes prfrs et, en option, conserve les termes originaux pour l'indexage. L'implmentation actuelle du dictionnaire thsaurus par PostgreSQL est une extension du dictionnaire
des synonymes avec un support additionnel des phrases. Un dictionnaire thsaurus ncessite un fichier de configuration au format
suivant :
# ceci est un commentaire
mots(s) : mot(s) index(s)
d'autre(s) mot(s) : d'autre(s) mot(s) index(s)
...
o le deux-points (:) agit comme un dlimiteur entre une phrase et son remplacement.
Un dictionnaire thsaurus utilise un sous-dictionnaire (qui est spcifi dans la configuration du dictionnaire) pour normaliser le
texte en entre avant la vrification des correspondances de phrases. Un seul sous-dictionnaire est slectionnable. Une erreur est
renvoye si le sous-dictionnaire choue dans la reconnaissance d'un mot. Dans ce cas, vous devez supprimer l'utilisation du mot ou
249

Recherche plein texte

le faire connatre au sous-dictionnaire. Vous pouvez placer une astrisque (*) devant un mot index pour ignorer l'utilisation du
sous-dictionnaire mais tous les mots doivent tre connus du sous-dictionnaire.
Le dictionnaire thsaurus choisit la plus grande correspondance s'il existe plusieurs phrases correspondant l'entre.
Les mots spcifiques reconnus par le sous-dictionnaire ne peuvent pas tre prciss ; la place, utilisez ? pour marquer tout emplacement o un terme courant peut apparatre. Par exemple, en supposant que a et the sont des termes courants d'aprs le sousdictionnaire :
? one ? two : swsw
correspond a one the two et the one a two. Les deux pourraient tre remplacs par swsw.
Comme un dictionnaire thsaurus a la possibilit de reconnatre des phrases, il doit se rappeler son tat et interagir avec
l'analyseur. Un dictionnaire thsaurus utilise ces assignements pour vrifier s'il doit grer le mot suivant ou arrter l'accumulation.
Le dictionnaire thsaurus doit tre configur avec attention. Par exemple, si le dictionnaire thsaurus s'occupe seulement du type
de jeton asciiword, alors une dfinition du dictionnaire thsaurus comme one 7 ne fonctionnera pas car le type de jeton
uint n'est pas affect au dictionnaire thsaurus.

Attention
Les thsaurus sont utiliss lors des indexages pour que toute modification dans les paramtres du dictionnaire thsaurus ncessite un rindexage. Pour la plupart des autres types de dictionnaire, de petites modifications comme
l'ajout ou la suppression de termes courants ne demandent pas un rindexage.

12.6.4.1. Configuration du thsaurus


Pour dfinir un nouveau dictionnaire thsaurus, utilisez le modle thesaurus. Par exemple :
CREATE TEXT SEARCH DICTIONARY thesaurus_simple (
TEMPLATE = thesaurus,
DictFile = mythesaurus,
Dictionary = pg_catalog.english_stem
);
Dans ce cas :

thesaurus_simple est le nom du nouveau dictionnaire


mythesaurus est le nom de base du fichier de configuration du thsaurus. (Son nom complet est
$SHAREDIR/tsearch_data/mythesaurus.ths, o $SHAREDIR est remplac par le rpertoire des donnes partages de l'installation.)
pg_catalog.english_stem est le sous-dictionnaire (ici un stemmer Snowball anglais) utiliser pour la normalisation
du thsaurus. Notez que le sous-dictionnaire aura sa propre configuration (par exemple, les termes courants) qui n'est pas affiche ici.

Maintenant, il est possible de lier le dictionnaire du thsaurus thesaurus_simple aux types de jeton dsirs dans une configuration, par exemple :
ALTER TEXT SEARCH CONFIGURATION russian
ALTER MAPPING FOR asciiword, asciihword, hword_asciipart WITH thesaurus_simple;

12.6.4.2. Exemple de thsaurus


Considrez un thsaurus d'astronomie thesaurus_astro, contenant quelques combinaisons de mots d'astronomie :
supernovae stars : sn
crab nebulae : crab
Ci-dessous, nous crons un dictionnaire et lions certains types de jeton un thsaurus d'astronomie et un stemmer anglais :
CREATE TEXT SEARCH DICTIONARY thesaurus_astro (
TEMPLATE = thesaurus,
DictFile = thesaurus_astro,
Dictionary = english_stem
);
250

Recherche plein texte

ALTER TEXT SEARCH CONFIGURATION russian


ALTER MAPPING FOR asciiword, asciihword, hword_asciipart WITH thesaurus_astro,
english_stem;
Maintenant, nous pouvons voir comment cela fonctionne. ts_lexize n'est pas trs utile pour tester un thsaurus car elle traite
l'entre en tant que simple jeton. la place, nous pouvons utiliser plainto_tsquery et to_tsvector qui cassera les
chanes en entre en plusieurs jetons :
SELECT plainto_tsquery('supernova star');
plainto_tsquery
----------------'sn'
SELECT to_tsvector('supernova star');
to_tsvector
------------'sn':1
En principe, il es possible d'utiliser to_tsquery si vous placez l'argument entre guillemets :
SELECT to_tsquery('''supernova star''');
to_tsquery
-----------'sn'
Notez que supernova star tablit une correspondance avec supernovae stars dans thesaurus_astro car nous
avions indiqu le stemmer english_stem dans la dfinition du thsaurus. Le stemmer a supprim e et s.
Pour indexer la phrase originale ainsi que son substitut, incluez-le dans la partie droite de la dfinition :
supernovae stars : sn supernovae stars
SELECT plainto_tsquery('supernova star');
plainto_tsquery
----------------------------'sn' & 'supernova' & 'star'

12.6.5. Dictionnaire Ispell


Le modle de dictionnaire Ispell ajoute le support des dictionnaires morphologiques qui peuvent normaliser plusieurs formes linguisitiques diffrentes d'un mot en un mme lexeme. Par exemple, un dictionnaire Ispell anglais peut tablir une correspondance
avec toutes les dclinaisons et conjugaisons du terme bank, c'est--dire banking, banked, banks, banks' et bank's.
La distribution standard de PostgreSQL n'inclut aucun des fichiers de configuration Ispell. Les dictionnaires sont disponibles
pour un grand nombre de langues partir du site web Ispell. De plus, certains formats de fichiers dictionnaires plus modernes sont
supports -- MySpell (OO < 2.0.1) et Hunspell (OO >= 2.0.2). Une large liste de dictionnaires est disponible sur le Wiki
d'OpenOffice .
Pour crer un dictionnaire Ispell, utilisez le modle interne Ispell et prcisez plusieurs paramtres :
CREATE TEXT SEARCH DICTIONARY english_ispell (
TEMPLATE = ispell,
DictFile = english,
AffFile = english,
StopWords = english
);
Ici, DictFile, AffFile et StopWords indiquent les noms de base des fichiers dictionnaire, affixes et termes courants. Le fichier des termes courants a le mme format qu'indiqu ci-dessus pour le type de dictionnaire simple. Le format des autres fichiers n'est pas indiqu ici mais est disponible sur les sites web mentionns ci-dessus.
Les dictionnaires Ispell reconnaissent habituellement un ensemble limit de mots, pour qu'ils puissent tre suivis par un dictionnaire encore plus gnraliste ; par exemple un dictionnaire Snowball qui reconnat tout.
Les dictionnaires Ispell supportent la sparation des mots composs, une fonctionnalit intressante. Notez que le fichier d'affixes
doit indiquer une option spciale qui marque les mots du dictionnaire qui peuvent participer une formation compose :
251

Recherche plein texte

compoundwords

controlled z

Voici quelques exemples en norvgien :


SELECT ts_lexize('norwegian_ispell', 'overbuljongterningpakkmesterassistent');
{over,buljong,terning,pakk,mester,assistent}
SELECT ts_lexize('norwegian_ispell', 'sjokoladefabrikk');
{sjokoladefabrikk,sjokolade,fabrikk}

Note
MySpell ne supporte pas les mots composs. Hunspell a un support sophistiqu des mots composs. Actuellement,
PostgreSQL implmente seulement les oprations basiques de Hunspell pour les mots composs.

12.6.6. Dictionnaire Snowball


Le modle de dictionnaire Snowball est bas sur le projet de Martin Porter, inventeur du populaire algorithme stemming de Porter
pour l'anglais. Snowball propose maintenant des algorithmes stemming pour un grand nombre de langues (voir le site Snowball
pour plus d'informations). Chaque algorithme sait comment rduire les variantes standard d'un mot vers une base, ou stem, en rapport avec la langue. Un dictionnaire Snowball rclame un paramtre langue pour identifier le stemmer utiliser et, en option, un
nom de fichier des termes courants donnant une liste de mots liminer. (Les listes de termes courants au standard PostgreSQL sont aussi fournies par le projet Snowball.) Par exemple, il existe un quivalent de la dfinition interne en
CREATE TEXT SEARCH DICTIONARY english_stem (
TEMPLATE = snowball,
Language = english,
StopWords = english
);
Le format du fichier des termes courants est identique celui dj expliqu.
Un dictionnaire Snowball reconnat tout, qu'il soit ou non capable de simplifier le mot, donc il doit tre plac en fin de la liste des
dictionnaires. Il est inutile de l'avoir avant tout autre dictionnaire car un jeton ne passera jamais au prochain dictionnaire.

12.7. Exemple de configuration


Une configuration de recherche plein texte prcise toutes les options ncessaires pour transformer un document en un tsvector : le
planificateur utiliser pour diviser le texte en jetons, et les dictionnaires utiliser pour transformer chaque jeton en un lexeme.
Chaque appel to_tsvector ou to_tsquery a besoin d'une configuration de recherche plein texte pour raliser le traitement. Le paramtre de configuration default_text_search_config indique le nom de la configuration par dfaut, celle utilise par
les fonctions de recherche plein texte si un paramtre explicite de configuration est oubli. Il se configure soit dans postgresql.conf soit dans une session individuelle en utilisant la commande SET.
Plusieurs configurations de recherche plein texte prdfinies sont disponibles et vous pouvez crer des versions personnalises facilement. Pour faciliter la gestion des objets de recherche plein texte, un ensemble de commandes SQL est disponible, et il existe
plusieurs commandes psql affichant des informations sur les objets de la recherche plein texte (Section 12.10, Support de
psql ).
Comme exemple, nous allons crer une configuration pg en commenant partir d'une duplication de la configuration english.
CREATE TEXT SEARCH CONFIGURATION public.pg ( COPY = pg_catalog.english );
Nous allons utiliser une liste de synonymes spcifique PostgreSQL et
$SHAREDIR/tsearch_data/pg_dict.syn. Le contenu du fichier ressemble ceci :
postgres
pgsql
postgresql

pg
pg
pg

Nous dfinissons le dictionnaire des synonymes ainsi :


CREATE TEXT SEARCH DICTIONARY pg_dict (
252

nous

allons

la

stocker

dans

Recherche plein texte

TEMPLATE = synonym,
SYNONYMS = pg_dict
);
Ensuite, nous enregistrons le dictionnaire Ispell english_ispell qui a ses propres fichiers de configuration :
CREATE TEXT SEARCH DICTIONARY english_ispell (
TEMPLATE = ispell,
DictFile = english,
AffFile = english,
StopWords = english
);
Maintenant, nous configurons la correspondance des mots dans la configuration pg :
ALTER TEXT SEARCH CONFIGURATION pg
ALTER MAPPING FOR asciiword, asciihword, hword_asciipart,
word, hword, hword_part
WITH pg_dict, english_ispell, english_stem;
Nous choisissons de ne pas indexer certains types de jeton que la configuration par dfaut peut grer :
ALTER TEXT SEARCH CONFIGURATION pg
DROP MAPPING FOR email, url, url_path, sfloat, float;
Maintenant, nous pouvons tester notre configuration :
SELECT * FROM ts_debug('public.pg', '
PostgreSQL, the highly scalable, SQL compliant, open source object-relational
database management system, is now undergoing beta testing of the next
version of our software.
');
La prochaine tape est d'initialiser la session pour utiliser la nouvelle configuration qui tait cre dans le schma public :
=> \dF
List of text search configurations
Schema | Name | Description
---------+------+------------public | pg
|
SET default_text_search_config = 'public.pg';
SET
SHOW default_text_search_config;
default_text_search_config
---------------------------public.pg

12.8. Tester et dboguer la recherche plein texte


Le comportement d'une configuration personnalise de recherche plein texte peut facilement devenir confuse. Les fonctions dcrites dans cette section sont utiles pour tester les objets de recherche plein texte. Vous pouvez tester une configuration complte
ou tester sparment analyseurs et dictionnaires.

12.8.1. Test d'une configuration


La fonction ts_debug permet un test facile d'une configuration de recherche plein texte.
ts_debug([ config regconfig, ] document text,
OUT alias text,
OUT description text,
OUT token text,
OUT dictionaries regdictionary[],
253

Recherche plein texte

OUT dictionary regdictionary,


OUT lexemes text[])
returns setof record
ts_debug affiche des informations sur chaque jeton d'un document tel qu'il est produit par l'analyseur et trait par les dictionnaires configurs. Elle utilise la configuration indique par config, ou default_text_search_config si cet argument
est omis.
ts_debug renvoie une ligne pour chaque jeton identifi dans le texte par l'analyseur. Les colonnes renvoyes sont :

alias text -- nom court du type de jeton


description text -- description du type de jeton
token text -- texte du jeton
dictionaries regdictionary[] -- les dictionnaires slectionns par la configuration pour ce type de jeton
dictionary regdictionary -- le dictionnaire qui a reconnu le jeton, ou NULL dans le cas contraire
lexemes text[] -- le ou les lexemes produit par le dictionnaire qui a reconnu le jeton, ou NULL dans le cas contraire ; un tableau vide ({}) signifie qu'il a t reconnu comme un terme courant

Voici un exemple simple :


SELECT * FROM ts_debug('english','a fat cat sat on a mat - it ate a fat rats');
alias
|
description
| token | dictionaries | dictionary | lexemes
-----------+-----------------+-------+----------------+--------------+--------asciiword | Word, all ASCII | a
| {english_stem} | english_stem | {}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | fat
| {english_stem} | english_stem | {fat}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | cat
| {english_stem} | english_stem | {cat}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | sat
| {english_stem} | english_stem | {sat}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | on
| {english_stem} | english_stem | {}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | a
| {english_stem} | english_stem | {}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | mat
| {english_stem} | english_stem | {mat}
blank
| Space symbols
|
| {}
|
|
blank
| Space symbols
| | {}
|
|
asciiword | Word, all ASCII | it
| {english_stem} | english_stem | {}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | ate
| {english_stem} | english_stem | {ate}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | a
| {english_stem} | english_stem | {}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | fat
| {english_stem} | english_stem | {fat}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | rats | {english_stem} | english_stem | {rat}
Pour une dmonstration plus importante, nous crons tout d'abord une configuration public.english et un dictionnaire ispell
pour l'anglais :
CREATE TEXT SEARCH CONFIGURATION public.english ( COPY = pg_catalog.english );
CREATE TEXT SEARCH DICTIONARY english_ispell (
TEMPLATE = ispell,
DictFile = english,
AffFile = english,
StopWords = english
);
ALTER TEXT SEARCH CONFIGURATION public.english
ALTER MAPPING FOR asciiword WITH english_ispell, english_stem;
SELECT * FROM ts_debug('public.english','The Brightest supernovaes');
alias
|
description
|
token
|
dictionaries
254

Recherche plein texte

dictionary
|
lexemes
-----------+-----------------+-------------+-------------------------------+---------------asciiword | Word, all ASCII | The
| {english_ispell,english_stem} |
english_ispell | {}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | Brightest
| {english_ispell,english_stem} |
english_ispell | {bright}
blank
| Space symbols
|
| {}
|
|
asciiword | Word, all ASCII | supernovaes | {english_ispell,english_stem} |
english_stem
| {supernova}
Dans cet exemple, le mot Brightest a t reconnu par l'analyseur comme un mot ASCII (alias asciiword). Pour ce type
de jeton, la liste de dictionnaire est english_ispell et english_stem. Le mot a t reconnu par english_ispell, qui
l'a rduit avec le mot bright. Le mot supernovaes est inconnu dans le dictionnaire english_ispell donc il est pass au
dictionnaire suivant et, heureusement, est reconnu (en fait, english_stem est un dictionnaire Snowball qui reconnat tout ; c'est
pourquoi il est plac en dernier dans la liste des dictionnaires).
Le mot The est reconnu par le dictionnaire english_ispell comme tant un terme courant (Section 12.6.1, Termes courants ) et n'est donc pas index. Les espaces sont aussi ignors car la configuration ne fournit aucun dictionnaire pour eux.
Vous pouvez rduire le volume en sortie en spcifiant explicitement les colonnes que vous voulez voir :
SELECT alias, token, dictionary, lexemes
FROM ts_debug('public.english','The Brightest supernovaes');
alias
|
token
|
dictionary
|
lexemes
-----------+-------------+----------------+------------asciiword | The
| english_ispell | {}
blank
|
|
|
asciiword | Brightest
| english_ispell | {bright}
blank
|
|
|
asciiword | supernovaes | english_stem
| {supernova}

12.8.2. Test de l'analyseur


Les fonctions suivantes permettent un test direct d'un analyseur de recherche plein texte.
ts_parse(parser_name text, document text, OUT tokid integer, OUT token text) returns
setof record
ts_parse(parser_oid oid, document text, OUT tokid integer, OUT token text) returns
setof record
ts_parse analyse le document indiqu et renvoie une srie d'enregistrements, un pour chaque jeton produit par l'analyse.
Chaque enregistrement inclut un tokid montrant le type de jeton affect et un jeton (token) qui est le texte dudit jeton. Par
exemple :
SELECT * FROM ts_parse('default', '123 - a number');
tokid | token
-------+-------22 | 123
12 |
12 | 1 | a
12 |
1 | number
ts_token_type(parser_name text, OUT tokid integer, OUT alias text, OUT description
text) returns setof record
ts_token_type(parser_oid oid, OUT tokid integer, OUT alias text, OUT description
text) returns setof record

255

Recherche plein texte

ts_token_type renvoie une table qui dcrit chaque type de jeton que l'analyseur indiqu peut reconnatre. Pour chaque type de
jeton, la table donne l'entier tokid que l'analyseur utilise pour labeliser un jeton de ce type, l'alias qui nomme le type de jeton
dans les commandes de configuration et une courte description. Par exemple :
SELECT * FROM ts_token_type('default');
tokid |
alias
|
description
-------+-----------------+-----------------------------------------1 | asciiword
| Word, all ASCII
2 | word
| Word, all letters
3 | numword
| Word, letters and digits
4 | email
| Email address
5 | url
| URL
6 | host
| Host
7 | sfloat
| Scientific notation
8 | version
| Version number
9 | hword_numpart
| Hyphenated word part, letters and digits
10 | hword_part
| Hyphenated word part, all letters
11 | hword_asciipart | Hyphenated word part, all ASCII
12 | blank
| Space symbols
13 | tag
| XML tag
14 | protocol
| Protocol head
15 | numhword
| Hyphenated word, letters and digits
16 | asciihword
| Hyphenated word, all ASCII
17 | hword
| Hyphenated word, all letters
18 | url_path
| URL path
19 | file
| File or path name
20 | float
| Decimal notation
21 | int
| Signed integer
22 | uint
| Unsigned integer
23 | entity
| XML entity

12.8.3. Test des dictionnaires


La fonction ts_lexize facilite le test des dictionnaires.
ts_lexize(dict regdictionary, token text) returns text[]
ts_lexize renvoie un tableau de lexemes si le jeton (token) en entre est connu du dictionnaire ou un tableau vide si le jeton
est connu du dictionnaire en tant que terme courant, ou enfin NULL si le mot n'est pas connu.
Exemples :
SELECT ts_lexize('english_stem', 'stars');
ts_lexize
----------{star}
SELECT ts_lexize('english_stem', 'a');
ts_lexize
----------{}

Note
La fonction ts_lexize attend un seul jeton, pas du texte. Voici un cas o cela peut devenir source de confusion :
SELECT ts_lexize('thesaurus_astro','supernovae stars') is null;
?column?
---------t
Le dictionnaire thsaurus thesaurus_astro connat la phrase supernovae stars mais ts_lexize
choue car il ne peut pas analyser le texte en entre mais le traite bien en tant que simple jeton. Utilisez plain256

Recherche plein texte

to_tsquery ou to_tsvector pour tester les dictionnaires thsaurus. Par exemple :


SELECT plainto_tsquery('supernovae stars');
plainto_tsquery
----------------'sn'

12.9. Types d'index GiST et GIN


Il existe deux types d'index qui peuvent tre utiliss pour acclrer les recherches plein texte. Notez que les index ne sont pas obligatoires pour la recherche plein texte mais, dans les cas o une colonne est utilise frquemment dans une recherche, un index sera
suffisamment intressant.

CREATE INDEX nom ON table USING gist(colonne);


Cre un index GiST (Generalized Search Tree). La colonne peut tre de type tsvector ou tsquery.
CREATE INDEX nom ON table USING gin(colonne);
Cre un index GIN (Generalized Inverted Index). La colonne doit tre de type tsvector.
Il y a des diffrences de performances substantielles entre les deux types d'index, donc il est important de comprendre leurs caractristiques.
Un index GiST est perte, signifiant que l'index peut produire des faux positifs, et il est ncessaire de vrifier la ligne de la table
pour les liminer. PostgreSQL le fait automatiquement si ncessire. Les index GiST sont perte car chaque document est reprsent dans l'index par une signature longueur fixe. La signature est gnre par le hachage de chaque mot en un bit alatoire dans
une chane n bit, tous ces bits tant assembls dans une opration OR qui produit une signature du document sur n bits. Quand
deux hachages de mots sont identiques, nous avons un faux positif. Si tous les mots de la requte ont une correspondance (vraie ou
fausse), alors la ligne de la table doit tre rcupre pour voir si la correspondance est correcte.
La perte implique une dgradation des performances cause de rcuprations inutiles d'enregistrements de la table qui s'avrent
tre de fausses correspondances. Comme les accs alatoire aux enregistrements de la table sont lents, ceci limite l'utilit des index
GiST. La probabilit de faux positifs dpends de plusieurs facteurs, en particulier le nombre de mots uniques, donc l'utilisation de
dictionnaires qui rduisent ce nombre est recommande.
Les index GIN ne sont pas perte pour les requtes standards mais leur performance dpend de faon logarithmique au nombre de
mots uniques. (Nanmoins, les index GIN enregistrent seulement les mots (lexemes) des valeurs de type tsvector, et non pas les labels de poids. Donc, la re-vrification d'une ligne de table est ncessaire quand vous utilisez une requte qui indique des poids.
Dans le choix du type d'index utiliser, GiST ou GIN, pensez ces diffrences de performances :

Les recherches par index GIN sont environ trois fois plus rapides que celles par index GiST.
Les index GIN prennent trois fois plus de temps se contruire que les index GiST.
Les index GIN sont un peu plus lents mettre jour que les index GiST, mais dix fois plus lent si le support de la mise jour
rapide a t dsactiv (voir Section 54.3.1, Technique GIN de mise jour rapide pour les dtails)
Les index GIN sont entre deux et trois fois plus gros que les index GiST.

En rgle gnrale, les index GIN sont meilleurs pour des donnes statiques car les recherches sont plus rapides. Pour des donnes
dynamiques, les index GiST sont plus rapides mettre jour. Autrement dit, les index GiST sont trs bons pour les donnes dynamiques et rapides si le nombre de mots uniques (lexemes) est infrieur 100000 alors que les index GIN greront plus de 100000
lexemes plus facilement mais sont plus lents mettre jour.
Notez que le temps de construction de l'index GIN peut souvent tre amlior en augmentant maintenance_work_mem alors qu'un
index GiST n'est pas sensible ce paramtre.
Le partitionnement de gros ensembles et l'utilisation intelligente des index GIN et GiST autorise l'implmentation de recherches
trs rapides avec une mise jour en ligne. Le partitionnement peut se faire au niveau de la base en utilisant l'hritage, ou en distribuant les documents sur des serveurs et en rcuprant les rsultats de la recherche en utilisant le module contrib/dblink. Ce
dernier est possible car les fonctions de score utilisent les informations locales.
257

Recherche plein texte

12.10. Support de psql


Des informations sur les objets de configuration de la recherche plein texte peuvent tre obtenues dans psql en utilisant l'ensemble
de commandes :
\dF{d,p,t}[+] [MODLE]
Un + supplmentaire affiche plus de dtails.
Le paramtre MODLE doit tre le nom d'un objet de la recherche plein texte, pouvant tre qualifi du nom du schma. Si MODLE
est omis, alors l'information sur tous les objets visibles est affiche. MODLE peut tre une expression rationnelle et peut fournir
des modles spars pour les noms du schma et de l'objet. Les exemples suivants illustrent ceci :
=> \dF *fulltext*
List of text search configurations
Schema | Name
| Description
--------+--------------+------------public | fulltext_cfg |
=> \dF *.fulltext*
List of text search configurations
Schema
| Name
| Description
----------+---------------------------fulltext | fulltext_cfg |
public
| fulltext_cfg |
Les commandes suivantes sont :
\dF[+] [MODLE]
Liste les configurations de recherche plein texte (ajouter + pour plus de dtails).
=> \dF russian
List of text search configurations
Schema
| Name
|
Description
------------+---------+-----------------------------------pg_catalog | russian | configuration for russian language
=> \dF+ russian
Text search configuration "pg_catalog.russian"
Parser: "pg_catalog.default"
Token
| Dictionaries
-----------------+-------------asciihword
| english_stem
asciiword
| english_stem
email
| simple
file
| simple
float
| simple
host
| simple
hword
| russian_stem
hword_asciipart | english_stem
hword_numpart
| simple
hword_part
| russian_stem
int
| simple
numhword
| simple
numword
| simple
sfloat
| simple
uint
| simple
url
| simple
url_path
| simple
version
| simple
word
| russian_stem
\dFd[+] [MODLE]
258

Recherche plein texte

Liste les dictionnaires de recherche plein texte (ajouter + pour plus de dtails).
=> \dFd

List of text search dictionaries


Schema
|
Name
|
Description
------------+-----------------+---------------------------------------------------------pg_catalog | danish_stem
| snowball stemmer for danish language
pg_catalog | dutch_stem
| snowball stemmer for dutch language
pg_catalog | english_stem
| snowball stemmer for english language
pg_catalog | finnish_stem
| snowball stemmer for finnish language
pg_catalog | french_stem
| snowball stemmer for french language
pg_catalog | german_stem
| snowball stemmer for german language
pg_catalog | hungarian_stem | snowball stemmer for hungarian language
pg_catalog | italian_stem
| snowball stemmer for italian language
pg_catalog | norwegian_stem | snowball stemmer for norwegian language
pg_catalog | portuguese_stem | snowball stemmer for portuguese language
pg_catalog | romanian_stem
| snowball stemmer for romanian language
pg_catalog | russian_stem
| snowball stemmer for russian language
pg_catalog | simple
| simple dictionary: just lower case and check for
stopword
pg_catalog | spanish_stem
| snowball stemmer for spanish language
pg_catalog | swedish_stem
| snowball stemmer for swedish language
pg_catalog | turkish_stem
| snowball stemmer for turkish language
\dFp[+] [MODLE]
Liste les analyseurs de recherche plein texte (ajouter + pour plus de dtails).
=> \dFp
List of text search parsers
Schema
| Name
|
Description
------------+---------+--------------------pg_catalog | default | default word parser
=> \dFp+
Text search parser "pg_catalog.default"
Method
|
Function
| Description
-----------------+----------------+------------Start parse
| prsd_start
|
Get next token | prsd_nexttoken |
End parse
| prsd_end
|
Get headline
| prsd_headline |
Get token types | prsd_lextype
|
Token types for parser "pg_catalog.default"
Token name
|
Description
-----------------+-----------------------------------------asciihword
| Hyphenated word, all ASCII
asciiword
| Word, all ASCII
blank
| Space symbols
email
| Email address
entity
| XML entity
file
| File or path name
float
| Decimal notation
host
| Host
hword
| Hyphenated word, all letters
hword_asciipart | Hyphenated word part, all ASCII
hword_numpart
| Hyphenated word part, letters and digits
hword_part
| Hyphenated word part, all letters
int
| Signed integer
numhword
| Hyphenated word, letters and digits
numword
| Word, letters and digits
protocol
| Protocol head
sfloat
| Scientific notation
tag
| HTML tag
uint
| Unsigned integer
url
| URL
url_path
| URL path
259

Recherche plein texte

version
word
(23 rows)

| Version number
| Word, all letters

\dFt[+] [MODLE]
Liste les modles de recherche plein texte (ajouter + pour plus de dtails).
=> \dFt
List of text search templates
Schema
|
Name
|
Description
------------+-----------+----------------------------------------------------------pg_catalog | ispell
| ispell dictionary
pg_catalog | simple
| simple dictionary: just lower case and check for stopword
pg_catalog | snowball | snowball stemmer
pg_catalog | synonym
| synonym dictionary: replace word by its synonym
pg_catalog | thesaurus | thesaurus dictionary: phrase by phrase substitution

12.11. Limites
Les limites actuelles de la recherche plein texte de PostgreSQL sont :

La longueur de chaque lexeme doit tre infrieure 2 Ko


La longueur d'un tsvector (lexemes + positions) doit tre infrieure 1 Mo
Le nombre de lexemes doit tre infrieur 264
Les valeurs de position dans un tsvector doivent tre suprieures 0 et infrieures ou gales 16383
Pas plus de 256 positions par lexeme
Le nombre de nuds (lexemes + oprateurs) dans un tsquery doit tre infrieur 32768

Pour comparaison, la documentation de PostgreSQL 8.1 contient 10441 mots uniques, un total de 335420 mots, et le mot le plus
frquent, postgresql , est mentionn 6127 fois dans 655 documents.
Un autre exemple -- les archives de la liste de discussion de PostgreSQL contenait 910989 mots uniques avec 57491343
lexemes dans 461020 messages.

12.12. Migration partir d'une recherche plein texte antrieure 8.3


Les applications qui ont utilis le module tsearch2 pour la recherche plein texte auront besoin de quelques ajustements pour fonctionner avec la version interne :

Certaines fonctions ont t renommes ou ont profit de petits ajustements dans leur listes d'arguments. Elles sont toutes dans
le schma pg_catalog alors que, dans une installation prcdente, elles auraient fait partie de public ou d'un autre schma utilisateur. Il existe une nouvelle version de tsearch2 qui fournit une couche de compatibilit permettant de rsoudre la majorit des problmes connus.

Les anciennes fonctions et les autres objets de tsearch2 doivent tre supprims lors du chargement d'une sauvegarde pg_dump
provenant d'une version antrieure la 8.3. Bien que beaucoup des objets ne sont pas chargs de toute faon, certains le sont et
peuvent causer des problmes. La faon la plus simple de grer ceci est de charger seulement le module tsearch2 avant la restauration de la sauvegarde ; cela bloquera la restauration des anciens objets.

Le paramtrage de la configuration de la recherche plein texte est compltement diffrent maintenant. Au lieu d'insrer manuellement des lignes dans les tables de configuration, la recherche se configure avec des commandes SQL spcialises indiques dans tout ce chapitre. Il n'existe pas de support automatis pour convertir une configuration personnalise existante pour
la 8.3. Vous devez vous en occuper manuellement.

Le plupart des types de dictionnaires repose sur certains fichiers de configuration en dehors de la base de donnes. Ils sont largement compatibles pour une utilisation pre-8.3, mais notez malgr tout les diffrences qui suivent :

Les fichiers de configuration doivent tre placs dans le rpertoire $SHAREDIR/tsearch_data, et doivent avoir une
extension spcifique dpendant du type de fichier, comme indiqu prcdemment dans les descriptions des diffrents types
de dictionnaires. Cette restriction a t ajoute pour viter des problmes de scurit.
Les fichiers de configuration doivent tre encods en UTF-8, quelque soit l'encodage utilis par la base de donnes.
Dans les fichiers de configuration du thsaurus, les termes courants doivent tre marqus avec ?.
260

Recherche plein texte

261

Chapitre 13. Contrle d'accs simultan


Ce chapitre dcrit le comportement de PostgreSQL lorsque deux sessions, ou plus, essaient d'accder aux mmes donnes au
mme moment. Le but dans cette situation est de permettre un accs efficace pour toutes les sessions tout en maintenant une intgrit stricte des donnes. Chaque dveloppeur d'applications utilisant des bases de donnes doit avoir une bonne comprhension des thmes couverts dans ce chapitre.

13.1. Introduction
PostgreSQL fournit un ensemble d'outils pour les dveloppeurs qui souhaitent grer des accs simulatns aux donnes. En interne, la cohrence des donnes est obtenue avec l'utilisation d'un modle multiversion (Multiversion Concurrency Control,
MVCC). Ceci signifie que, lors de l'envoi d'une requte la base de donnes, chaque transaction voit une image des donnes
(une version de la base de donnes) telle qu'elles taient quelque temps auparavant, quel que soit l'tat actuel des donnes sousjacentes. Ceci protge la transaction de donnes incohrentes, causes par des mises jour effectues par une (autre) transaction
simultane sur les mmes lignes de donnes, fournissant ainsi une isolation des transactions pour chaque session de la base de
donnes. MVCC, en vitant les mthodes des verrous des systmes de bases de donnes traditionnels, minimise la dure des
verrous pour permettre des performances raisonnables dans des environnements multiutilisateurs.
Le principal avantage de l'utilisation du modle MVCC pour le contrle des accs simultans, contrairement au verrouillage, est
que, dans les verrous acquis par MVCC pour rcuprer (en lecture) des donnes, aucun conflit n'intervient avec les verrous acquis pour crire des donnes. Du coup, lire ne bloque jamais l'criture et crire ne bloque jamais la lecture. PostgreSQL maintient cette garantie mme quand il fournit le niveau d'isolation le plus strict au moyen d'un niveau Serializable Snapshot Isolation (SSI) innovant.
Des possibilits de verrouillage des tables ou des lignes sont aussi disponibles dans PostgreSQL pour les applications qui
n'ont pas besoin en gnral d'une isolation complte des transactions et prfrent grer explicitement les points de conflits particuliers. Nanmoins, un bon usage de MVCC fournira gnralement de meilleures performances que les verrous. De plus, les
verrous informatifs dfinis par l'utilisateur fournissent un mcanisme d'acquisition de verrous qui n'est pas li une transaction.

13.2. Isolation des transactions


Le standard SQL dfinit quatre niveaux d'isolation de transaction. Le plus strict est Serializable, qui est dfini par le standard
dans un paragraphe qui dclare que toute excution concurrente d'un jeu de transactions srialisables doit apporter la garantie de
produire le mme effet que l'excution conscutive de chacun d'entre eux dans un certain ordre. Les trois autres niveaux sont dfinis en terme de phnomnes, rsultant de l'intraction entre les transactions concurrentes, qui ne doivent pas se produire
chaque niveau. Le standard note qu'en raison de la dfinition de Serializable, aucun de ces phnomnes n'est possible ce niveau. (Cela n'a rien de surprenant -- si l'effet des transactions doit tre cohrent avec l'excution conscutive de chacune d'entre
elles, comment pourriez vous voir un phnomne caus par des interactions?).
Les phnomnes qui sont interdits chaque niveau sont:
lecture sale
Une transaction lit des donnes crites par une transaction concurrente non valide (dirty read).
lecture non reproductible
Une transaction relit des donnes qu'elle a lu prcdemment et trouve que les donnes ont t modifies par une autre transaction (valide depuis la lecture initiale) (non repeatable read).
lecture fantme
Une transaction r-excute une requte renvoyant un ensemble de lignes satisfaisant une condition de recherche et trouve
que l'ensemble des lignes satisfaisant la condition a chang du fait d'une autre transaction rcemment valide (phantom
read).
Les quatre niveaux d'isolation de transaction et les comportements correspondants sont dcrits dans le Tableau 13.1, Niveaux
d'isolation des transactions du standard SQL .
Tableau 13.1. Niveaux d'isolation des transactions du standard SQL

Niveau d'isolation

Lecture sale

Lecture non re- Lecture fantme


productible

Uncommited Read (en franais, Lecture de donnes non valides ) Possible

Possible

Possible

Commited Read (en franais, Lecture de donnes valides )

Possible

Possible

262

Impossible

Contrle d'accs simultan

Niveau d'isolation

Lecture sale

Lecture non re- Lecture fantme


productible

Repeatable Read (en franais, Lecture rpte )

Impossible

Impossible

Possible

Serializable (en franais, Srialisable )

Impossible

Impossible

Impossible

Dans PostgreSQL, vous pouvez demander un des quatre niveaux standards d'isolation de transaction. Mais, en interne, il existe
seulement trois niveaux distincts d'isolation, qui correspondent aux niveaux Read Committed et Repeatable Read, and Serializable. Lorsque vous slectionnez le niveau Read Uncommitted, vous obtenez rellement Read Committed, et les lectures fantmes
ne sont pas possibles dans l'implmentation PostgreSQL de Repeatable Read. Le niveau d'isolation actuel pourrait donc tre
plus strict que ce que vous slectionnez. Ceci est permis par le standard SQL. Les quatre niveaux d'isolation dfinissent seulement
quel phnomne ne doit pas survenir, ils ne dfinissent pas ce qui doit arriver. La raison pour laquelle PostgreSQL fournit seulement trois niveaux d'isolation est qu'il s'agit de la seule faon raisonnable de faire correspondre les niveaux d'isolation standards
avec l'architecture de contrle des accs simultans multiversion. Le comportement des niveaux standards d'isolation est dtaill
dans les sous-sections suivantes.
Pour initialiser le niveau d'isolation d'une transaction, utilisez la commande SET TRANSACTION(7).

13.2.1. Niveau d'isolation Read committed (lecture uniquement des donnes valides)
Read Committed est le niveau d'isolation par dfaut dans PostgreSQL. Quand une transaction utilise ce niveau d'isolation, une
requte SELECT (sans clause FOR UPDATE/SHARE) voit seulement les donnes valides avant le dbut de la requte ; il ne
voit jamais les donnes non valides et les modifications valides pendant l'excution de la requte par des transactions excutes
en parallle. En effet, une requte SELECT voit une image de la base de donnes datant du moment o l'excution de la requte
commence. Nanmoins, SELECT voit les effets de mises jour prcdentes excutes dans sa propre transaction, mme si cellesci n'ont pas encore t valides. De plus, notez que deux commandes SELECT successives peuvent voir des donnes diffrentes,
mme si elles sont excutes dans la mme transaction si d'autres transactions valident des modifications pendant l'excution du
premier SELECT.
Les commandes UPDATE, DELETE, SELECT FOR UPDATE et SELECT FOR SHARE se comportent de la mme faon
que SELECT en ce qui concerne la recherche des lignes cibles : elles ne trouveront que les lignes cibles qui ont t valides avant
le dbut de la commande. Nanmoins, une telle ligne cible pourrait avoir dj t mise jour (ou supprime ou verrouille) par
une autre transaction concurrente au moment o elle est dcouverte. Dans ce cas, le processus de mise jour attendra que la premire transaction soit valide ou annule (si elle est toujours en cours). Si la premire mise jour est annule, alors ses effets sont
nis et le deuxime processus peut excuter la mise jour des lignes originellement trouves. Si la premire mise jour est valide, la deuxime mise jour ignorera la ligne si la premire mise jour l'a supprime, sinon elle essaiera d'appliquer son opration
la version mise jour de la ligne. La condition de la recherche de la commande (la clause WHERE) est r-value pour savoir si
la version mise jour de la ligne correspond toujours la condition de recherche. Dans ce cas, la deuxime mise jour continue
son opration en utilisant la version mise jour de la ligne. Dans le cas des commandes SELECT FOR UPDATE et SELECT
FOR SHARE, cela signifie que la version mise jour de la ligne est verrouille et renvoye au client.
cause de la rgle ci-dessus, une commande de mise jour a la possibilit de voir une image non cohrente : elle peut voir les effets de commandes de mises jour concurrentes sur les mmes lignes que celles qu'elle essaie de mettre jour mais elle ne voit
pas les effets de ces commandes sur les autres lignes de la base de donnes. Ce comportement rend le mode de lecture valide non
convenable pour les commandes qui impliquent des conditions de recherche complexes ; nanmoins, il est intressant pour les cas
simples. Par exemple, considrons la mise jour de balances de banque avec des transactions comme :
BEGIN;
UPDATE comptes SET balance = balance + 100.00 WHERE no_compte = 12345;
UPDATE comptes SET balance = balance - 100.00 WHERE no_compte = 7534;
COMMIT;
Si deux transactions comme celle-ci essaient de modifier en mme temps la balance du compte 12345, nous voulons clairement
que la deuxime transaction commence partir de la version mise jour de la ligne du compte. Comme chaque commande
n'affecte qu'une ligne prdtermine, la laisser voir la version mise jour de la ligne ne cre pas de soucis de cohrence.
Des utilisations plus complexes peuvent produire des rsultats non dsirs dans le mode Read Committed. Par exemple, considrez une commande DELETE oprant sur des donnes qui sont la fois ajoutes et supprimes du critre de restriction par une
autre commande. Supposons que website est une table sur deux lignes avec website.hits valant 9 et 10 :
BEGIN;
UPDATE website SET hits = hits + 1;
-- excut par une autre session : DELETE FROM website WHERE hits = 10;
COMMIT;
263

Contrle d'accs simultan

La commande DELETE n'aura pas d'effet mme s'il existe une ligne website.hits = 10 avant et aprs la commande UPDATE. Cela survient parce que la valeur 9 de la ligne avant mise jour est ignore et que lorsque l'UPDATE termine et que DELETE obtient un verrou, la nouvelle valeur de la ligne n'est plus 10, mais 11, ce qui ne correspond plus au critre.
Comme le mode Read Committed commence chaque commande avec une nouvelle image qui inclut toutes les transactions valides jusqu' cet instant, les commandes suivantes dans la mme transaction verront les effets de la transaction valide en parallle
dans tous les cas. Le problme en question est de savoir si une seule commande voit une vue absolument cohrente ou non de la
base de donnes.
L'isolation partielle des transactions fournie par le mode Read Committed est adquate pour de nombreuses applications, et ce
mode est rapide et simple utiliser. Nanmoins, il n'est pas suffisant dans tous les cas. Les applications qui excutent des requtes
et des mises jour complexes pourraient avoir besoin d'une vue plus rigoureusement cohrente de la base de donnes, une vue que
le mode Read Committed ne fournit pas.

13.2.2. Repeatable Read Isolation Level


Le niveau d'isolation Repeatable Read ne voit que les donnes valides avant que la transaction ait dmarr; il ne voit jamais ni les
donnes non valides, ni les donnes valides par des transactions concurrentes durant son excution. (Toutefois, la requte voit
les effets de mises jour prcdentes effectues dans sa propre transaction, bien qu'elles ne soient pas encore valides). C'est une
garantie plus leve que requise par le standard SQL pour ce niveau d'isolation, et elle vite le phnomne dcrit dans Tableau 13.1, Niveaux d'isolation des transactions du standard SQL . Comme mentionn plus haut, c'est permis par le standard,
qui ne dfinit que la protection minimale que chaque niveau d'isolation doit fournir.
Ce niveau est diffrent de Read Committed parce qu'une requte dans une transaction repeatable read voit un instantan au dbut
de la transaction, et non pas du dbut de la requte en cours l'intrieur de la transaction. Du coup, les commandes SELECT successives l'intrieur d'une seule transaction voient toujours les mmes donnes, c'est--dire qu'elles ne voient jamais les modifications faites par les autres transactions qui ont valid aprs le dbut de leur propre transaction.
Les applications utilisant ce niveau d'isolation doivent tre prpares retenter des transactions cause d'checs de srialisation.
Les commandes UPDATE, DELETE, SELECT FOR UPDATE et SELECT FOR SHARE se comportent de la mme faon
que SELECT en ce qui concerne la recherche de lignes cibles : elles trouveront seulement les lignes cibles qui ont t valides
avant le dbut de la transaction. Nanmoins, une telle ligne cible pourrait avoir t mise jour (ou supprime ou verrouille) par
une autre transaction concurrente au moment o elle est utilise. Dans ce cas, la transaction repeatable read attendra que la premire transaction de mise jour soit valide ou annule (si celle-ci est toujours en cours). Si la premire mise jour est annule,
les effets sont inverss et la transaction repeatable read peut continuer avec la mise jour de la ligne trouve l'origine. Mais si la
mise jour est valide (et que la ligne est mise jour ou supprime, pas simplement verrouille), alors la transaction repeatable
read sera annule avec le message
ERROR:

could not serialize access due to concurrent update

parce qu'une transaction srialisable ne peut pas modifier ou verrouiller les lignes changes par d'autres transactions aprs que la
transaction srialisable ait commenc.
Quand une application reoit ce message d'erreurs, elle devrait annuler la transaction actuelle et r-essayer la transaction complte.
La seconde fois, la transaction voit les modifications dj valides comme faisant partie de sa vue initiale de la base de donnes,
donc il n'y a pas de conflit logique en utilisant la nouvelle version de la ligne comme point de dpart pour la mise jour de la nouvelle transaction.
Notez que seules les transactions de modifications ont besoin d'tre tentes de nouveau ; les transactions en lecture seule n'auront
jamais de conflits de srialisation.
Le mode Repeatable Repeatable fournit une garantie rigoureuse que chaque transaction voit un tat compltement stable de la base
de donnes. Toutefois cette vue ne sera pas ncessairement toujours cohrente avec l'excution srielle (un la fois) de transactions concurrentes du mme niveau d'isolation. Par exemple, mme une transaction en lecture seule ce niveau pourrait voire un
enregistrement de contrle mis jour pour indiquer qu'un traitement par lot a t termin mais ne pas voir un des enregistrements
de dtail qui est une partie logique du traitement par lot parce qu'il a lu une ancienne version de l'enregistrement de contrle.
L'implmentation correcte de rgles de gestion par des transactions s'excutant ce niveau d'isolation risque de ne pas marcher
correctement sans une utilisation prudente de verrouillages explicites qui bloquent les transactions en conflits.
Avant la version 9.1 de PostgreSQL, une demande d'isolation de transaction Serializable fournissait exactement le comportement dcrit ici. Pour maintenir l'ancien niveau Serializable, il faudra maintenant demander Repeatable Read.

13.2.3. Niveau d'Isolation Serializable


Le niveau d'isolation Serializable fournit le niveau d'isolation le plus strict. Ce niveau mule l'excution srielle de transaction,
comme si les transactions avaient t excutes les unes aprs les autres, squentiellement, plutt que simultanment. Toutefois,
264

Contrle d'accs simultan

comme pour le niveau Repeatable Read, les applications utilisant ce niveau d'isolation doivent tre prtes rpter leurs transactions en cas d'chec de srialisation. En fait, ce niveau d'isolation fonctionne exactement comme Repeatable Read, except qu'il
surveille les conditions qui pourraient amener l'excution d'un jeu de transactions concurrentes se comporter d'une manire incomptible avec les excutions srielles (une la fois) de toutes ces transactions. Cette surveillance n'introduit aucun blocage supplmentaire par rapport repeatable read, mais il y a un cot cette surveillance, et la dtection des conditions pouvant amener
une anomalie de srialisation dclenchera un chec de srialisation.
Comme exemple, considrez la table ma_table, contenant initialement
classe | valeur
--------+------1 |
10
1 |
20
2 |
100
2 |
200
Supposons que la transaction srialisable A traite
SELECT SUM(valeur) FROM ma_table WHERE classe = 1;
puis insre le rsultat (30) comme valeur dans une nouvelle ligne avec classe = 2. Simultanment, la transaction serialisable
B traite
SELECT SUM(valeur) FROM ma_table WHERE classe = 2;
et obtient le rsultat 300, qu'il insre dans une nouvelle ligne avec classe = 1. ce moment l les deux transactions essayent
de valider. Si l'une des transactions fonctionnait au niveau d'isolation Repeatable Read, les deux seraient autorises valider; mais
puisqu'il n'y a pas d'ordre d'excution sriel cohrent avec le rsultat, l'utilisation de transactions Serializable permettra une des
deux transactions de valider, et annulera l'autre avec ce message:
ERREUR:

n'a pas pu srialiser un accs cause d'une mise jour en parallle"

C'est parce que si A a t excut avant B, B aurait trouv la somme 330, et non pas 300. De faon similaire, l'autre ordre aurait eu
comme rsultat une somme diffrente pour le calcul par A.
Pour garantir une vraie srialisation PostgreSQL utilise le verrouillage de prdicats, ce qui signifie qu'il conserve des verrous
qui permettent de dterminer quand une criture aurait eu un impact sur le rsultat d'une lecture antrieure par une transaction
concurrente, si elle s'tait excute d'abord. Dans PostgreSQL, ces verrous ne causent pas de blocage et ne peuvent donc pas
jouer un rle dans l'avnement d'un verrou mortel (deadlock). Ils sont utiliss pour identifier et marquer les dpendances entre des
transactions srialisables concurrentes qui dans certaines combinaisons peuvent entrainer des anomalies de srialisation. Par
contraste, une transaction Read Committed ou Repeatable Read qui voudrait garantir la cohrence des donnes devra prendre un
verrou sur la table entire, ce qui pourrait bloquer d'autres utilisateurs voulant utiliser cette table, ou pourrait utiliser SELECT
FOR UPDATE ou SELECT FOR SELECT qui non seulement peut bloquer d'autres transactions, mais entrane un accs au
disque.
Les verrous de prdicats dans PostgreSQL, comme dans la plupart des autres systmes de bases de donnes, s'appuient sur les
donnes rellement accdes par une transaction. Ils seront visibles dans la vue systme pg_locks avec un mode de SIReadLock. Les verrous acquis pendant l'excution d'une requte dpendront du plan utilis par la requte, et plusieurs verrous fins (par
exemple, des verrous d'enregistrement) pourraient tre combins en verrous plus grossiers (par exemple, des verrous de page) pendant le droulement de la transaction afin d'viter d'puiser la mmoire utilise pour suivre les verrous. Une transaction READ
ONLY pourra librer ses verrous SIRead avant sa fin, si elle dtecte qu'aucun conflit ne peut encore se produire pouvant potentiellement entrainer une anomalie de srialisation. En fait, les transaction READ ONLY seront souvent capable d'tablir ce fait au moment de leur dmarrage, et ainsi viter de prendre des verrous de prdicat. Si vous demandez explicitement une transaction SERIALIZABLE READ ONLY DEFERRABLE, elle bloquera jusqu' ce qu'elle puisse tablir ce fait. (C'est le seul cas o_une transaction Serializable bloque mais pas une transaction Repeatable Read.) D'autre part, les verrous SIRead doivent souvent tre gards aprs la fin d'une transaction, jusqu' ce que toutes les lectures-critures s'tant droules simultanment soient termines.
L'utilisation systmatique de transactions Serializable peut simplifier le dveloppement. La garantie que n'importe quel jeu de
transactions concurrentes aura le mme effet que si elles s'excutent une seule la fois signifie que si vous pouvez dmontrer
qu'une transaction seule, comme elle est crite, effectuera ce qui est attendu quand elle est excute seule, vous pouvez tre sr
qu'elle effectuera ce qui est attendu quelques soient les autres transactions serializable qui s'excutent en mme temps, mme sans
aucune information sur ce que ces autres transactions pourraient faire. Il est important qu'un environnement qui utilise cette technique ait une faon gnralise de traiter les erreurs de srialisation (qui retournent toujours un SQLSTATE valant '40001'), parce
qu'il sera trs difficile de prdire exactement quelles transactions pourraient contribuer des dpendances lecture/criture et auront
besoin d'tre annules pour viter les anomalies de srialisation. La surveillance des dpendances lecture/criture a un cot, tout
comme l'chec, mais mis en face du cot et du blocage entrains par les verrous explicites et SELECT FOR UPDATE ou SELECT FOR SHARE, les transactions serializable sont le meilleur choix en termes de performances pour certains environnements.
Pour une performance optimale quand on s'appuie sur les transactions Serializable pour le contrle de la concurrence, ces points
265

Contrle d'accs simultan

doivent tre pris en considration:

Dclarer les transactions comme READ ONLY quand c'est possible.

Contrler le nombre de connexions actives, en utilisant un pool de connexions si ncessaire. C'est toujours un point important
pour les performances, mais cela peut tre particulirement important pour un systme charg qui utilise des transactions Serializable.

Ne mettez jamais plus dans une transaction seule qu'il n'est ncessaire dans un but d'intgrit.

Ne laissez pas des connexions trainer en idle in transaction plus longtemps que ncessaire.

Supprimez les verrous explicites, SELECT FOR UPDATE, et SELECT FOR SHARE qui ne sont plus ncessaires grce aux
protections fournies automatiquement par les transactions Serializable.

Quand le systme est forc combiner plusieurs verrous de prdicat au niveau page en un seul verrou de prdicat au niveau relation (si la table des verrous de prdicat est court de mmoire), une augmentation du taux d'checs de srialisation peut survenir. Vous pouvez viter ceci en augmentant max_pred_locks_per_transaction.

Un parcours squentiel ncessitera toujours un verrou de prdicat au niveau relation. Ceci peut rsulter en un taux plus important d'checs de srialisation. Il peut tre utile d'encourager l'utilisation de parcours d'index en diminuant random_page_cost
et/ou en augmentant cpu_tuple_cost. Assurez-vous de bien mesurer toute diminution du nombre d'annulation de transactions et
restarts against any overall change in query execution time.

Avertissement
Le support pour le niveau d'isolation Serializable n'a pas encore t ajout aux cibles de rplication Hot Standby
(dcrites dans Section 25.5, Hot Standby ). Bien que les critures permanentes dans la base effectues dans des
transactions Serializable sur le matre garantiront que toutes les standbys atteindront un tat cohrent, une transaction Repeatable Read sur la standby pourra quelquefois voir un tat transitoire qui sera incohrent avec une excution srielle sur le matre.

13.3. Verrouillage explicite


PostgreSQL fournit de nombreux modes de verrous pour contrler les accs simultans aux donnes des tables. Ces modes
peuvent tre utiliss pour contrler le verrouillage par l'application dans des situations o MVCC n'a pas le comportement dsir.
De plus, la plupart des commandes PostgreSQL acquirent automatiquement des verrous avec les modes appropris pour
s'assurer que les tables rfrences ne sont pas supprimes ou modifies de faon incompatible lorsque la commande s'excute
(par exemple, TRUNCATE ne peut pas tre excut de faon sr en mme temps que d'autres oprations sur la mme table, donc
il obtient un verrou exclusif sur la table pour s'assurer d'une bonne excution).
Pour examiner une liste des verrous en cours, utilisez la vue systme pg_locks. Pour plus d'informations sur la surveillance du statut du sous-systme de gestion des verrous, rfrez-vous au Chapitre 27, Surveiller l'activit de la base de donnes.

13.3.1. Verrous de niveau table


La liste ci-dessous affiche les modes de verrous disponibles et les contextes dans lesquels ils sont automatiquement utiliss par
PostgreSQL. Vous pouvez aussi acqurir explicitement n'importe lequel de ces verrous avec la commande LOCK(7). Rappelezvous que tous ces modes de verrous sont des verrous au niveau table, mme si le nom contient le mot row (NdT : ligne) ; les
noms des modes de verrous sont historiques. Dans une certaine mesure, les noms refltent l'utilisation typique de chaque mode de
verrou -- mais la smantique est identique. La seule vraie diffrence entre un mode verrou et un autre est l'ensemble des modes
verrous avec lesquels ils rentrent en conflit (voir Tableau 13.2, Modes de verrou conflictuels ). Deux transactions ne peuvent
pas conserver des verrous de modes en conflit sur la mme table au mme moment (nanmoins, une transaction n'entre jamais en
conflit avec elle-mme. Par exemple, elle pourrait acqurir un verrou ACCESS EXCLUSIVE et acqurir plus tard un verrou ACCESS SHARE sur la mme table). Des modes de verrou sans conflit peuvent tre dtenus en mme temps par plusieurs transactions. Notez, en particulier, que certains modes de verrous sont en conflit avec eux-mme (par exemple, un verrou ACCESS EXCLUSIVE ne peut pas tre dtenu par plus d'une transaction la fois) alors que d'autres n'entrent pas en conflit avec eux-mme
(par exemple, un verrou ACCESS SHARE peut tre dtenu par plusieurs transactions).
Modes de verrous au niveau table

ACCESS SHARE
En conflit avec le mode verrou ACCESS EXCLUSIVE.

266

Contrle d'accs simultan

Les commandes SELECT acquirent un verrou de ce mode avec les tables rfrences. En gnral, tout requte lisant seulement une table et ne la modifiant pas obtient ce mode de verrou.
ROW SHARE
En conflit avec les modes de verrous EXCLUSIVE et ACCESS EXCLUSIVE.
La commande SELECT FOR UPDATE et SELECT FOR SHARE acquirent un verrou de ce mode avec la table cible (en
plus des verrous ACCESS SHARE des autres tables rfrences mais pas slectionnes FOR UPDATE/FOR SHARE).
ROW EXCLUSIVE
En conflit avec les modes de verrous SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE et ACCESS EXCLUSIVE.
Les commandes UPDATE, DELETE et INSERT acquirent ce mode de verrou sur la table cible (en plus des verrous ACCESS SHARE sur toutes les autres tables rfrences). En gnral, ce mode de verrouillage sera acquis par toute commande
modifiant des donnes de la table.
SHARE UPDATE EXCLUSIVE
En conflit avec les modes de verrous SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE et
ACCESS EXCLUSIVE. Ce mode protge une table contre les modifications simultanes de schma et l'excution d'un VACUUM.
Acquis par VACUUM (sans FULL), ANALYZE, CREATE INDEX CONCURRENTLY, and some forms of ALTER
TABLE.
SHARE
En conflit avec les modes de verrous ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE,
EXCLUSIVE et ACCESS EXCLUSIVE. Ce mode protge une table contre les modifications simultanes des donnes.
Acquis par CREATE INDEX (sans CONCURRENTLY).
SHARE ROW EXCLUSIVE
En conflit avec les modes de verrous ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE et ACCESS EXCLUSIVE. Ce mode protge une table contre les modifications concurrentes de donnes,
et est en conflit avec elle-mme, afin qu'une seule session puisse le possder un moment donn.
Ce mode de verrouillage n'est pas acquis automatiquement par une commande PostgreSQL.
EXCLUSIVE
En conflit avec les modes de verrous ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE
ROW EXCLUSIVE, EXCLUSIVE et ACCESS EXCLUSIVE. Ce mode autorise uniquement les verrous ACCESS SHARE
concurrents, c'est--dire que seules les lectures partir de la table peuvent tre effectues en parallle avec une transaction
contenant ce mode de verrouillage.
Ce mode de verrouillage n'est acquis automatiquement sur des tables par aucune commande PostgreSQL.
ACCESS EXCLUSIVE
Entre en conflit avec tous les modes (ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE,
SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE et ACCESS EXCLUSIVE). Ce mode garantit que le dtenteur est la
seule transaction accder la table de quelque faon que ce soit.
Acquis par les commandes ALTER TABLE, DROP TABLE, TRUNCATE, REINDEX, CLUSTER et VACUUM FULL.
C'est aussi le mode de verrou par dfaut des instructions LOCK TABLE qui ne spcifient pas explicitement de mode de verrouillage.

Astuce
Seul un verrou ACCESS EXCLUSIVE bloque une instruction SELECT (sans FOR UPDATE/SHARE).
Une fois acquis, un verrou est normalement dtenu jusqu' la fin de la transaction. Mais si un verrou est acquis aprs
l'tablissement d'un point de sauvegarde, le verrou est relch immdiatement si le point de sauvegarde est annul. Ceci est cohrent avec le principe du ROLLBACK annulant tous les effets des commandes depuis le dernier point de sauvegarde. Il se passe la
mme chose pour les verrous acquis l'intrieur d'un bloc d'exception PL/pgSQL : un chappement d'erreur partir du bloc lche
les verrous acquis dans le bloc.
Tableau 13.2. Modes de verrou conflictuels

267

Contrle d'accs simultan

Verrou de- Verrou dj dtenu


mand
ACCESS
ROW
SHARE
SHARE

ROW EX- SHARE UP- SHARE


CLUSIVE DATE EXCLUSIVE

SHARE
EXCLUROW EX- SIVE
CLUSIVE

ACCESS
SHARE

ACCESS
EXCLUSIVE
X

ROW
SHARE
ROW EXCLUSIVE
SHARE UPDATE EXCLUSIVE

SHARE

SHARE
ROW EXCLUSIVE

EXCLUSIVE
ACCESS
EXCLUSIVE

13.3.2. Verrous au niveau ligne


En plus des verrous au niveau table, il existe des verrous au niveau ligne, qui peuvent tre des verrous exclusifs ou partags. Un
verrou exclusif sur une ligne spcifique est automatiquement acquis lorsque la ligne est mise jour ou supprime. Le verrou est
dtenu jusqu' la fin de la transaction, que ce soit une validation ou une annulation, de la mme faon que les verrous de niveau
table. Les verrous au niveau ligne n'affectent pas les requtes sur les donnes ; ils bloquent seulement les modifieurs d'une mme
ligne.
Pour acqurir un verrou exclusif au niveau ligne sans modifier rellement la ligne, slectionnez la ligne avec SELECT FOR UPDATE. Notez qu'une fois le verrou au niveau ligne acquis, la transaction pourrait mettre jour la ligne plusieurs fois sans peur des
conflits.
Pour acqurir un verrou partag niveau ligne sur une ligne spcifique, slectionnez la ligne avec SELECT FOR SHARE. Un verrou partag n'empche pas les autres transactions d'obtenir le mme verrou partag. Nanmoins, aucune transaction n'est autorise
mettre jour, supprimer ou verrouiller exclusivement une ligne dont une autre transaction a obtenu un verrou partag. Toute tentative de le faire bloque tant que les verrous partags n'ont pas t enlevs.
PostgreSQL ne garde en mmoire aucune information sur les lignes modifies, il n'y a donc aucune limite sur le nombre de
lignes verrouilles un moment donn. Nanmoins, verrouiller une ligne peut causer une criture disque ; ainsi, par exemple, SELECT FOR UPDATE modifie les lignes slectionnes pour les marquer verrouilles et cela aboutit des critures disques.
En plus des verrous tables et lignes, les verrous partags/exclusifs sur les pages sont utiliss pour contrler la lecture et l'criture
des pages de table dans l'ensemble des tampons partages. Ces verrous sont immdiatement relchs une fois la ligne rcupre ou
mise jour. Les dveloppeurs d'applications ne sont normalement pas concerns par les verrous au niveau page mais nous les
mentionnons dans un souci d'exhaustivit.

13.3.3. Verrous morts (blocage)


L'utilisation de verrous explicites accrot le risque de verrous morts lorsque deux transactions (voire plus) dtiennent chacune un
verrou que l'autre convoite. Par exemple, si la transaction 1 a acquis un verrou exclusif sur la table A puis essaie d'acqurir un verrou exclusif sur la table B alors que la transaction 2 possde dj un verrou exclusif sur la table B et souhaite maintenant un verrou
exclusif sur la table A, alors aucun des deux ne peut continuer. PostgreSQL dtecte automatiquement ces situations de blocage
et les rsout en annulant une des transactions impliques, permettant ainsi l'autre (aux autres) de se terminer (quelle est exactement la transaction annule est difficile prvoir mais vous ne devriez pas vous en proccuper).
Notez que les verrous morts peuvent aussi se produire en consquence des verrous de niveau ligne (et du coup, ils peuvent se
produire mme si le verrouillage explicite n'est pas utilis). Considrons le cas o il existe deux transactions concurrentes modifiant une table. La premire transaction excute :
268

Contrle d'accs simultan

UPDATE comptes SET balance = balance + 100.00 WHERE no_compte = 11111;


Elle acquiert un verrou au niveau ligne sur la ligne spcifie par le numro de compte (no_compte). Ensuite, la deuxime transaction excute :
UPDATE comptes SET balance = balance + 100.00 WHERE no_compte = 22222;
UPDATE comptes SET balance = balance - 100.00 WHERE no_compte = 11111;
La premire instruction UPDATE acquiert avec succs un verrou au niveau ligne sur la ligne spcifie, donc elle russit mettre
jour la ligne. Nanmoins, la deuxime instruction UPDATE trouve que la ligne qu'elle essaie de mettre jour a dj t verrouille, alors elle attend la fin de la transaction ayant acquis le verrou. Maintenant, la premire transaction excute :
UPDATE comptes SET balance = balance - 100.00 WHERE no_compte = 22222;
La premire transaction essaie d'acqurir un verrou au niveau ligne sur la ligne spcifie mais ne le peut pas : la deuxime transaction dtient dj un verrou. Donc, elle attend la fin de la transaction deux. Du coup, la premire transaction est bloque par la
deuxime et la deuxime est bloque par la premire : une condition de blocage, un verrou mort. PostgreSQL dtectera cette situation et annulera une des transactions.
La meilleure dfense contre les verrous morts est gnralement de les viter en s'assurant que toutes les applications utilisant une
base de donnes acquirent des verrous sur des objets multiples dans un ordre cohrent. Dans l'exemple ci-dessus, si les deux transactions avaient mis jour les lignes dans le mme ordre, aucun blocage n'aurait eu lieu. Vous devez vous assurer que le premier
verrou acquis sur un objet dans une transaction est dans le mode le plus restrictif pour cet objet. S'il n'est pas possible de vrifier
ceci l'avance, alors les blocages doivent tre grs l'excution en r-essayant les transactions annules cause de blocage.
Tant qu'aucune situation de blocage n'est dtecte, une transaction cherchant soit un verrou de niveau table soit un verrou de niveau ligne attend indfiniment que les verrous en conflit soient relchs. Ceci signifie que maintenir des transactions ouvertes sur
une longue priode de temps (par exemple en attendant une saisie de l'utilisateur) est parfois une mauvaise ide.

13.3.4. Verrous informatifs


PostgreSQL fournit un moyen pour crer des verrous qui ont une signification dfinie par l'application. Ils sont qualifis d'informatifs car le systme ne force pas leur utilisation -- c'est l'application de les utiliser correctement. Les verrous informatifs
peuvent tre utiles pour des manires d'utiliser le verrouillage qui ne sont pas en phase avec le modle MVCC. Par exemple, une
utilisation habituelle des verrous informations est l'mulation de stratgie de verrouillage pessimiste typique des systmes de gestion de donnes partir de fichiers plat . Bien qu'un drapeau stock dans une table puisse tre utilis pour la mme raison, les
verrous informatifs sont plus rapides, vitent la fragmentation de la table et sont nettoys automatiquement par le serveur la fin
de la session.
Il existe deux faons pour acqurir un verrou informatif dans PostgreSQL : au niveau de la session ou au niveau de la transaction. Une fois acquis au niveau de la session, un verrou information est dtenu jusqu' ce que le verrou soit explicitement relch
ou la fin de la session. Contrairement aux demandes de verrou standard, les demandes de verrous informatifs au niveau session
n'honorent pas la smantique de la transaction : un verrou acquis lors d'une transaction qui est annule plus tard sera toujours acquis aprs le ROLLBACK, et de la mme faon, un verrou relch reste valide mme si la transaction appelante a chou aprs.
Un verrou peut tre acquis plusieurs fois par le processus qui le dtient ; pour chaque demande de verrou termine, il doit y avoir
une demande de relche du verrou correspondant avant que ce dernier ne soit rellement relch. D'un autre ct, les demandes de
verrou au niveau transaction se comportent plutt comme des demandes de verrous standards : les verrous sont automatiquement
relchs la fin de la transaction, et il n'y a pas d'opration explicite de dverrouillage. Ce comportement est souvent plus intressant que le comportement au niveau session pour un usage rapide d'un verrou informatif. Les demandes de verrou au niveau session et transaction pour le mme identifiant de verrou informatif se bloqueront de la faon attendue. Si une session dtient dj un
verrou informatif donn, les demandes supplmentaires par le mme processus russiront toujours, mme si d'autres sessions sont
en attente ; ceci est vrai quelque soit le niveau (session ou transaction) du verrou dtenu et des verrous demands.
Comme tous les verrous dans PostgreSQL, une liste complte des verrous informatifs dtenus actuellement par toute session est
disponible dans la vue systme pg_locks.
Les verrous informatifs et les verrous standards sont stocks dans une partie de la mmoire partage, dont la taille est dfinie par
les variables de configuration max_locks_per_transaction et max_connections. Attention ne pas vider cette mmoire, sinon le
serveur ne serait plus capable d'accorder des verrous. Ceci impose une limite suprieure au nombre de verrous informatifs que le
serveur peut accorder, typiquement entre des dizaines et des centaines de milliers suivant la faon dont le serveur est configur.
Dans certains cas qui utilisent cette mthode, tout spcialement les requtes impliquant un tri explicite et des clauses LIMIT, une
grande attention doit tre porte au contrle des verrous acquis, cause de l'ordre dans lequel les expressions SQL sont values.
Par exemple :
SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- danger !
SELECT pg_advisory_lock(q.id) FROM
(
269

Contrle d'accs simultan

SELECT id FROM foo WHERE id > 12345 LIMIT 100


) q; -- ok
Dans les requtes ci-dessus, la deuxime forme est dangereuse parce qu'il n'est pas garanti que l'application de LIMIT ait lieu
avant que la fonction du verrou soit excute. Ceci pourrait entraner l'acquisition de certains verrous que l'application n'attendait
pas, donc qu'elle ne pourrait, du coup, pas relcher (sauf la fin de la session). Du point de vue de l'application, de tels verrous
sont en attente, bien qu'ils soient visibles dans pg_locks.
Les fonctions fournies pour manipuler les verrous informatifs sont dcrites dans Tableau 9.62, Fonctions de verrous consultatifs .

13.4. Vrification de cohrence des donnes au niveau de


l'application
Il est trs difficile d'implmenter des rgles de gestion sur l'intgrit des donnes en utilisant des transactions Read Committed
parce que la vue des donnes est changeante avec chaque ordre, met mme un seul ordre peut ne pas se cantonner son propre
instantan si un conflit en criture se produit.
Bien qu'une transaction Repeatable Read ait une vue stable des donnes dans toute la dure de son excution, il y a un problme
subtil quand on utilise les instantans MVCC pour vrifier la cohrence des donnes, impliquant quelque chose connu sous le nom
de conflits lecture/criture. Si une transaction crit des donnes et qu'une transaction concurrent essaye de lire la mme donne
(que ce soit avant ou aprs l'criture), elle ne peut pas voir le travail de l'autre transaction. Le lecteur donne donc l'impression de
s'tre excut le premier quel que soit celui qui a commenc le premier ou qui a valid le premier. Si on s'en tient l, ce n'est pas
un problme, mais si le lecteur crit aussi des donnes qui sont lues par une transaction concurrente il y a maintenant une transaction qui semble s'tre excute avant les transactions prcdemment mentionnes. Si la transaction qui semble s'tre excute en
dernier valide en premier, il est trs facile qu'un cycle apparaisse dans l'ordre d'excution des transactions. Quand un cycle de ce
genre apparat, les contrles d'intgrit ne fonctionneront pas correctement sans aide.
Comme mentionn dans Section 13.2.3, Niveau d'Isolation Serializable , les transactions Serializable ne sont que des transactions Repeatable Read qui ajoutent une supervision no-bloquante de formes dangereuses de conflits lecture/criture. Quand une de
ces formes est dtecte qui pourrait entraner un cycle dans l'ordre apparent d'excution, une des transactions impliques est annule pour casser le cycle.

13.4.1. Garantir la Cohrence avec Des Transactions Serializable


Si le niveau d'isolation de transactions Serializable est utilis pour toutes les critures et toutes les lectures qui ont besoin d'une
vue cohrente des donnes, aucun autre effort n'est requis pour garantir la cohrence. Un logiciel d'un autre environnement crit
pour utiliser des transactions serializable pour garantir la cohrence devrait fonctionner sans modification de ce point de vue
dans PostgreSQL.
L'utilisation de cette technique vitera de crer une charge de travail inutile aux dveloppeurs d'applications si le logiciel utilise un
framework qui ressaye le s transactions annules pour chec de srialisation automatiquement. Cela pourrait tre une bonne ide
de positionner default_transaction_isolation serializable. Il serait sage, par ailleurs, de vous assurer
qu'aucun autre niveau d'isolation n'est utilis, soit par inadvertance, soit pour contourner les contrles d'intgrit, en vrifiant les
niveaux d'isolations dans les triggers.
Voyez Section 13.2.3, Niveau d'Isolation Serializable pour des suggestions sur les performances.

Avertissement
Ce niveau de protection de protection de l'intgrit en utilisant des transactions Serializable ne s'tend pour le moment pas jusqu'au mode standby (Section 25.5, Hot Standby ). Pour cette raison, les utilisateurs du hot standby
voudront peut-tre utiliser Repeatable Read et un verrouillage explicite sur le matre.

13.4.2. Garantir la Cohrence avec des Verrous Bloquants Explicites


Quand des critures non-srialisables sont possibles, pour garantir la validit courante d'un enregistrement et le protger contre des
mises jour concurrentes, on doit utiliser SELECT FOR UPDATE, SELECT FOR SHARE, ou un ordre LOCK TABLE appropri. (SELECT FOR UPDATE et SELECT FOR SELECT ne verrouillent que les lignes retournes contre les mises jour
concurrentes, tandis que LOCK TABLE verrouille toute la table.) Cela doit tre pris en considration quand vous portez des applications PostgreSQL partir d'autres environnements.
Il est aussi important de noter pour ceux qui convertissent partir d'autres environnements le fait que SELECT FOR UPDATE
ne garantit pas qu'une transaction concurrente ne mettra pas jour ou n'effacera pas l'enregistrement selectionn. Pour faire cela
270

Contrle d'accs simultan

dans PostgreSQL vous devez rellement modifier l'enregistrement, mme si vous n'avez pas besoin de modifier une valeur. SELECT FOR UPDATE empche temporairement les autres transactions d'acqurir le mme verrou ou d'excuter un UPDATE ou
DELETE qui modifierait l'enregistrement verrouill, mais une fois que la transaction possdant ce verrou valide ou annule, une
transaction bloque pourra continuer avec son opration en conflit sauf si un rel UPDATE de l'enregistement a t effectu pendant que le verrou tait possd.
Les verrifications globales de validit demandent davantage de rflexion sous un MVCC non srialisable. Par exemple, une application bancaire pourrait vouloir vrifier que la somme de tous les crdits d'une table est gale la somme de tous les dbits d'une
autre, alors que les deux tables sont en cours de mise jour. La comparaison des rsultas de deux SELECT sum(...) successifs
ne fonctionnera pas correctement en mode Read Committed, puisque la seconde requte incluera probablement les rsultats de
transactions pas prises en compte dans la premire. Effectuer les deux sommes dans une seule transaction repeatable read donnera
une image prcise des effets d'uniquement les transactions qui ont valid avant le dbut de la transaction repeatable read $mdash;
mais on pourrait lgitimement se demander si la rponse est toujours valide au moment o elle est fournie. Si la transaction repeatable read a elle mme effectu des modifications avant d'effectuer le test de cohrence, l'utilit de la vrification devient encore
plus sujette caution, puisque maintenant elle inclut des modifications depuis le dbut de la transaction, mais pas toutes. Dans ce
genre de cas, une personne prudente pourra vouloir verrouiller toutes les tables ncessaires la vrification, afin d'avoir une vision
incontestable de la ralit courante. Un mode SHARE (ou plus lev) garantit qu'il n'y a pas de changements non valids dans la
table verrouille, autres que ceux de la transaction courante.
Notez aussi que si on se fie au verrouillage explicite pour empcher les mises jour concurrentes, on devrait soit utiliser Read
Committed, soit utiliser Repeatable Read et faire attenion obtenir les verrous avant d'effectuer les requtes. Un verrou obtenu par
une transaction repeatable read guarantit qu'aucune autre transaction modifiant la table n'est en cours d'excution, mais si
l'instantan vu par la transaction est antrieur l'obtention du verrou, il pourrait aussi prcder des modifications maintenant valides dans la table. Un instantan de transaction repeatable read est en fait fig l'excution de sa premire requte ou commande
de modification de donnes (SELECT, INSERT, UPDATE, ou DELETE), il est donc possible d'obtenir les verrous explicitement
avant que l'instantan ne soit fig.

271

Chapitre 14. Conseils sur les performances


La performance des requtes peut tre affecte par un grand nombre d'lments. Certains peuvent tre contrls par l'utilisateur,
d'autres sont fondamentaux au concept sous-jacent du systme. Ce chapitre fournit des conseils sur la comprhension et sur la
configuration fine des performances de PostgreSQL.

14.1. Utiliser EXPLAIN


PostgreSQL ralise un plan de requte pour chaque requte qu'il reoit. Choisir le bon plan correspondant la structure de la
requte et aux proprits des donnes est absolument critique pour de bonnes performances, donc le systme inclut un planificateur complexe qui tente de choisir les bons plans. Vous pouvez utiliser la commande EXPLAIN(7) pour voir quel plan de requte le planificateur cre pour une requte particulire. La lecture du plan est un art qui mrite un tutoriel complet, ce que vous
n'aurez pas l ; ici ne se trouvent que des informations de base.
La structure d'un plan de requte est un arbre de nuds de plan. Les nuds de bas niveau sont les nuds de parcours de tables :
ils renvoient les lignes brutes d'une table. Il existe diffrents types de nuds de parcours pour les diffrentes mthodes d'accs
aux tables : parcours squentiel, parcours d'index et parcours d'index bitmap. Si la requte requiert des jointures, agrgations,
tris ou d'autres oprations sur les lignes brites, ce seront des nuds supplmentaires au-dessus des nuds de parcours pour raliser ces oprations. Encore une fois, il existe plus d'une faon de raliser ces oprations, donc diffrents types de nuds peuvent
aussi apparatre ici. La sortie d'EXPLAIN comprend une ligne pour chaque nud dans l'arbre du plan, montrant le type de
nud basique avec les estimations de cot que le planificateur a fait pour l'excution de ce nud du plan. La premire ligne (le
nud tout en haut) comprend le cot d'excution total estim pour le plan ; c'est ce nombre que le planificateur cherche minimiser.
Voici un exemple trivial, juste pour montrer quoi ressemble l'affichage. 1
EXPLAIN SELECT * FROM tenk1;
QUERY PLAN
------------------------------------------------------------Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
Les nombres donns par EXPLAIN sont (de gauche droite) :

Cot estim du lancement (temps pass avant que l'affichage de la sortie ne commence, c'est--dire pour faire le tri dans un
nud de tri) ;

Cot total estim (si toutes les lignes doivent tre rcupres, ce qui pourrait ne pas tre le cas : par exemple une requte
avec une clause LIMIT ne paiera pas le cot total du nud d'entre du nud du plan Limit) ;

Nombre de lignes estim en sortie par ce nud de plan (encore une fois, seulement si excut jusqu'au bout) ;

Largeur moyenne estime (en octets) des lignes en sortie par ce nud de plan.

Les cots sont mesurs en units arbitraires dtermines par les paramtres de cot du planificateur (voir Section 18.7.2,
Constantes de cot du planificateur ). La pratique habituelle est de mesurer les cots en unit de rcupration de pages
disque ; autrement dit, seq_page_cost est initialis 1.0 par convention et les autres paramtres de cot sont relatifs cette valeur. Les exemples de cette section sont excuts avec les paramtres de cot par dfaut.
Il est important de noter que le cot d'un nud de haut niveau inclut le cot de tous les nuds fils. Il est aussi important de raliser que le cot reflte seulement les lments d'importance pour le planificateur. En particulier, le cot ne considre pas le temps
dpens dans la transmission des lignes de rsultat au client, ce qui pourrait tre un facteur important dans le temps rel pass ;
mais le planificateur l'ignore parce qu'il ne peut pas le changer en modifiant le plan (chaque plan correct sortira le mme ensemble de lignes).
La valeur rows est un peu difficile car il ne s'agit pas du nombre de lignes traites ou parcourues par le plan de nuds. C'est habituellement moins, refltant la slectivit estime des conditions de la clause WHERE qui sont appliques au nud. Idalement,
les estimations des lignes de haut niveau sera une approximation des nombres de lignes dj renvoyes, mises jour, supprimes par la requte.
Pour revenir notre exemple :
EXPLAIN SELECT * FROM tenk1;
1

Les exemples dans cette section sont rcuprs de la base de donnes des tests de rgression aprs avoir lanc un VACUUM ANALYZE, en utilisant les sources de la version 8.2. Vous devriez tre
capable d'obtenir des rsultats similaires si vous essayez vous-mme les exemples mais vos cots estims et les nombres de lignes varieront probablement lgrement car les statistiques d'ANALYZE
se font partir de valeurs prises au hasard.

272

Conseils sur les performances

QUERY PLAN
------------------------------------------------------------Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
C'est aussi direct que ce que nous obtenons. Si vous fates :
SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
vous trouverez que tenk1 a 358 pages disque et 10000 lignes. Le cot estim est calcul avec (nombre de pages lues *
seq_page_cost) + (lignes parcourues * cpu_tuple_cost). Par dfaut, seq_page_cost vaut 1.0 et cpu_tuple_cost vaut 0.01.
Donc le cot estim est de (358 * 1.0) + (10000 * 0.01), soit 458.
Maintenant, modifions la requte originale pour ajouter une condition WHERE :
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 7000;
QUERY PLAN
-----------------------------------------------------------Seq Scan on tenk1 (cost=0.00..483.00 rows=7033 width=244)
Filter: (unique1 < 7000)
Notez que l'affichage d'EXPLAIN montre la clause WHERE applique comme une condition de filtre ; ceci signifie que le
nud de plan vrifie la condition pour chaque ligne qu'il parcourt et ne conserve que celles qui satisfont la condition. L'estimation
des lignes en sortie a baiss cause de la clause WHERE. Nanmoins, le parcours devra toujours visiter les 10000 lignes, donc le
cot n'a pas baiss ; en fait, il a un peu augment (par 10000 * cpu_operator_cost pour tre exact) dans le but de reflter le temps
CPU supplmentaire dpens pour vrifier la condition WHERE.
Le nombre rel de lignes que cette requte slectionnera est 7000 mais l'estimation rows est approximative. Si vous tentez de dupliquer cette exprience, vous obtiendrez probablement une estimation lgrement diffrente ; de plus, elle changera aprs chaque
commande ANALYZE parce que les statistiques produites par ANALYZE sont prises partir d'un extrait au hasard de la table.
Maintenant, rendons la condition plus restrictive :
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100;
QUERY PLAN
-----------------------------------------------------------------------------Bitmap Heap Scan on tenk1 (cost=2.37..232.35 rows=106 width=244)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0)
Index Cond: (unique1 < 100)
Ici, le planificateur a dcid d'utiliser un plan en deux tapes : le nud en bas du plan visite un index pour trouver l'emplacement
des lignes correspondant la condition de l'index, puis le nud du plan du dessus rcupre rellement ces lignes de la table. Rcuprer sparment les lignes est bien plus coteux que de les lire squentiellement mais comme toutes les pages de la table n'ont
pas tre visites, cela revient toujours moins cher qu'un parcours squentiel (la raison de l'utilisation d'un plan deux niveaux est
que le nud du plan du dessus trie les emplacements des lignes identifis par l'index dans l'ordre physique avant de les lire pour
minimiser les cots des rcuprations spars. Le bitmap mentionn dans les noms de nuds est le mcanisme qui s'occupe du
tri).
Si la condition WHERE est assez slective, le planificateur pourrait basculer vers un plan de parcours d'index simple :
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 3;
QUERY PLAN
-----------------------------------------------------------------------------Index Scan using tenk1_unique1 on tenk1 (cost=0.00..10.00 rows=2 width=244)
Index Cond: (unique1 < 3)
Dans ce cas, les lignes de la table sont rcupres dans l'ordre de l'index, ce qui les rend encore plus coteuses lire mais elles
sont si peu nombreuses que le cot supplmentaire de triage des emplacements de lignes ne vaut pas le coup. Vous verrez plus frquemment ce type de plan pour les requtes qui rcuprent une seule ligne et pour les requtes qui ont une condition ORDER BY
correspondant l'ordre de l'index.
Ajoutez une autre condition la clause WHERE :
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 3 AND stringu1 = 'xxx';
QUERY PLAN
------------------------------------------------------------------------------Index Scan using tenk1_unique1 on tenk1 (cost=0.00..10.01 rows=1 width=244)
273

Conseils sur les performances

Index Cond: (unique1 < 3)


Filter: (stringu1 = 'xxx'::name)
La condition ajoute stringu1 = 'xxx' rduit l'estimation du nombre de lignes en sortie mais pas le cot car nous devons
toujours visiter le mme ensemble de lignes. Notez que la clause stringu1 ne peut pas tre appliqu une condition d'index
(car cet index est seulement sur la colonne unique1). la place, il est appliqu comme un filtre sur les lignes rcupres par
l'index. Du coup, le cot a un peu augment pour reflter cette vrification supplmentaire.
S'il existe des index sur plusieurs colonnes rfrences dans la condition WHERE, le planificateur pourrait choisir d'utiliser une
combinaison AND ou OR des index :
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000;
QUERY PLAN
------------------------------------------------------------------------------------Bitmap Heap Scan on tenk1 (cost=11.27..49.11 rows=11 width=244)
Recheck Cond: ((unique1 < 100) AND (unique2 > 9000))
-> BitmapAnd (cost=11.27..11.27 rows=11 width=0)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0)
Index Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique2 (cost=0.00..8.65 rows=1042 width=0)
Index Cond: (unique2 > 9000)
Mais ceci requiert de visiter plusieurs index, donc ce n'est pas ncessaire un gain compar l'utilisation d'un seul index et au traitement de l'autre condition par un filtre. Si vous variez les chelles de valeurs impliques, vous vous apercevrez que le plan
change en accord.
Maintenant, essayons de joindre deux tables, en utilisant les colonnes dont nous avons discut :
EXPLAIN SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;
QUERY PLAN
-------------------------------------------------------------------------------------Nested Loop (cost=2.37..553.11 rows=106 width=488)
-> Bitmap Heap Scan on tenk1 t1 (cost=2.37..232.35 rows=106 width=244)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0)
Index Cond: (unique1 < 100)
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..3.01 rows=1 width=244)
Index Cond: (unique2 = t1.unique2)
Dans cette jointure en boucle imbrique, le parcours externe utilise le mme parcours de bitmap que celui vu prcdemment et
donc son cot et le nombre de lignes sont les mmes parce que nous appliquons la clause WHERE unique1 < 100 ce nud.
La clause t1.unique2 = t2.unique2 n'a pas encore d'intrt donc elle n'affecte pas le nombre de lignes du parcours externe. Pour le parcours interne, la valeur unique2 de la ligne courante du parcours externe est connecte dans le parcours d'index
interne pour produire une condition d'index identique unique2 = constante. Donc, nous obtenons le mme plan de parcours interne et les cots que nous obtenons de, disons, EXPLAIN SELECT * FROM tenk2 WHERE unique2 = 42. Les
cots du nud correspondant la boucle sont ensuite initialiss sur la base du cot du parcours externe, avec une rptition du
parcours interne pour chaque ligne externe (ici, 106 * 3.01), plus un petit temps CPU pour traiter la jointure.
Dans cet exemple, le nombre de lignes en sortie de la jointure est identique aux nombres de lignes des deux parcours mais ce n'est
pas vrai en rgle gnrale car vous pouvez avoir des clauses WHERE mentionnant les deux tables et qui, donc, peuvent seulement
tre appliques au point de jointure, et non pas aux parcours d'index. Par exemple, si nous avions ajout WHERE ... AND
t1.hundred < t2.hundred, cela aurait diminu le nombre de lignes en sortie du nud de jointure mais cela n'aurait pas
chang les parcours d'index.
Une faon de rechercher des plans diffrents est de forcer le planificateur oublier certaines stratgies qu'il aurait trouv moins
coteuses en utilisant les options d'activation (enable)/dsactivation (disable) dcrites dans la Section 18.7.1, Configuration de la
mthode du planificateur (c'est un outil complexe mais utile ; voir aussi la Section 14.3, Contrler le planificateur avec des
clauses JOIN explicites ).
SET enable_nestloop = off;
EXPLAIN SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;
QUERY PLAN
-----------------------------------------------------------------------------------------274

Conseils sur les performances

Hash Join (cost=232.61..741.67 rows=106 width=488)


Hash Cond: (t2.unique2 = t1.unique2)
-> Seq Scan on tenk2 t2 (cost=0.00..458.00 rows=10000 width=244)
-> Hash (cost=232.35..232.35 rows=106 width=244)
-> Bitmap Heap Scan on tenk1 t1 (cost=2.37..232.35 rows=106 width=244)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106
width=0)
Index Cond: (unique1 < 100)
Ce plan propose d'extraire les 100 lignes intressantes de tenk1 en utilisant le mme parcours d'index, de les placer dans une
table de hachage en mmoire puis de faire un parcours squentiel de tenk2, en cherchant dans la table de hachage des correspondances possibles de la ligne t1.unique2 = t2.unique2 pour chaque tenk2. Le cot pour lire tenk1 et pour initialiser la
table de hachage correspond au cot de lancement complet pour la jointure hache car nous n'obtiendrons pas de lignes jusqu'
avoir lu tenk2. Le temps total estim pour la jointure inclut aussi une charge importante du temps CPU pour requter la table de
hachage 10000 fois. Nanmoins, notez que nous ne chargeons pas 10000 fois 232,35 ; la configuration de la table de hachage n'est
excute qu'une fois dans ce type de plan.
Il est possible de vrifier la prcision des cots estims par le planificateur en utilisant EXPLAIN ANALYZE. Cette commande
excute rellement la requte puis affiche le vrai temps d'excution accumul par chaque nud du plan, avec les mmes cots estims que ceux affichs par un simple EXPLAIN. Par exemple, nous pourrions obtenir un rsultat comme celui-ci :
EXPLAIN ANALYZE SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;

QUERY PLAN
-------------------------------------------------------------------------------------------Nested Loop (cost=2.37..553.11 rows=106 width=488) (actual time=1.392..12.700
rows=100 loops=1)
-> Bitmap Heap Scan on tenk1 t1 (cost=2.37..232.35 rows=106 width=244) (actual
time=0.878..2.367 rows=100 loops=1)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0)
(actual time=0.546..0.546 rows=100 loops=1)
Index Cond: (unique1 < 100)
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..3.01 rows=1 width=244)
(actual time=0.067..0.078 rows=1 loops=100)
Index Cond: (unique2 = t1.unique2)
Total runtime: 14.452 ms
Notez que les valeurs temps rel sont en millisecondes alors que les estimations de cot sont exprimes dans des units arbitraires ; donc il y a peu de chances qu'elles correspondent. L'important est de vrifier si les ratios temps rel et cots estims correspondent.
Dans certains plans de requte, il est possible qu'un nud de sous-plan soit excut plus d'une fois. Par exemple, le parcours
d'index interne est excut une fois par ligne externe dans le plan de boucle imbrique ci-dessus. Dans de tels cas, la valeur
loops renvoie le nombre total d'excution du nud, et le temps rel et les valeurs des lignes affiches sont une moyenne par excution. Ceci est fait pour que les nombres soient comparables avec la faon dont les estimations de cots sont affiches. Multipliez
par la valeur de loops pour obtenir le temps total rellement pass dans le nud.
Le Total runtime (temps total d'excution) affich par EXPLAIN ANALYZE inclut les temps de lancement et d'arrt de
l'excuteur, mais pas le temps pass pour l'analyse, la rcriture ou la planification. Pour les commandes INSERT, UPDATE et
DELETE, le temps pass appliquer les modifications est comptabilis sur le nud de haut-niveau Insert, Update ou Delete. (Les
nuds du plan sous ce nud reprsentent le travail de recherche des anciennes lignes et/ou de calcul des anciennes.) Le temps
pass excuter les triggers BEFORE (s'ils sont prsents) est comptabilis dans le nud relatif (Insert, Update ou Delete). Par
contre, ce n'est pas le cas pour les triggers AFTER. Le temps pass dans chaque trigger (BEFORE ou AFTER) est aussi affich sparment et est inclus dans le temps d'excution total. Notez cependant que les triggers de contraintes diffrs ne seront pas excuts avant la fin de la transaction. Du coup, ils ne sont pas affichs par EXPLAIN ANALYZE.
Il existe deux raisons importantes pour lesquelles les temps d'excution mesurs par EXPLAIN ANALYZE peuvent dvier de
l'excution normale de la mme requte. Tout d'abord, comme aucune ligne n'est rellement envoye au client, les cots de transmission rseau et les cots de formatage des entres/sorties ne sont pas inclus. Ensuite, la surcharge gnr par la commande EXPLAIN ANALYZE peut tre importante, tout spcialement sur les machines dont les appels la fonction gettimeofday()
sont particulirement lents.
Il est bon de noter que les rsultats de EXPLAIN ne devraient pas tre extrapols pour des situations autres que celles de vos tests
en cours ; par exemple, les rsultats sur une petite table ne peuvent tre appliqus des tables bien plus importantes. Les estimations de cot du planificateur ne sont pas linaires et, du coup, il pourrait bien choisir un plan diffrent pour une table plus petite
275

Conseils sur les performances

ou plus grande. Un exemple extrme est celui d'une table occupant une page disque. Vous obtiendrez pratiquement toujours un
parcours squentiel que des index soient disponibles ou non. Le planificateur ralise que cela va ncessiter la lecture d'une seule
page disque pour traiter la table dans ce cas, il n'y a donc pas d'intrt tendre des lectures de pages supplmentaires pour un index.

14.2. Statistiques utilises par le planificateur


Comme nous avons vu dans la section prcdente, le planificateur de requtes a besoin d'estimer le nombre de lignes rcupres
par une requte pour faire les bons choix dans ses plans de requtes. Cette section fournit un aperu rapide sur les statistiques que
le systme utilise pour ces estimations.
Un lment des statistiques est le nombre total d'entres dans chaque table et index, ainsi que le nombre de blocs disque occups
par chaque table et index. Cette information est conserve dans la table pg_class sur les colonnes reltuples et relpages.
Nous pouvons la regarder avec des requtes comme celle-ci :
SELECT relname, relkind, reltuples, relpages
FROM pg_class
WHERE relname LIKE 'tenk1%';
relname
| relkind | reltuples | relpages
----------------------+---------+-----------+---------tenk1
| r
|
10000 |
358
tenk1_hundred
| i
|
10000 |
30
tenk1_thous_tenthous | i
|
10000 |
30
tenk1_unique1
| i
|
10000 |
30
tenk1_unique2
| i
|
10000 |
30
(5 rows)
Ici, nous pouvons voir que tenk1 contient 10000 lignes, comme pour ses index, mais que les index sont bien plus petits que la
table (ce qui n'est pas surprenant).
Pour des raisons d'efficacit, reltuples et relpages ne sont pas mis jour en temps rel, et du coup, elles contiennent habituellement des valeurs un peu obsoltes. Elles sont mises jour par les commandes VACUUM, ANALYZE et quelques commandes DDL comme CREATE INDEX. Un ANALYZE seul, donc ne faisant pas partie d'un VACUUM, gnre une valeur approximative de reltuples car il ne lit pas chaque ligne de la table. Le planificateur mettra l'chelle les valeurs qu'il aura trouver dans pg_class pour correspondre la taille physique de la table, obtenant ainsi une approximation plus proche de la ralit.
La plupart des requtes ne rcupre qu'une fraction des lignes dans une table cause de clauses WHERE qui restreignent les lignes
examiner. Du coup, le planificateur a besoin d'une estimation de la slectivit des clauses WHERE, c'est--dire la fraction des
lignes qui correspondent chaque condition de la clause WHERE. L'information utilise pour cette tche est stocke dans le catalogue systme pg_statistic. Les entres de pg_statistic sont mises jour par les commandes ANALYZE et VACUUM ANALYZE et sont toujours approximatives mme si elles ont t mises jour rcemment.
Plutt que de regarder directement dans pg_statistic, il est mieux de visualiser sa vue pg_stats lors de l'examen manuel des statistiques. pg_stats est conu pour tre plus facilement lisible. De plus, pg_stats est lisible par tous alors que pg_statistic n'est lisible
que par un superutilisateur (ceci empche les utilisateurs non privilgis d'apprendre certains choses sur le contenu des tables appartenant d'autres personnes partir des statistiques. La vue pg_stats est restreinte pour afficher seulement les lignes des tables
lisibles par l'utilisateur courant). Par exemple, nous pourrions lancer :
SELECT attname, alled, n_distinct,
array_to_string(most_common_vals, E'\n') as most_common_vals
FROM pg_stats
WHERE tablename = 'road';
attname | alled | n_distinct |
most_common_vals
---------+-----------+------------+-----------------------------------name
| f
| -0.363388 | I- 580
Ramp+
|
|
| I- 880
Ramp+
|
|
| Sp Railroad
+
|
|
| I- 580
+
|
|
| I- 680
Ramp
name
| t
| -0.284859 | I- 880
Ramp+
|
|
| I- 580
Ramp+
|
|
| I- 680
Ramp+
|
|
| I- 580
+
|
|
| State Hwy 13
Ramp
(2 rows)
Notez que deux lignes sont affiches pour la mme colonne, une correspondant la hirarchie d'hritage complte commenant
276

Conseils sur les performances

la table road (alled=t), et une autre incluant seulement la table road elle-mme (alled=f).
Le nombre d'informations stockes dans pg_statistic par ANALYZE, en particulier le nombre maximum d'lments dans les tableaux most_common_vals et histogram_bounds pour chaque colonne, peut tre initialis sur une base colonnepar-colonne en utilisant la commande ALTER TABLE SET STATISTICS ou globalement en initialisant la variable de configuration default_statistics_target. La limite par dfaut est actuellement de cent entres. Augmenter la limite pourrait permettre des
estimations plus prcises du planificateur, en particulier pour les colonnes ayant des distributions de donnes irrgulires, au prix
d'un plus grand espace consomm dans pg_statistic et en un temps plus long pour calculer les estimations. En revanche, une limite
plus basse pourrait tre suffisante pour les colonnes distributions de donnes simples.
Le Chapitre 57, Comment le planificateur utilise les statistiques donne plus de dtails sur l'utilisation des statistiques par le planificateur.

14.3. Contrler le planificateur avec des clauses JOIN explicites


Il est possible de contrler le planificateur de requtes un certain point en utilisant une syntaxe JOIN explicite. Pour voir en quoi
ceci est important, nous avons besoin de quelques connaissances.
Dans une simple requte de jointure, telle que :
SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
le planificateur est libre de joindre les tables donnes dans n'importe quel ordre. Par exemple, il pourrait gnrer un plan de requte qui joint A B en utilisant la condition WHERE a.id = b.id, puis joint C cette nouvelle table jointe en utilisant l'autre
condition WHERE. Ou il pourrait joindre B C, puis A au rsultat de cette jointure prcdente. Ou il pourrait joindre A C puis les
joindre avec B mais cela pourrait ne pas tre efficace car le produit cartsien complet de A et C devra tre form alors qu'il n'y a
pas de condition applicable dans la clause WHERE pour permettre une optimisation de la jointure (toutes les jointures dans
l'excuteur PostgreSQL arrivent entre deux tables en entres donc il est ncessaire de construire le rsultat de l'une ou de l'autre
de ces faons). Le point important est que ces diffrentes possibilits de jointures donnent des rsultats smantiquement quivalents mais pourraient avoir des cots d'excution grandement diffrents. Du coup, le planificateur va toutes les explorer pour trouver le plan de requte le plus efficace.
Quand une requte implique seulement deux ou trois tables, il y a peu d'ordres de jointures prparer. Mais le nombre d'ordres de
jointures possibles grandit de faon exponentielle au fur et mesure que le nombre de tables augmente. Au-del de dix tables en
entre, il n'est plus possible de faire une recherche exhaustive de toutes les possibilits et mme la planification de six ou sept
tables pourrait prendre beaucoup de temps. Quand il y a trop de tables en entre, le planificateur PostgreSQL basculera d'une recherche exhaustive une recherche gntique probabiliste via un nombre limit de possibilits (la limite de bascule est initialise
par le paramtre en excution geqo_threshold). La recherche gntique prend moins de temps mais elle ne trouvera pas ncessairement le meilleur plan possible.
Quand la requte implique des jointures externes, le planificateur est moins libre qu'il ne l'est lors de jointures internes. Par
exemple, considrez :
SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
Bien que les restrictions de cette requte semblent superficiellement similaires l'exemple prcdent, les smantiques sont diffrentes car une ligne doit tre mise pour chaque ligne de A qui n'a pas de ligne correspondante dans la jointure entre B et C. Du
coup, le planificateur n'a pas de choix dans l'ordre de la jointure ici : il doit joindre B C puis joindre A ce rsultat. Du coup,
cette requte prend moins de temps planifier que la requte prcdente. Dans d'autres cas, le planificateur pourrait tre capable
de dterminer que plus d'un ordre de jointure est sr. Par exemple, tant donn :
SELECT * FROM a LEFT JOIN b ON (a.bid = b.id) LEFT JOIN c ON (a.cid = c.id);
il est valide de joindre A soit B soit C en premier. Actuellement, seul un FULL JOIN contraint compltement l'ordre de jointure. La plupart des cas pratiques impliquant un LEFT JOIN ou un RIGHT JOIN peuvent tre arrangs jusqu' un certain degr.
La syntaxe de jointure interne explicite (INNER JOIN, CROSS JOIN ou JOIN) est smantiquement identique lister les relations en entres du FROM, donc il ne contraint pas l'ordre de la jointure.
Mme si la plupart des types de JOIN ne contraignent pas compltement l'ordre de jointure, il est possible d'instruire le planificateur de requte de PostgreSQL pour qu'il traite toutes les clauses JOIN de faon contraindre quand mme l'ordre de jointure.
Par exemple, ces trois requtes sont logiquement quivalentes :
SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
SELECT * FROM a CROSS JOIN b CROSS JOIN c WHERE a.id = b.id AND b.ref = c.id;
SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
Mais si nous disons au planificateur d'honorer l'ordre des JOIN, la deuxime et la troisime prendront moins de temps planifier
que la premire. Cet effet n'est pas inquitant pour seulement trois tables mais cela pourrait bien nous aider avec un nombre im277

Conseils sur les performances

portant de tables.
Pour forcer le planificateur suivre l'ordre de jointure demand par les JOIN explicites, initialisez le paramtre en excution
join_collapse_limit 1 (d'autres valeurs possibles sont discutes plus bas).
Vous n'avez pas besoin de restreindre l'ordre de jointure pour diminuer le temps de recherche car il est bien d'utiliser les oprateurs JOIN dans les lments d'une liste FROM. Par exemple, considrez :
SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;
Avec join_collapse_limit = 1, ceci force le planificateur joindre A B avant de les joindre aux autres tables mais sans
restreindre ses choix. Dans cet exemple, le nombre d'ordres de jointures possibles est rduit par un facteur de cinq.
Restreindre la recherche du planificateur de cette faon est une technique utile pour rduire les temps de planification et pour diriger le planificateur vers un bon plan de requtes. Si le planificateur choisit un mauvais ordre de jointure par dfaut, vous pouvez le
forcer choisir un meilleur ordre via la syntaxe JOIN -- en supposant que vous connaissiez un meilleur ordre. Une exprimentation est recommande.
Un problme trs proche et affectant le temps de planification est le regroupement de sous-requtes dans leurs requtes parents.
Par exemple, considrez :
SELECT *
FROM x, y,
(SELECT * FROM a, b, c WHERE quelquechose) AS ss
WHERE quelquechosedautre;
Cette requte pourrait survenir suite l'utilisation d'une vue contenant une jointure ; la rgle SELECT de la vue sera insre la
place de la rfrence de la vue, demande une requte plutt identique celle ci-dessus. Normalement, le planificateur essaiera de
regrouper la sous-requte avec son parent, donnant :
SELECT * FROM x, y, a, b, c WHERE quelquechose AND quelquechosedautre;
Ceci rsulte habituellement en un meilleur plan que de planifier sparment la sous-requte (par exemple, les conditions WHERE
externes pourraient tre telles que joindre X A limine en premier lieu un bon nombre de lignes de A, vitant ainsi le besoin de
former la sortie complte de la sous-requte). Mais en mme temps, nous avons accru le temps de planification ; ici, nous avons
une problme de jointure cinq tables remplaant un problme de deux jointures spares trois tables. cause de l'augmentation
exponentielle du nombre de possibilits, ceci fait une grande diffrence. Le planificateur essaie d'viter de se retrouver coinc
dans des problmes de recherche de grosses jointures en ne regroupant pas une sous-requte sur plus de
from_collapse_limit lments sont la rsultante de la requte parent. Vous pouvez comparer le temps de planification avec
la qualit du plan en ajustant ce paramtre en excution.
from_collapse_limit et join_collapse_limit sont nomms de faon similaire parce qu'ils font pratiquement la mme chose : l'un
d'eux contrle le moment o le planificateur aplatira les sous-requtes et l'autre contrle s'il y a aplatissement des jointures explicites. Typiquement, vous initialiserez join_collapse_limit comme from_collapse_limit (de faon ce que les
jointures explicites et les sous-requtes agissent de la mme faon) ou vous initialiserez join_collapse_limit 1 (si vous
voulez contrler l'ordre de jointure des jointures explicites). Mais vous pourriez les initialiser diffremment si vous tentez de
configurer finement la relation entre le temps de planification et le temps d'excution.

14.4. Remplir une base de donnes


Vous pourriez avoir besoin d'insrer un grand nombre de donnes pour remplir une base de donnes au tout dbut. Cette section
contient quelques suggestions pour raliser cela de la faon la plus efficace.

14.4.1. Dsactivez la validation automatique (autocommit)


Lors d'INSERT multiples, dsactivez la validation automatique et faites une seule validation la fin (en SQL, ceci signifie de lancer BEGIN au dbut et COMMIT la fin. Quelques bibliothques client pourraient le faire derrire votre dos auquel cas vous devez vous assurer que la bibliothque le fait quand vous le voulez). Si vous permettez chaque insertion d'tre valide sparment,
PostgreSQL fait un gros travail pour chaque ligne ajoute. Un bnfice supplmentaire de raliser toutes les insertions dans une
seule transaction est que si l'insertion d'une ligne choue alors les lignes insres jusqu' maintenant seront annules. Vous ne serez donc pas bloqu avec des donnes partiellement charges.

14.4.2. Utilisez COPY


Utilisez COPY(7) pour charger toutes les lignes en une seule commande, plutt que d'utiliser une srie de commandes INSERT.
La commande COPY est optimise pour charger un grand nombre de lignes ; elle est moins flexible que INSERT mais introduit
significativement moins de surcharge lors du chargement de grosses quantits de donnes. Comme COPY est une seule commande, il n'y a pas besoin de dsactiver la validation automatique (autocommit) si vous utilisez cette mthode pour remplir une
table.
278

Conseils sur les performances

Si vous ne pouvez pas utiliser COPY, utiliser PREPARE(7) pourrait vous aider crer une instruction prpare INSERT, puis
utilisez EXECUTE autant de fois que ncessaire. Ceci vite certaines surcharges lors d'une analyse et d'une planification rptes
de commandes INSERT. Diffrentes interfaces fournissent cette fonctionnalit de plusieurs faons ; recherchez instructions prpares dans la documentation de l'interface.
Notez que charger un grand nombre de lignes en utilisant COPY est pratiquement toujours plus rapide que d'utiliser INSERT,
mme si PREPARE ... INSERT est utilis lorsque de nombreuses insertions sont groupes en une seule transaction.
COPY est plus rapide quand il est utilis dans la mme transaction que la commande CREATE TABLE ou TRUNCATE prcdente. Dans ce cas, les journaux de transactions ne sont pas impacts car, en cas d'erreur, les fichiers contenant les donnes nouvellement charges seront supprims de toute faon. Nanmoins, cette considration ne s'applique que quand wal_level vaut minimal, car toutes les commandes doivent crire dans les journaux de transaction dans ce cas.

14.4.3. Supprimez les index


Si vous chargez une table tout juste cre, la mthode la plus rapide est de crer la table, de charger en lot les donnes de cette
table en utilisant COPY, puis de crer tous les index ncessaires pour la table. Crer un index sur des donnes dj existantes est
plus rapide que de mettre jour de faon incrmentale chaque ligne ajoute.
Si vous ajoutez beaucoup de donnes une table existante, il pourrait tre avantageux de supprimer les index, de charger la table,
puis de recrer les index. Bien sr, les performances de la base de donnes pour les autres utilisateurs pourraient souffrir tout le
temps o les index seront manquant. Vous devez aussi y penser deux fois avant de supprimer des index uniques car la vrification d'erreur apporte par la contrainte unique sera perdue tout le temps o l'index est manquant.

14.4.4. Suppression des contraintes de cls trangres


Comme avec les index, une contrainte de cl trangre peut tre vrifie en gros volume plus efficacement que ligne par ligne.
Donc, il pourrait tre utile de supprimer les contraintes de cls trangres, de charger les donnes et de crer de nouveau les
contraintes. De nouveau, il y a un compromis entre la vitesse de chargement des donnes et la perte de la vrification des erreurs
lorsque la contrainte manque.
What's more, when you load data into a table with existing foreign key constraints, each new row requires an entry in the server's
list of pending trigger events (since it is the firing of a trigger that checks the row's foreign key constraint). Loading many millions
of rows can cause the trigger event queue to overflow available memory, leading to intolerable swapping or even outright failure
of the command. Therefore it may be necessary, not just desirable, to drop and re-apply foreign keys when loading large amounts
of data. If temporarily removing the constraint isn't acceptable, the only other recourse may be to split up the load operation into
smaller transactions.

14.4.5. Augmentez maintenance_work_mem


Augmentez temporairement la variable maintenance_work_mem lors du chargement de grosses quantits de donnes peut amener
une amlioration des performances. Ceci aidera l'acclration des commandes CREATE INDEX et ALTER TABLE ADD
FOREIGN KEY. Cela ne changera pas grand chose pour la commande COPY. Donc, ce conseil est seulement utile quand vous
utilisez une des deux ou les deux techniques ci-dessus.

14.4.6. Augmentez checkpoint_segments


Augmenter temporairement la variable de configuration checkpoint_segments peut aussi aider un chargement rapide de grosses
quantits de donnes. Ceci est d au fait que charger une grosse quantit de donnes dans PostgreSQL causera la venue trop frquente de points de vrification (la frquence de ces points de vrification est spcifie par la variable de configuration checkpoint_timeout). Quand survient un point de vrification, toutes les pages modifies sont crites sur le disque. En augmentant
checkpoint_segments temporairement lors du chargement des donnes, le nombre de points de vrification requis peut tre
diminu.

14.4.7. Dsactiver l'archivage des journaux de transactions et la rplication en


flux
Lors du chargement de grosse quantit de donnes dans une instance qui utilise l'archivage des journaux de transactions ou la rplication en flux, il pourrait tre plus rapide de prendre une nouvelle sauvegarde de base aprs que le chargement ait termin, plutt que de traiter une grosse quantit de donnes incrmentales dans les journaux de transactions. Pour empcher un accroissement
de la journalisation des transactions lors du chargement, vous pouvez dsactiver l'archivage et la rplication en flux lors du chargement en configurant wal_level minimal, archive_mode off et max_wal_senders zro). Mais notez que le changement
de ces paramtres requiert un redmarrage du serveur.
En dehors d'viter le temps de traitement des donnes des journaux de transactions par l'archiveur ou l'metteur des journaux de
279

Conseils sur les performances

transactions, le faire rendrait certaines commandes plus rapides parce qu'elles sont conues pour ne pas crire du tout dans les
journaux de transactions si wal_level vaut minimal. (Elles peuvent garantir la sret des donnes de faon moins coteuse
en excutant un fsync la fin plutt qu'en crivant les journaux de transactions :

CREATE TABLE AS SELECT

CREATE INDEX (et les variantes telles que ALTER TABLE ADD PRIMARY KEY)

ALTER TABLE SET TABLESPACE

CLUSTER

COPY FROM, quand la table cible vient d'tre cre ou vide auparavant dans la transaction

14.4.8. Lancez ANALYZE aprs


Quand vous avez chang significativement la distribution des donnes l'intrieur d'une table, lancer ANALYZE(7) est fortement
recommande. Ceci inclut le chargement de grosses quantits de donnes dans la table. Lancer ANALYZE (ou VACUUM ANALYZE) vous assure que le planificateur dispose de statistiques jour sur la table. Sans statistiques ou avec des statistiques obsoltes, le planificateur pourrait prendre de mauvaises dcisions lors de la planification de la requte, amenant des performances
pauvres sur toutes les tables sans statistiques ou avec des statistiques inexactes. Notez que si le dmon autovacuum est dsactive,
il pourrait excuter ANALYZE automatiquement ; voir Section 23.1.3, Maintenir les statistiques du planificateur et Section 23.1.5, Le dmon auto-vacuum pour plus d'informations.

14.4.9. Quelques notes sur pg_dump


Les scripts de sauvegarde gnrs par pg_dump appliquent automatiquement plusieurs des indications ci-dessus, mais pas toutes.
Pour recharger une sauvegarde pg_dump aussi rapidement que possible, vous avez besoin de faire quelques tapes supplmentaires manuellement (notez que ces points s'appliquent lors de la restauration d'une sauvegarde, et non pas lors de sa cration. Les
mmes points s'appliquent soit lors de la restauration d'une sauvegarde texte avec psql soit lors de l'utilisation de pg_restore pour
charger un fichier de sauvegarde pg_dump).
Par dfaut, pg_dump utilise COPY et, lorsqu'il gnre une sauvegarde complexe, schma et donnes, il est prfrable de charger
les donnes avant de crer les index et les cls trangres. Donc, dans ce cas, plusieurs lignes de conduite sont gres automatiquement. Ce qui vous reste faire est de :

Configurez des valeurs appropries (c'est--dire plus importante que la normale) pour maintenance_work_mem et
checkpoint_segments.

Si vous utilisez l'archivage des journaux de transactions ou la rplication en flux, considrez leur dsactivation lors de la restauration. Pour faire cela, configurez archive_mode off, wal_level minimal et max_wal_senders zro
avant de charger le script de sauvegarde. Aprs coup, remettez les anciennes valeurs et effectuez une nouvelle sauvegarde de
base.

Demandez-vous si la sauvegarde complte doit tre restaure dans une seule transaction. Pour cela, passez l'option -1 ou -single-transaction psql pi pg_restore. Lors de l'utilisation de ce mode, mme les erreurs les plus petites annuleront
la restauration complte, peut-tre en annulant des heures de traitement. Suivant quel point les donnes sont en relation, il
peut tre prfrable de faire un nettoyage manuel. Les commandes COPY s'excuteront plus rapidement si vous utilisez une
transaction simple et que vous avez dsactiv l'archivage des journaux de transaction.

Si plusieurs processeurs sont disponibles sur le serveur, pensez utiliser l'option --jobs de pg_restore. Cela permet la paralllisation du chargement des donnes et de la cration des index.

Excutez ANALYZE aprs coup.

Une sauvegarde des donnes seules utilise toujours COPY mais elle ne supprime ni ne recre les index et elle ne touche gnralement pas les cls trangres. 2 Donc, lorsque vous chargez une sauvegarde ne contenant que les donnes, c'est vous de supprimer
et recrer les index et cls trangres si vous souhaitez utiliser ces techniques. Il est toujours utile d'augmenter checkpoint_segments lors du chargement des donnes mais ne vous embtez pas augmenter maintenance_work_mem ; en
fait, vous le ferez lors d'une nouvelle cration manuelle des index et des cls trangres. Et n'oubliez pas ANALYZE une fois que
vous avez termin ; voir Section 23.1.3, Maintenir les statistiques du planificateur et Section 23.1.5, Le dmon auto-vacuum pour plus d'informations.

Vous pouvez obtenir l'effet de dsactivation des cls trangres en utilisant l'option --disable-triggers -- mais ralisez que cela limine, plutt que repousse, la validation des cls trangres et
qu'il est du coup possible d'insrer des donnes mauvaises si vous l'utilisez.

280

Conseils sur les performances

14.5. Configuration avec une perte accepte


La durabilit est une fonctionnalit des serveurs de bases de donnes permettant de garantir l'enregistrement des transactions valides mme si le serveur s'arrte brutalement, par exemple en cas de coupure lectrique. Nanmoins, la durabilit ajoute une surcharge significative. Si votre base de donnes n'a pas besoin de cette ganratie, PostgreSQL peut tre configur pour fonctionner
bien plus rapidement. Voici des modifications de configuration que vous pouvez faire pour amliorer les performances dans ce
cas. Sauf indication contraire, la durabilit des transactions est garantie dans le cas d'un crash du serveur de bases de donnes ;
seul un arrt brutal du systme d'exploitation cre un risque de perte de donnes ou de corruption quand ses paramtres sont utiliss.

Placer le rpertoire des donnes dans un systme de fichiers en mmoire (par exemple un disque RAM). Ceci limine toutes
les entres/sorties disque de la base de donnes. Cela limite aussi la quantit de mmoire disponible (et peut-tre aussi du
swap).

Dsactiver fsync ; il n'est pas ncessaire d'crire les donnes sur disque.

Dsactiver full_page_writes ; il n'est pas ncessaire de se prmunir contre les critures de pages partielles.

Augmenter checkpoint_segments et checkpoint_timeout ; cela rduit les frquences des CHECKPOINT mais augmente
l'espace disque ncessaire dans pg_xlog.

Dsactiver synchronous_commit ; il n'est pas forcment ncessaire d'crire les journaux de transactions (WAL) chaque validation de transactions. Ce paramtre engendre un risque de perte de transactions (mais pas de corruption de donnes) dans le
cas d'un crash de la base de donnes seule.

281

Partie III. Administration du serveur


Cette partie couvre des thmes de grand intrt pour un administrateur de bases de donnes PostgreSQL, savoir l'installation
du logiciel, la mise en place et la configuration du serveur, la gestion des utilisateurs et des bases de donnes et la maintenance.
Tout administrateur d'un serveur PostgreSQL, mme pour un usage personnel, mais plus particulirement en production, doit
tre familier des sujets abords dans cette partie.
Les informations sont ordonnes de telle sorte qu'un nouvel utilisateur puisse les lire linairement du dbut la fin. Cependant les
chapitres sont indpendants et peuvent tre lus sparment. L'information est prsente dans un style narratif, regroupe en units
thmatiques. Les lecteurs qui recherchent une description complte d'une commande particulire peuvent se rfrer la Partie VI,
Rfrence .
Les premiers chapitres peuvent tre compris sans connaissances pralables. Ainsi, de nouveaux utilisateurs installant leur propre
serveur peuvent commencer leur exploration avec cette partie.
Le reste du chapitre concerne l'optimisation (tuning) et la gestion. Le lecteur doit tre familier avec l'utilisation gnrale du systme de bases de donnes PostgreSQL. Les lecteurs sont encourags regarder la Partie I, Tutoriel et la Partie II, Langage
SQL pour obtenir des informations complmentaires.

Chapitre 15. Procdure d'installation de


PostgreSQL du code source
Ce document chapitre dcrit l'installation de PostgreSQL en utilisant le code source. (Ce document chapitre peut tre ignor
lors de l'installation d'une distribution pr-empaquete, paquet RPM ou Debian, par exemple. Il est alors plus utile de lire les
instruction du mainteneur du paquet.)

15.1. Version courte


./configure
gmake
su
gmake install
adduser postgres
mkdir /usr/local/pgsql/data
chown postgres /usr/local/pgsql/data
su - postgres
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >logfile 2>&1 &
/usr/local/pgsql/bin/createdb test
/usr/local/pgsql/bin/psql test
Le reste du document chapitre est la version longue.

15.2. Prrequis
En gnral, les plateformes style unix modernes sont capables d'excuter PostgreSQL. Les plateformes sur lesquelles des tests
ont t effectus sont listes dans la Section 15.8, Plateformes supportes ci-aprs. Dans le rpertoire doc de la distribution,
il y a plusieurs FAQ spcifiques des plateformes particulires consulter en cas de difficults.
Les logiciels suivants sont ncessaires pour compiler PostgreSQL :

GNU make version 3.80 (ou une version plus rcente) est ncessaire ; les autres programmes make ou les versions plus anciennes de GNU make ne fonctionnent pas. GNU make est souvent install sous le nom gmake ; ce document y fait toujours rfrence sous ce nom (sur certains systme, GNU make est l'outil par dfaut et est nomm make). Pour connatre la
version utilise, saisir
gmake --version

Il est ncessaire d'avoir un compilateur C ISO/ANSI (au minimum compatible avec C89). Une version rcente de GCC est
recommande mais PostgreSQL est connu pour tre compilable avec de nombreux compilateurs de divers vendeurs.

tar est requis pour dballer la distribution des sources, associ gzip ou bzip2.

La bibliothque GNU Readline est utilise par dfaut. Elle permet psql (l'interprteur de ligne de commandes SQL de
PostgreSQL) de se souvenir de chaque commande saisie, et permet d'utiliser les touches de flches pour rappeler et diter les
commandes prcdentes. C'est trs pratique et fortement recommand. Pour ne pas l'utiliser, il faut prciser -without-readline au moment de l'excution de la commande configure. Une alternative possible est l'utilisation
de la bibliothqe libedit sous license BSD, dveloppe au dbut sur NetBSD. La bibliothque libedit est compatible GNU Readline et est utilise si cette dernire n'est pas trouve ou si --with-libedit-preferred est utilis
sur la ligne de commande de configure. Lorsqu'une distribution Linux base de paquets est utilise, si les paquets
readline et readline-devel sont spars, il faut imprativement installer les deux.

La bibliothque de compression zlib est utilise par dfaut. Pour ne pas l'utiliser, il faut prciser --without-zlib
configure. Cela a pour consquence de dsactiver le support des archives compresses dans pg_dump et pg_restore.

Les paquets suivants sont optionnels. S'ils ne sont pas obligatoires lors d'une compilation par dfaut de PostgreSQL, ils le deviennent lorsque certaines options sont utilises, comme cela est expliqu par la suite.

Pour installer le langage procdural PL/Perl, une installation complte de Perl, comprenant la bibliothque libperl et
les fichiers d'en-tte, est ncessaire.
Comme PL/Perl est une bibliothque partage, la bibliothque libperl doit aussi tre partage sur la plupart des plateformes. C'est dsormais le choix par dfaut dans les versions rcentes de Perl, mais ce n'tait pas le cas dans les versions
283

Procdure d'installation de PostgreSQL du


code source
plus anciennes. Dans tous les cas, c'est du ressort de celui qui installe Perl. Si vous avez l'intention d'avoir plus qu'une utilisation occasionnelle de PL/Perl, vous devez vous assurer que l'installation de Perl a t faite avec l'option usemultiplicity active (perl -V vous indiquera si c'est le cas).
Si la bibliothque partage, ncessaire, n'est pas prsente, un message d'avertissement tel que celui qui suit apparat la compilation :
*** Cannot build PL/Perl because libperl is not a shared library.
*** You might have to rebuild your Perl installation. Refer to
*** the documentation for details.
(Si la sortie cran est ignore, on peut constater que la bibliothque plperl.so de PL/Perl, ou similaire, n'est pas installe.)
Si ce message est affich, il faut recompiler et rinstaller Perl manuellement pour pouvoir compiler PL/Perl. Lors de la
phase de configuration de Perl, il faut demander une bibliothque partage.

Pour compiler le langage de programmation serveur PL/Python, il faut que Python soit install avec les fichiers d'en-tte et
le module distutils. La version requise minimum est Python 2.2. Python 3 est support s'il s'agit d'une version 3.1 ou ultrieure ; voir la documentation de PL/Python Section 42.1, Python 2 et Python 3 lors de l'utilisation de Python 3.
Puisque PL/Python doit tre une bibliothque partage, la bibliothque libpython doit l'tre aussi sur la plupart des plateformes. Ce n'est pas le cas des installations par dfaut de Python. Si, aprs la compilation et l'installation de PostgreSQL, il
existe un fichier nomm plpython.so (des extensions diffrentes sont possibles), tout va bien. Sinon, il est fort probable
qu'un avertissement semblable celui qui suit soit apparu :
*** Cannot build PL/Python because libpython is not a shared library.
*** You might have to rebuild your Python installation. Refer to
*** the documentation for details.
Ce qui signifie qu'il faut recompiler (une partie de) Python pour crer cette bibliothque partage.
En cas de problmes, on peut excuter le configure de Python 2.3 ou ultrieur en utilisant le commutateur -enable-shared. Sur certains systmes d'exploitation, il n'est pas ncessaire de construire une bibliothque partage, mais
il faut en convaincre le systme de construction de PostgreSQL. Le fichier Makefile du rpertoire src/pl/plpython
donne des dtails complmentaires.

Pour construire le langage procdural PL/Tcl, Tcl doit tre install. Si une version antrieure la version 8.4 de Tcl, est
utilise, on s'assurera qu'il a t construit sans le support du multi-thread.

Pour activer le support de langage natif (NLS), qui permet d'afficher les messages d'un programme dans une langue autre que
l'anglais, une implantation de l'API Gettext est ncessaire. Certains systmes d'exploitation l'intgrent (par exemple, Linux,
NetBSD, Solaris). Pour les autres systmes, un paquet additionnel peut tre tlcharg sur
http://www.gnu.org/software/gettext/. Pour utiliser l'implantation Gettext des bibliothques C GNU, certains utilitaires ncessitent le paquet GNU Gettext. Il n'est pas ncessaire dans les autres implantations.

Vous avez besoin de Kerberos, OpenSSL, OpenLDAP ou PAM pour bnficier de l'authentification ou du chiffrement en
utilisant ces services.

En cas de compilation partir d'une arborescence Git et non d'un paquet de sources publi, ou pour faire du dveloppement au niveau serveur, les paquets suivants seront galement ncessaires :

GNU Flex et Bison sont ncessaires pour compiler partir d'un export du Git ou lorsque les fichiers de dfinition de
l'analyseur ou du scanner sont modifis. Les versions ncessaires sont Flex 2.5.31 ou ultrieure et Bison 1.875 ou ultrieure. Les autres programmes lex et yacc ne peuvent pas tre utiliss.

Perl 5.8 ou ultrieur est aussi ncessaire pour construire les sources du Git, ou lorsque les fichiers en entre pour n'importe laquelle des tapes de construction qui utilisent des scripts Perl ont t modifis. Sous Windows, Perl est ncessaire dans tous les
cas.

Si d'autres paquets GNU sont ncessaires, ils peuvent tre rcuprs


http://www.gnu.org/order/ftp.html pour la liste) ou sur ftp://ftp.gnu.org/gnu/.

sur

un

site

miroir

de

GNU

(voir

Il est important de vrifier qu'il y a suffisamment d'espace disque disponible. 100 Mo sont ncessaires pour la compilation et
20 Mo pour le rpertoire d'installation. Un groupe de bases de donnes vide ncessite 35 Mo ; les fichiers des bases prennent cinq
fois plus d'espace que des fichiers texte contenant les mmes donnes. Si des tests de rgression sont prvus, 150 Mo supplmentaires sont temporairement ncessaires. On peut utiliser la commande df pour vrifier l'espace disque disponible.

15.3. Obtenir les sources


284

Procdure d'installation de PostgreSQL du


code source
Les
sources
de
PostgreSQL
9.1.14
peuvent
tre
obtenues
par
ftp
anonyme
sur
ftp://ftp.postgresql.org/pub/source/v9.1.14/postgresql-9.1.14.tar.gz. D'autres options de tlchargement sont possibles partir du
site web : http://www.postgresql.org/download/. Aprs avoir obtenu le fichier, on le dcompresse :
gunzip postgresql-9.1.14.tar.gz
tar xf postgresql-9.1.14.tar
Cela cre un rpertoire postgresql-9.1.14 contenant les sources de PostgreSQL dans le rpertoire courant. Le reste de la
procdure d'installation s'effectue depuis ce rpertoire.
Les sources peuvent galement tre obtenues directement partir du systme de contrle de version. Pour plus d'informations,
voir Annexe H, Dpt du code source.

15.4. Procdure d'installation


1.

Configuration
La premire tape de la procdure d'installation est de configurer l'arborescence systme et de choisir les options intressantes. Ce qui est fait en excutant le script configure. Pour une installation par dfaut, entrer simplement
./configure
Ce script excutera de nombreux tests afin de dterminer les valeurs de certaines variables dpendantes du systme et de dtecter certains alas relatifs au systme d'exploitation. Il crera divers fichiers dans l'arborescence de compilation pour enregistrer ce qui a t trouv. configure peut aussi tre excut partir d'un rpertoire hors de l'arborescence des sources
pour conserver l'arborescence de compilation spar. Cette procdure est aussi appel une construction a VPATH build. Voici
comment la faire :
mkdir build_dir
cd build_dir
/path/to/source/tree/configure [les options vont ici]
gmake
La configuration par dfaut compilera le serveur et les utilitaires, aussi bien que toutes les applications clientes et interfaces
qui requirent seulement un compilateur C. Tous les fichiers seront installs par dfaut sous /usr/local/pgsql.
Les processus de compilation et d'installation peuvent tre personnaliss par l'utilisation d'une ou plusieurs options sur la
ligne de commande aprs configure :
--prefix=PREFIX
Installe tous les fichiers dans le rpertoire PREFIX au lieu du rpertoire /usr/local/pgsql. Les fichiers actuels seront
installs dans divers sous-rpertoires ; aucun fichier ne sera directement install sous PREFIX.
Pour satisfaire des besoins spcifiques, les sous-rpertoires peuvent tre personnaliss l'aide des options qui suivent. Toutefois, en laissant les options par dfaut, l'installation est dplaable, ce qui signifie que le rperoire peut tre dplac aprs installation. (Cela n'affecte pas les emplacements de man et doc.)
Pour les installations dplaables, on peut utiliser l'option --disable-rpath de configure. De plus, il faut indiquer au
systme d'exploitation comment trouver les bibliothques partages.
--exec-prefix=EXEC-PREFIX
Les fichiers qui dpendent de l'architecture peuvent tre installs dans un rpertoire diffrent, EXEC-PREFIX, de celui donn
par PREFIX. Ce qui peut tre utile pour partager les fichiers dpendant de l'architecture entre plusieurs machines. S'il est
omis, EXEC-PREFIX est gal PREFIX et les fichiers dpendant seront installs sous la mme arborescence que les fichiers
indpendants de l'architecture, ce qui est probablement le but recherch.
--bindir=REPERTOIRE
Prcise le rpertoire des
usr/local/pgsql/bin.

excutables.

Par

dfaut,

il

s'agit

de

EXEC-PREFIX/bin,

ce

qui

signifie

--sysconfdir=REPERTOIRE
Prcise le rpertoire de divers fichiers de configuration. Par dfaut, il s'agit de PREFIX/etc.
--libdir=REPERTOIRE
Prcise le rpertoire d'installation des bibliothques et des modules chargeables dynamiquement. Par dfaut, il s'agit de
EXEC-PREFIX/lib.
285

Procdure d'installation de PostgreSQL du


code source

--includedir=REPERTOIRE
Prcise le rpertoire d'installation des en-ttes C et C++. Par dfaut, il s'agit de PREFIX/include.
--datarootdir=REPERTOIRE
Indique le rpertoire racine de diffrents types de fichiers de donnes en lecture seule. Cela ne sert qu' paramtrer des valeurs
par dfaut pour certaines des options suivantes. La valeur par dfaut est PREFIX/share.
--datadir=REPERTOIRE
Indique le rpertoire pour les fichiers de donnes en lecture seule utiliss par les programmes installs. La valeur par dfaut
est DATAROOTDIR. Cela n'a aucun rapport avec l'endroit o les fichiers de base de donnes seront placs.
--localedir=REPERTOIRE
Indique le rpertoire pour installer les donnes locales, en particulier les fichiers catalogues de traductions de messages. La
valeur par dfaut est DATAROOTDIR/locale.
--mandir=REPERTOIRE
Les pages man fournies avec PostgreSQL seront installes sous ce rpertoire, dans leur sous-rpertoire manx respectif. Par
dfaut, il s'agit de DATAROOTDIR/man.
--docdir=RPERTOIRE
Configure le rpertoire racine pour installer les fichiers de documentation, sauf les pages man . Ceci ne positionne la valeur par dfaut que pour les options suivantes. La valeur par dfaut pour cette option est DATAROOTDIR/
doc/postgresql.
--htmldir=RPERTOIRE
La documentation formate en HTML pour PostgreSQL sera installe dans ce rpertoire. La valeur par dfaut est DATAROOTDIR.

Note
Une attention toute particulire a t prise afin de rendre possible l'installation de PostgreSQL dans des rpertoires partags (comme /usr/local/include) sans interfrer avec des noms de fichiers relatifs au
reste du systme. En premier lieu, le mot /postgresql est automatiquement ajout aux rpertoires datadir, sysconfdir et docdir, moins que le nom du rpertoire partir de la racine contienne dj le
mot postgres ou pgsql . Par exemple, si /usr/local est choisi comme prfixe, la documentation sera installe dans /usr/local/doc/postgresql, mais si le prfixe est /opt/postgres, alors il
sera dans /opt/postgres/doc. Les fichiers d'en-tte publiques C de l'interface cliente seront installs
sous includedir et sont indpendants des noms de fichiers relatifs au reste du systme. Les fichiers
d'en-tte privs et les fichiers d'en-tte du serveur sont installs dans des rpertoires privs sous
includedir. Voir la documentation de chaque interface pour savoir comment obtenir ces fichiers d'en-tte.
Enfin, un rpertoire priv sera aussi cr si ncessaire sous libdir pour les modules chargeables dynamiquement.

--with-includes=REPERTOIRES
REPERTOIRES est une liste de rpertoires spars par des caractres deux points (:) qui sera ajoute la liste de recherche
des fichiers d'en-tte. Si vous avez des paquetages optionnels (tels que Readline GNU) installs dans des rpertoires non
conventionnels, vous pouvez utiliser cette option et certainement l'option --with-libraries correspondante.
Exemple : --with-includes=/opt/gnu/include:/usr/sup/include.
--with-libraries=REPERTOIRES
REPERTOIRES est une liste de recherche de rpertoires de bibliothques spars par des caractres deux points (:). Si des paquets sont installs dans des rpertoires non conventionnels, il peut s'avrer ncessaire d'utiliser cette option (et l'option correspondante --with-includes).
Exemple : --with-libraries=/opt/gnu/lib:/usr/sup/lib.
--enable-nls[=LANGUES]
Permet de mettre en place le support des langues natives (NLS). C'est la possibilit d'afficher les messages des programmes
dans une langue autre que l'anglais. LANGUES est une liste, optionnelle, des codes des langues que vous voulez supporter spars par un espace. Par exemple, --enable-nls='de fr' (l'intersection entre la liste et l'ensemble des langues traduites actuellement sera calcule automatiquement). En l'absence de liste, toutes les traductions disponibles seront installes.
Pour utiliser cette option, une implantation de l'API Gettext est ncessaire ; voir ci-dessous.
286

Procdure d'installation de PostgreSQL du


code source

--with-pgport=NUMERO
Positionne NUMERO comme numro de port par dfaut pour le serveur et les clients. La valeur par dfaut est 5432. Le port
peut toujours tre chang ultrieurement mais, prcis ici, les excutables du serveur et des clients auront la mme valeur par
dfaut, ce qui est vraiment trs pratique. Habituellement, la seule bonne raison de choisir une valeur autre que celle par dfaut
est l'excution de plusieurs serveurs PostgreSQL sur la mme machine.
--with-perl
Permet l'utilisation du langage de procdures PL/Perl ct serveur.
--with-python
Permet la compilation du langage de procdures PL/Python.
--with-tcl
Permet la compilation du langage de procdures PL/Tcl.
--with-tclconfig=REPERTOIRE
Tcl installe les fichiers tclConfig.sh, contenant certaines informations de configuration ncessaires pour compiler le module d'interfaage avec Tcl. Ce fichier est trouv automatiquement mais, si pour utiliser une version diffrente de Tcl, il faut
indiquer le rpertoire o le trouver.
--with-gssapi
Construire avec le support de l'authentification GSSAPI. Sur de nombreux systmes, GSSAPI (qui fait habituellement partie
d'une installation Kerberos) n'est pas install dans un emplacement recherch par dfaut (c'est--dire /usr/include, /
usr/lib), donc vous devez utiliser les options --with-includes et --with-libraries en plus de cette option.
configure vrifiera les fichiers d'en-ttes ncessaires et les bibliothques pour s'assurer que votre installation GSSAPI est
suffisante avant de continuer.
--with-krb5
Compile le support d'authentification de Kerberos 5. Sur beaucoup de systmes, le systme Kerberos n'est pas install un
emplacement recherch par dfaut (c'est--dire /usr/include, /usr/lib), donc vous devez utiliser les options -with-includes et --with-libraries en plus de cette option. configure vrifiera les fichiers d'en-tte et les bibliothques requis pour s'assurer que votre installation Kerberos est suffisante avant de continuer
--with-krb-srvnam=NOM
Le nom par dfaut du service principal de Kerberos (aussi utilis par GSSAPI). postgres est pris par dfaut. Il n'y a habituellement pas de raison de le changer sauf dans le cas d'un environnement Windows, auquel cas il doit tre mis en majuscule,
POSTGRES.
--with-openssl
Compile le support de connexion SSL (chiffrement). Le paquetage OpenSSL doit tre install. configure vrifiera que
les fichiers d'en-tte et les bibliothques soient installs pour s'assurer que votre installation d'OpenSSL est suffisante avant
de continuer.
--with-pam
Compile le support PAM (Modules d'Authentification Pluggable).
--with-ldap
Demande l'ajout du support de LDAP pour l'authentification et la recherche des paramtres de connexion (voir la documentation sur l'authentification des clients et libpqSection 31.16, Recherches LDAP des paramtres de connexion et Section 19.3.8, Authentification LDAP ). Sur Unix, cela requiert l'installation du paquet OpenLDAP. Sur Windows, la bibliothque WinLDAP est utilise par dfaut. configure vrifiera l'existence des fichiers d'en-tte et des bibliothques requis pour s'assurer que votre installation d'OpenLDAP est suffisante avant de continuer.
--without-readline
vite l'utilisation de la bibliothque Readline (et de celle de libedit). Cela dsactive l'dition de la ligne de commande et
l'historique dans psql, ce n'est donc pas recommand.
--with-libedit-preferred
Favorise l'utilisation de la bibliothque libedit (sous licence BSD) plutt que Readline (GPL). Cette option a seulement un
sens si vous avez install les deux bibliothques ; dans ce cas, par dfaut, Readline est utilis.
--with-bonjour
Compile le support de Bonjour. Ceci requiert le support de Bonjour dans votre systme d'exploitation. Recommand sur Mac
OS X.
--with-ossp-uuid
Construit les composants en utilisant la bibliothque OSSP UUID. Autrement dit, construit le module uuid-ossp uuid-ossp,
287

Procdure d'installation de PostgreSQL du


code source

qui fournit des fonctions pour gnrer des UUIDs.


--with-libxml
Construit avec libxml (active le support SQL/XML). Une version 2.6.23 ou ultrieure de libxml est requise pour cette fonctionnalit.
Libxml installe un programme xml2-config qui est utilis pour dtecter les options du compilateur et de l'diteur de liens.
PostgreSQL l'utilisera automatiquement si elle est trouve. Pour indiquer une installation de libxml dans un emplacement inhabituel, vous pouvez soit configurer la variable d'environnement XML2_CONFIG pour pointer vers le programme
xml2-config appartenant l'installation, ou utiliser les options --with-includes et --with-libraries.
--with-libxslt
Utilise libxslt pour construire le module xml2 xml2. Le module contrib/xml2 se base sur cette bibliothque pour raliser
les transformations XSL du XML.
--disable-integer-datetimes
Dsactive le support pour le stockage des intervalles et horodatages en entier 64 bits, et stocke les valeurs de type date/temps
en temps que nombre virgule flottante la place. Le stockage virgule flottante des dates/temps tait la valeur par dfaut
dans les versions de PostgreSQL antrieures la 8.4, mais est maintenant obsolte parce qu'il ne permet pas une prcision
la microseconde pour toute l'tendue des valeurs timestamp. Toutefois, le stockage des dates/temps base d'entiers ncessite
un type entier de 64 bits. Par consquent, cette option peut tre utilise quand ce type de donnes n'est pas disponible, ou pour
maintenir la compatibilit avec des applications crites pour des versions antrieures de PostgreSQL. Voir la documentation propos des types dates/temps Section 8.5, Types date/heure pour plus d'informations.
--disable-float4-byval
Dsactive le passage par valeur des valeurs float4, entranant leur passage par rfrence la place. Cette option a un
cot en performance, mais peut tre ncessaire pour maintenir la compatibilit avec des anciennes fonctions cres par
l'utilisateur qui sont crites en C et utilisent la convention d'appel version 0 . Une meilleure solution long terme est de
mettre jour toutes ces fonctions pour utiliser la convention d'appel version 1 .
--disable-float8-byval
Dsactive le passage par valeur des valeurs float8, entranant leur passage par rfrence la place. Cette option a un
cot en performance, mais peut tre ncessaire pour maintenir la compatibilit avec des anciennes fonctions cres par
l'utilisateur qui sont crites en C et utilisent la convention d'appel version 0 . Une meilleure solution long terme est de
mettre jour toutes ces fonctions pour utiliser la convention d'appel version 1 . Notez que cette option n'affecte pas que
float8, mais aussi int8 et quelques types apparents comme timestamp. Sur les plateformes 32 bits, -disable-float8-byval est la valeur par dfaut, et il n'est pas permis de slectionner --enable-float8-byval.
--with-segsize=TAILLESEG
Indique la taille d'un segment, en gigaoctets. Les grandes tables sont divises en plusieurs fichiers du systme d'exploitation,
chacun de taille gale la taille de segment. Cela vite les problmes avec les limites de tailles de fichiers qui existent sur de
nombreuses plateformes. Si votre systme d'exploitation supporte les fichiers de grande taille ( largefile ), ce qui est le cas
de la plupart d'entre eux de nos jours, vous pouvez utiliser une plus grande taille de segment. Cela peut tre utile pour rduire
le nombre de descripteurs de fichiers qui peuvent tre utiliss lors de travail sur des trs grandes tables. Attention ne pas slectionner une valeur plus grande que ce qui est support par votre plateforme et le(s) systme(s) de fichiers que vous prvoyez d'utiliser. D'autres outils que vous pourriez vouloir utiliser, tels que tar, pourraient aussi limiter la taille maximum utilisable pour un fichier. Il est recommand, mme si pas vraiment ncessaire, que cette valeur soit un multiple de 2. Notez que
changer cette valeur impose de faire un initdb.
--with-blocksize=TAILLEBLOC
Indique la taille d'un bloc, en kilooctets. C'est l'unit de stockage et d'entre/sortie dans les tables. La valeur par dfaut, 8 kilooctets, est approprie pour la plupart des cas ; mais d'autres valeurs peuvent tre utilises dans des cas spciaux. Cette valeur
doit tre une puissance de 2 entre 1 et 32 (kilooctets). Notez que changer cette valeur impose de faire un initdb.
--with-wal-segsize=TAILLESEG
Indique la taille d'un segment WAL, en mgaoctets. C'est la taille de chaque fichier individuel dans les journaux de transactions. Il peut tre utile d'ajuster cette taille pour contrler la granularit du transport de journaux de transations. La valeur par
dfaut est de 16 mgaoctets. La valeur doit tre une puissance de 2 entre 1 et 6 (mgaoctets). Notez que changer cette valeur
impose de faire un initdb.
--with-wal-blocksize=TAILLEBLOC
Indique la taille d'un bloc WAL, en kilooctets. C'est l'unit de stockage et d'entre/sortie dans le journal des transactions. La
valeur par dfaut, 8 kilooctets, est approprie pour la plupart des cas ; mais d'autres valeurs peuvent tre utilises dans des cas
spciaux. La valeur doit tre une puissance de 2 entre 1 et 64 (kilooctets).
--disable-spinlocks
288

Procdure d'installation de PostgreSQL du


code source

Autorise le succs de la construction y compris lorsque PostgreSQL n'a pas le support spinlock du CPU pour la plateforme.
Ce manque de support rsultera en des performances faibles ; du coup, cette option devra seulement tre utilise si la
construction choue et vous informe du manque de support de spinlock sur votre plateforme. Si cette option est requise pour
construire PostgreSQL sur votre plateforme, merci de rapporter le problme aux dveloppeurs de PostgreSQL.
--disable-thread-safety
Dsactive la sret des threads pour les bibliothques clients. Ceci empche les threads concurrents dans les programmes
libpq et ECPG de contrler avec sret leur pointeurs de connexion privs.
--with-system-tzdata=RPERTOIRE
PostgreSQL inclut sa propre base de donnes des fuseaux horaires, ncessaire pour les oprations sur les dates et les heures.
Cette base de donnes est en fait compatible avec la base de fuseaux horaires zoneinfo fournie par de nombreux systmes
d'exploitation comme FreeBSD, Linux et Solaris, donc ce serait redondant de l'installer une nouvelle fois. Quand cette option
est utilise, la base des fuseaux horaires, fournie par le systme, dans RPERTOIRE est utilise la place de celle inclus dans
la distribution des sources de PostgreSQL. RPERTOIRE doit tre indiqu avec un chemin absolu. /
usr/share/zoneinfo est un rpertoire trs probable sur certains systmes d'exploitation. Notez que la routine
d'installation ne dtectera pas les donnes de fuseau horaire diffrentes ou errones. Si vous utilisez cette option, il vous est
conseill de lancer les tests de rgression pour vrifier que les donnes de fuseau horaire que vous pointez fonctionnent correctement avec PostgreSQL.
Cette option a pour cible les distributeurs de paquets binaires qui connaissent leur systme d'exploitation. Le principal avantage d'utiliser cette option est que le package PostgreSQL n'aura pas besoin d'tre mis jour chaque fois que les rgles des
fuseaux horaires changent. Un autre avantage est que PostgreSQL peut tre cross-compil plus simplement si les fichiers des
fuseaux horaires n'ont pas besoin d'tre construit lors de l'installation.
--without-zlib
vite l'utilisation de la bibliothque Zlib. Cela dsactive le support des archives compresses dans pg_dump et pg_restore.
Cette option est seulement l pour les rares systmes qui ne disposent pas de cette bibliothque.
--enable-debug
Compile tous les programmes et bibliothques en mode de dbogage. Cela signifie que vous pouvez excuter les programmes
via un dbogueur pour analyser les problmes. Cela grossit considrablement la taille des excutables et, avec des compilateurs autres que GCC, habituellement, cela dsactive les optimisations du compilateur, provoquant des ralentissements. Cependant, mettre ce mode en place est extrmement utile pour reprer les problmes. Actuellement, cette option est recommande pour les installations en production seulement si vous utilisez GCC. Nanmoins, vous devriez l'utiliser si vous dveloppez
ou si vous utilisez une version bta.
--enable-coverage
Si vous utilisez GCC, les programmes et bibliothques sont compils avec de l'instrumentation de test de couverture de code.
Quand ils sont excuts, ils gnrent des fichiers dans le rpertoire de compilation avec des mtriques de couverture de code.
Voir Section 30.4, Examen de la couverture du test pour davantage d'informations. Cette option ne doit tre utilise
qu'avec GCC et uniquement en phase de dveloppement.
--enable-profiling
En cas d'utilisation de GCC, tous les programmes et bibliothques sont compils pour qu'elles puissent tre profiles. la
sortie du processus serveur, un sous-rpertoire sera cr pour contenir le fichier gmon.out utiliser pour le profilage. Cette
option est utiliser seulement avec GCC lors d'un dveloppement.
--enable-cassert
Permet la vrification des assertions par le serveur qui teste de nombreux cas de conditions impossibles . Ce qui est inestimable dans le cas de dveloppement, mais les tests peuvent ralentir sensiblement le systme. Activer cette option n'influe pas
sur la stabilit de votre serveur ! Les assertions vrifies ne sont pas classes par ordre de svrit et il se peut qu'un bogue
anodin fasse redmarrer le serveur s'il y a un chec de vrification. Cette option n'est pas recommande dans un environnement de production mais vous devriez l'utiliser lors de dveloppement ou pour les versions bta.
--enable-depend
Active la recherche automatique des dpendances. Avec cette option, les fichiers makefile sont appels pour recompiler les fichiers objet ds qu'un fichier d'en-tte est modifi. C'est pratique si vous faites du dveloppement, mais inutile si vous ne voulez que compiler une fois et installer. Pour le moment, cette option ne fonctionne qu'avec GCC.
--enable-dtrace
Compile PostgreSQL avec le support de l'outil de trace dynamique, DTrace. Voir Section 27.4, Traces dynamiques
pour plus d'informations.
Pour pointer vers le programme dtrace, la variable d'environnement DTRACE doit tre configure. Ceci sera souvent ncessaire car dtrace est typiquement install sous /usr/sbin, qui pourrait ne pas tre dans le chemin.
289

Procdure d'installation de PostgreSQL du


code source

Des options supplmentaires en ligne de commande peuvent tre indiques dans la variable d'environnement DTRACEFLAGS
pour le programme dtrace. Sur Solaris, pour inclure le support de DTrace dans un excutable 64-bit, ajoutez l'option DTRACEFLAGS="-64" pour configure. Par exemple, en utilisant le compilateur GCC :
./configure CC='gcc -m64' --enable-dtrace DTRACEFLAGS='-64' ...
En utilisant le compilateur de Sun :
./configure CC='/opt/SUNWspro/bin/cc -xtarget=native64' --enable-dtrace
DTRACEFLAGS='-64' ...
Si vous prfrez utiliser un compilateur C diffrent de ceux lists par configure, positionnez la variable d'environnement
CC pour qu'elle pointe sur le compilateur de votre choix. Par dfaut, configure pointe sur gcc s'il est disponible, sinon il
utilise celui par dfaut de la plateforme (habituellement cc). De faon similaire, vous pouvez repositionner les options par
dfaut du compilateur l'aide de la variable CFLAGS.
Les variables d'environnement peuvent tre indiques sur la ligne de commande configure, par exemple :
./configure CC=/opt/bin/gcc CFLAGS='-O2 -pipe'
Voici une liste des variables importantes qui sont configurables de cete faon :
BISON
programme Bison
CC
compilateur C
CFLAGS
options passer au compilateur C
CPP
prprocesseur C
CPPFLAGS
options passer au prprocesseur C
DTRACE
emplacement du programme dtrace
DTRACEFLAGS
options passer au programme dtrace
FLEX
programme Flex
LDFLAGS
options utiliser lors de l'dition des liens des excutables et des bibliothques partages
LDFLAGS_EX
options supplmentaires valables uniquement lors de l'dition des liens des excutables
LDFLAGS_SL
options supplmentaires valables uniquement lors de l'dition des liens des bibliothques partages
MSGFMT
programme msgfmt pour le support des langues
PERL
chemin complet vers l'interprteur Perl. Il sera utilis pour dterminer les dpendances pour la construction de PL/Perl.
PYTHON
chemin complet vers l'interprteur Python. Il sera utilis pour dterminer les dpendances pour la construction de PL/Python.
De plus, si Python 2 ou 3 est spcifi ici (ou implicitement choisi), il dtermine la variante de PL/Python qui devient disponible. Voir la documentation PL/Python Section 42.1, Python 2 et Python 3 pour plus d'informations.
TCLSH
chemin complet vers l'interprteur Tcl. Il sera utilis pour dterminer les dpendances pour la construction de PL/Tcl, et il sera substitu dans des scripts Tcl.
290

Procdure d'installation de PostgreSQL du


code source

XML2_CONFIG
programme xml2-config utilis pour localiser l'installation de libxml.
2.

Compilation
Pour dmarrer la compilation, saisissez
gmake
(Rappelez-vous d'utiliser GNU make). La compilation prendra quelques minutes, selon votre matriel. La dernire ligne affiche devrait tre
All of PostgreSQL is successfully made. Ready to install.
Si vous voulez construire tout ce qui peut tre construit, ceci incluant la documentation (HTML et pages man) et les modules
supplmentaires (contrib), saisissez la place :
gmake world
La dernire ligne affiche doit tre :
PostgreSQL, contrib and HTML documentation successfully made. Ready to install.

3.

Tests de rgression
Si vous souhaitez tester le serveur nouvellement compil avant de l'installer, vous pouvez excuter les tests de rgression ce
moment. Les tests de rgression sont une suite de tests qui vrifient que PostgreSQL fonctionne sur votre machine tel que
les dveloppeurs l'esprent. Saisissez
gmake check
(cela ne fonctionne pas en tant que root ; faites-le en tant qu'utilisateur sans droits). Le fichier src/
test/regress/README et la documentation contiennentLe Chapitre 30, Tests de rgression contient des dtails sur
l'interprtation des rsultats de ces tests. Vous pouvez les rpter autant de fois que vous le voulez en utilisant la mme commande.

4.

Installer les fichiers

Note
Si vous mettez jour une version existante, assurez-vous d'avoir bien lu la documentation Section 17.6,
Mise jour d'une instance PostgreSQL qui donne les instructions sur la mise jour d'un cluster.
Pour installer PostgreSQL, saisissez
gmake install
Cela installera les fichiers dans les rpertoires spcifis dans l'tape 1. Assurez-vous d'avoir les droits appropris pour crire
dans ces rpertoires. Normalement, vous avez besoin d'tre superutilisateur pour cette tape. Une alternative consiste crer
les rpertoires cibles l'avance et leur donner les droits appropries.
Pour installer la documentation (HTML et pages man), saisissez :
gmake install-docs
Si vous construisez tout, saisissez ceci la place :
gmake install-world
Cela installe aussi la documentation.
Vous pouvez utiliser gmake install-strip en lieu et place de gmake install pour dpouiller l'installation des
excutables et des bibliothques. Cela conomise un peu d'espace disque. Si vous avez effectu la compilation en mode de
dbogage, ce dpouillage l'enlvera, donc ce n'est faire seulement si ce mode n'est plus ncessaire. install-strip essaie d'tre raisonnable en sauvegardant de l'espace disque mais il n'a pas une connaissance parfaite de la faon de dpouiller
un excutable de tous les octets inutiles. Ainsi, si vous voulez sauvegarder le maximum d'espace disque, vous devrez faire le
291

Procdure d'installation de PostgreSQL du


code source

travail la main.
L'installation standard fournit seulement les fichiers en-ttes ncessaires pour le dveloppement d'applications clientes ainsi
que pour le dveloppement de programmes ct serveur comme des fonction personnelles ou des types de donnes crits en
C (avant PostgreSQL 8.0, une commande gmake install-all-headers spare tait ncessaire pour ce dernier
point mais cette tape a t intgre l'installation standard).
Installation du client uniquement : Si vous voulez uniquement installer les applications clientes et les bibliothques
d'interface, alors vous pouvez utilisez ces commandes :
gmake
gmake
gmake
gmake

-C
-C
-C
-C

src/bin install
src/include install
src/interfaces install
doc install

src/bin comprend quelques excutables utiliss seulement par le serveur mais ils sont petits.
Enregistrer eventlog sur Windows : Pour enregistrer une bibliothque eventlog sur Windows grce au systme d'exploitation,
excutez cette commande aprs l'installation :
regsvr32 pgsql_library_directory/pgevent.dll
Ceci cre les entres du registre utilises par le visualisateur d'vnements.
Dsinstallation : Pour dsinstaller, utilisez la commande gmake uninstall. Cependant, cela ne supprimera pas les rpertoires
crs.
Nettoyage : Aprs l'installation, vous pouvez librer de l'espace en supprimant les fichiers issus de la compilation des rpertoires
sources l'aide de la commande gmake clean. Cela conservera les fichiers crs par la commande configure, ainsi vous pourrez
tout recompiler ultrieurement avec gmake. Pour remettre l'arborescence source dans l'tat initial, utilisez gmake distclean. Si
vous voulez effectuer la compilation pour diverses plateformes partir des mmes sources vous devrez d'abord refaire la configuration chaque fois (autrement, utilisez un rpertoire de construction spar pour chaque plateforme, de faon ce que le rpertoire des sources reste inchang).
Si vous avez compil et que vous vous tes rendu compte que les options de configure sont fausses ou si vous changez quoi que
ce soit que configure prenne en compte (par exemple, la mise jour d'applications), alors faire un gmake distclean avant de reconfigurer et recompiler est une bonne ide. Sans a, vos changements dans la configuration ne seront pas rpercuts partout o il
faut.

15.5. Initialisation post-installation


15.5.1. Bibliothques partages
Sur certains systmes qui utilisent les bibliothques partages (ce que font de nombreux systmes), vous avez besoin de leurs spcifier comment trouver les nouvelles bibliothques partages. Les systmes sur lesquels ce n'est pas ncessaire comprennent BSD/
OS, FreeBSD, HP-UX, IRIX, Linux, NetBSD, OpenBSD, Tru64 UNIX (auparavant Digital UNIX) et Solaris.
La mthode pour le faire varie selon la plateforme, mais la mthode la plus rpandue consiste positionner des variables
d'environnement comme LD_LIBRARY_PATH : avec les shells Bourne (sh, ksh, bash, zsh) :
LD_LIBRARY_PATH=/usr/local/pgsql/lib
export LD_LIBRARY_PATH
ou en csh ou tcsh :
setenv LD_LIBRARY_PATH /usr/local/pgsql/lib
Remplacez /usr/local/pgsql/lib par la valeur donne --libdir dans l'tape 1. Vous pouvez mettre ces commandes
dans un script de dmarrage tel que /etc/profile ou ~/.bash_profile. Certaines informations pertinentes au sujet de
mises en garde associes cette mthode peuvent tre trouves sur http://xahlee.org/UnixResource_dir/_/ldpath.html.
Sur certains systmes, il peut tre prfrable de renseigner la variable d'environnement LD_RUN_PATH avant la compilation.
Avec Cygwin, placez le rpertoire des bibliothques dans la variable PATH ou dplacez les fichiers .dll dans le rpertoire bin.
En cas de doute, rfrez-vous aux pages de man de votre systme (peut-tre ld.so ou rld). Si vous avez ultrieurement un message
tel que
psql: error in loading shared libraries
292

Procdure d'installation de PostgreSQL du


code source
libpq.so.2.1: cannot open shared object file: No such file or directory
alors cette tape est vraiment ncessaire. Faites-y attention.
Si votre systme d'exploitation est BSD/OS, Linux ou SunOS 4 et que vous avez les accs de superutilisateur, vous pouvez
excuter :
/sbin/ldconfig /usr/local/pgsql/lib
(ou le rpertoire quivalent) aprs l'installation pour permettre l'diteur de liens de trouver les bibliothques partages plus rapidement. Rfrez-vous aux pages man portant sur ldconfig pour plus d'informations. Pour les systmes d'exploitation FreeBSD,
NetBSD et OpenBSD, la commande est :
/sbin/ldconfig -m /usr/local/pgsql/lib
Les autres systmes d'exploitation ne sont pas connus pour avoir de commande quivalente.

15.5.2. Variables d'environnement


Si l'installation a t ralise dans /usr/local/pgsql ou un autre endroit qui n'est pas dans les rpertoires contenant les
excutables par dfaut, vous devez ajouter /usr/local/pgsql/bin (ou le rpertoire fourni --bindir au moment de
l'tape 1) dans votre PATH. Techniquement, ce n'est pas une obligation mais cela rendra l'utilisation de PostgreSQL plus
confortable.
Pour ce faire, ajoutez ce qui suit dans le fichier d'initialisation de votre shell, par exemple ~/.bash_profile (ou /
etc/profile, si vous voulez que tous les utilisateurs l'aient) :
PATH=/usr/local/pgsql/bin:$PATH
export PATH
Si vous utilisez le csh ou le tcsh, alors utilisez la commande :
set path = ( /usr/local/pgsql/bin $path )
Pour que votre systme trouve la documentation man, il vous faut ajouter des lignes telles que celles qui suivent votre fichier
d'initialisation du shell, moins que vous installiez ces pages dans un rpertoire o elles sont mises normalement :
MANPATH=/usr/local/pgsql/man:$MANPATH
export MANPATH
Les variables d'environnement PGHOST et PGPORT indiquent aux applications clientes l'hte et le port du serveur de base. Elles
surchargent les valeurs utilises lors de la compilation. Si vous excutez des applications clientes distance, alors c'est plus pratique si tous les utilisateurs peuvent paramtrer PGHOST. Ce n'est pas une obligation, cependant, la configuration peut tre communique via les options de lignes de commande la plupart des programmes clients.

15.6. Dmarrer
La suite est un rsum rapide de la faon de faire fonctionner PostgreSQL une fois l'installation termine. La documentation
principale contient plus d'informations.
1.

Crer un compte utilisateur pour le serveur PostgreSQL. C'est cet utilisateur qui fera dmarrer le serveur. Pour un usage en
production, vous devez crer un compte sans droits ( postgres est habituellement utilis). Si vous n'avez pas les accs superutilisateur ou si vous voulez juste regarder, votre propre compte utilisateur est suffisant. Mais, utiliser le compte superutilisateur pour dmarrer le serveur est risqu (au point de vue scurit) et ne fonctionnera pas.
adduser postgres

2.

Faire l'installation de la base de donnes avec la commande initdb. Pour excuter initdb, vous devez tre connect sur votre
serveur avec le compte PostgreSQL. Cela ne fonctionnera pas avec le compte superutilisateur.
root# mkdir /usr/local/pgsql/data
root# chown postgres /usr/local/pgsql/data
root# su - postgres
postgres$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
L'option -D spcifie le rpertoire o les donnes seront stockes. Vous pouvez utiliser le chemin que vous voulez, il n'a pas
tre sous le rpertoire de l'installation. Avant de lancer initdb, assurez-vous que le compte serveur peut crire dans ce rpertoire (ou le crer s'il n'existe pas), comme c'est montr ici.
293

Procdure d'installation de PostgreSQL du


code source

3.

ce moment, si vous n'utilisez pas l'option -A de initdb, vous devez modifier le fichier pg_hba.conf pour contrler les
accs en local du serveur avant de le lancer. La valeur par dfaut est de faire confiance tous les utilisateurs locaux.

4.

L'tape initdb prcdente vous a indiqu comment dmarrer le serveur de base. Maintenant, faites-le. La commande doit ressembler :
/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
Cela dmarrera le serveur en avant-plan. Pour le mettre en arrire plan faites quelque chose comme :
nohup /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data \
</dev/null >>server.log 2>&1 </dev/null &
Pour arrter le serveur fonctionnant en arrire-plan, vous pouvez saisir :
kill `cat /usr/local/pgsql/data/postmaster.pid`

5.

Crer une base de donnes :


createdb testdb
Ensuite, entrez
psql testdb
pour vous connecter la base. l'invite, vous pouvez saisir des commandes SQL et commencer l'exprimentation.

15.7. Et maintenant ?

La distribution de PostgreSQL comprend un document comprhensible que vous devriez lire de temps en temps. Aprs
l'installation, le document peut tre lu en faisant pointer votre navigateur internet sur /
usr/local/pgsql/doc/html/index.html, except si vous avez chang les rpertoires d'installation.
Le premier chapitre de la documentation est un tutoriel qui devrait tre votre premire lecture si vous tes nouveau dans le
monde des bases de donnes SQL. Si vous tes familier avec les concepts des bases de donnes, alors vous devriez commencer
avec la partie administration du serveur qui contient des informations sur la faon de mettre en place le serveur de base, les
bases des utilisateurs et l'authentification.

Normalement, vous voudrez faire en sorte que le serveur de base dmarre automatiquement au boot de la machine. Pour ce
faire, quelques suggestions se trouvent dans la documentation.

Faire les tests de rgression sur le serveur install (en utilisant gmake installcheck). Si vous ne l'avez pas fait auparavant,
vous devriez dfinitivement le faire maintenant. C'est aussi expliqu dans la documentation.

Par dfaut, PostgreSQL est configur pour fonctionner sur un matriel mimimal. Ceci lui permet de fonctionner sur pratiquement toutes les configurations matrielles. Nanmoins, la configuration par dfaut n'est pas conue pour des performances
optimales. Pour disposer des meilleures performances, plusieurs paramtres serveurs doivent tre ajusts, les deux plus communs tant shared_buffers et work_mem. Les autres paramtres mentionns dans la documentation affectent aussi les
performances.

15.8. Plateformes supportes


Une plateforme (c'est--dire une combinaison d'un processeur et d'un systme d'exploitation) est considre supporte par la communaut de dveloppeur de PostgreSQL si le code permet le fonctionnement sur cette plateforme et que la construction et les
tests de regrssion ont t rcemment vrifis sur cette plateforme. Actuellement, la plupart des tests de compatibilit de plateforme se fait automatiquement par des machines de tests dans la ferme de construction de PostgreSQL. Si vous tes intresss par
l'utilisation de PostgreSQL sur une plateforme qui n'est pas reprsente dans la ferme de construction, mais pour laquelle le
code fonctionne ou peut fonctionner, nous vous suggrons fortement de construire une machine qui sera membre de la ferme pour
que la compatibilit puisse tre assure dans la dure.
En gnral, PostgreSQL doit fonctionner sur les architectures processeur suivantes : x86, x86_64, IA64, PowerPC, PowerPC
64, S/390, S/390x, Sparc, Sparc 64, Alpha, ARM, MIPS, MIPSEL, M68K et PA-RISC. Un support du code existe pour M32R,
NS32K et VAX mais ces architectures n'ont pas t testes rcemment notre connaissance. Il est souvent possible de construire
PostgreSQL sur un type de processeur non support en prcisant --disable-spinlocks. Cependant, les performance en
souffriront.
294

Procdure d'installation de PostgreSQL du


code source
PostgreSQL doit fonctionner sur les systmes d'exploitation suivants : Linux (toutes les distributions rcentes), Windows
(Win2000 SP4 et ultrieure), FreeBSD, OpenBSD, NetBSD, Mac OS X, AIX, HP/UX, IRIX, Solaris, Tru64 Unix et UnixWare.
D'autres systmes style Unix peuvent aussi fonctionner mais n'ont pas t rcemment tests. Dans la plupart des cas, toutes les architectures processeurs supportes par un systme d'exploitation donn fonctionneront. Cherchez dans le rpertoire Section 15.9,
Notes spcifiques des plateformes ci-dessous pour voir s'il y a des informations spcifiques votre systme d'exploitation,
tout particulirement dans le cas d'un vieux systme.
Si vous avez des problmes d'installation sur une plateforme qui est connue comme tant supporte d'aprs les rcents rsultats de
la ferme de construction, merci de rapporter cette information <pgsql-bugs@postgresql.org>. Si vous tes intress
pour porter PostgreSQL sur une nouvelle plateforme, <pgsql-hackers@postgresql.org> est l'endroit appropri pour
en discuter.

15.9. Notes spcifiques des plateformes


Cette section documente des problmes spcifiques additionnels lis des plateformes, en ce qui concerne l'installation et le paramtrage de PostgreSQL. Assurez-vous de lire aussi les instructions d'installation, et en particulier Section 15.2, Prrequis . Par
ailleurs, consultez le fichier src/test/regress/README et la documentation Chapitre 30, Tests de rgression propos de
l'interprtation des tests de rgression.
Les plateformes qui ne sont pas traites ici n'ont pas de problmes d'installation spcifiques connus.

15.9.1. AIX
PostgreSQL fonctionne sur AIX, mais russir l'installer correctement peut s'avrer difficile. Les versions AIX de la 4.3.3 la 6.1
sont considres comme supportes en thorie. Vous pouvez utiliser GCC ou le compilateur natif IBM xlc. En gnral, utiliser des
versions rcentes d'AIX et PostgreSQL rend la tche plus simple. Vrifiez la ferme de compilation pour avoir des informations
jour sur les versions d'AIX connues pour tre compatibles.
Les niveaux minimums recommands de correctifs pour les versions supportes de AIX sont :
AIX 4.3.3
Maintenance Level 11 + post ML11 bundle
AIX 5.1
Maintenance Level 9 + post ML9 bundle
AIX 5.2
Technology Level 10 Service Pack 3
AIX 5.3
Technology Level 7
AIX 6.1
Base Level
Pour vrifier votre niveau de correctif, utilisez oslevel -r de AIX 4.3.3 AIX 5.2 ML 7, et oslevel -s pour les versions ultrieures.
Utilisez les options de configure en plus de vos propres options si vous avez install Readline ou libz dans /usr/local : -with-includes=/usr/local/include --with-libraries=/usr/local/lib.

15.9.1.1. Problmes avec GCC


Sur AIX 5.3, il y a des problmes pour compiler et faire fonctionner PostgreSQL avec GCC.
Vous voudrez utiliser une version de GCC suprieure 3.3.2, en particulier si vous utilisez une version pr-package. Nous avons
eu de bons rsultats avec la 4.0.1. Les problmes avec les versions prcdentes semblent tre davantage lies la faon dont IBM
a packag GCC qu' des problmes rels, avec GCC, ce qui fait que si vous compilez GCC vous-mme, vous pourriez russir avec
une version plus ancienne de GCC.

15.9.1.2. Sockets du domaine Unix inutilisables


Dans AIX 5.3, la structure sockaddr_storage n'est pas dfinie avec une taille suffisante. En version 5.3, IBM a augment la taille
de sockaddr_un, la structure d'adresse pour une socket de domaine Unix, mais n'a pas augment en consquence la taille de sockaddr_storage. La consquence est que les tentatives d'utiliser une socket de domaine Unix avec PostgreSQL amnent libpq dpasser la taille de la structure de donnes. Les connexions TCP/IP fonctionnent, mais pas les sockets de domaine Unix, ce qui empche les tests de rgression de fonctionner.

295

Procdure d'installation de PostgreSQL du


code source
Le problme a t rapport IBM, et est enregistr en tant que rapport de bogue PMR29657. Si vous mettez jour vers le niveau
de maintenance 5300-03 et ultrieur, le correctif sera inclus. Une rsolution immdiate est de corriger _SS_MAXSIZE 1025
dans /usr/include/sys/socket.h. Dans tous les cas, recompilez PostgreSQL une fois que vous avez l'en-tte corrig.

15.9.1.3. Problmes avec les adresses internet


PostgreSQL se base sur la fonction systme getaddrinfo pour analyser les adresses IP dans listen_addresses et dans
pg_hba.conf, etc. Les anciennes versions d'AIX ont quelques bogues dans cette fonction. Si vous avez des problmes relatifs
ces paramtres, la mise jour vers le niveau de correctif AIX appropri indiqu ci-dessus pourrait se charger de cela.
Un utilisateur a rapport :
Lors de l'implmentation de PostgreSQL version 8.1 sur AIX 5.3, nous tombions priodiquement sur des problmes quand le collecteur de statistiques ne voulait mystrieusement pas dmarrer. Cela se trouvait tre le rsultat d'un comportement inattendu
dans l'implmentation d'IPv6. Il semble que PostgreSQL et IPv6 ne fonctionnent pas bien ensemble sur AIX 5.3.
Chacune des actions suivantes corrige le problme.

Supprimer l'adresse IPv6 pour localhost :


(as root)
# ifconfig lo0 inet6 ::1/0 delete

Supprimer IPv6 des services rseau. Le fichier /etc/netsvc.conf sur AIX est en gros quivalent /
etc/nsswitch.conf sur Solaris/Linux. La valeur par dfaut, sur AIX, est donc :
hosts=local,bind
Remplacez ceci avec :
hosts=local4,bind4
pour dsactiver la recherche des adresses IPv6.

Avertissement
Ceci est en ralit un contournement des problmes relatifs l'immaturit du support IPv6, qui a amlior la visibilit pour les versions 5.3 d'AIX. Cela a fonctionn avec les versions 5.3 d'AIX mais n'en fait pas pour autant une
solution lgante ce problme. Certaines personnes ont indiqu que ce contournement est non seulement inutile,
mais pose aussi des problmes sur AIX 6.1, o le support IPv6 est beaucoup plus mature.

15.9.1.4. Gestion de la mmoire


AIX est particulier dans la faon dont il gre la mmoire. Vous pouvez avoir un serveur avec des gigaoctets de mmoire libre,
mais malgr tout avoir des erreurs de mmoire insuffisante ou des erreurs d'espace d'adressage quand vous lancez des applications.
Un exemple est createlang qui choue avec des erreurs inhabituelles. Par exemple, en excutant en tant que propritaire de
l'installation PostgreSQL :
-bash-3.00$ createlang plperl template1
createlang: language installation failed: ERROR: could not load library
"/opt/dbs/pgsql748/lib/plperl.so": A memory address is not in the address space for the
process.
En l'excutant en tant que non-propritaire, mais dans le groupe propritaire de l'installation PostgreSQL :
-bash-3.00$ createlang plperl template1
createlang: language installation failed: ERROR:
"/opt/dbs/pgsql748/lib/plperl.so": Bad address

could not load library

On a un autre exemple avec les erreurs 'out of memory' dans les traces du serveur PostgreSQL, avec toute allocation de mmoire
proche ou suprieure 256 Mo qui choue.
La cause gnrale de ces problmes est le nombre de bits et le modle mmoire utilis par le processus serveur. Par dfaut, tous
les binaires compils sur AIX sont 32-bits. Cela ne dpend pas du matriel ou du noyau en cours d'utilisation. Ces processus
296

Procdure d'installation de PostgreSQL du


code source
32-bits sont limits 4 Go de mmoire prsente en segments de 256 Mo utilisant un parmi quelques modles. Le modle par dfaut permet moins de 256 Mo dans le tas, comme il partage un seul segment avec la pile.
Dans le cas de l'exemple createlang ci-dessus, vrifiez votre umask et les droits des binaires de l'installation PostgreSQL. Les binaires de l'exemple taient 32-bits et installs en mode 750 au lieu de 755. En raison des droits, seul le propritaire ou un membre
du groupe propritaire peut charger la bibliothque. Puisqu'il n'est pas lisible par tout le mode, le chargeur place l'objet dans le tas
du processus au lieu d'un segment de mmoire de bibliothque o il aurait t sinon plac.
La solution idale pour ceci est d'utiliser une version 64-bits de PostgreSQL, mais ce n'est pas toujours pratique, parce que les
systmes quips de processeurs 32-bits peuvent compiler mais ne peuvent pas excuter de binaires 64-bits.
Si un binaire 32-bits est souhait, positionnez LDR_CNTRL MAXDATA=0xn0000000, o 1<=n <= 8 avant de dmarrer le serveur PostgreSQL, et essayez diffrentes valeurs et paramtres de postgresql.conf pour trouver une configuration qui fonctionne de faon satisfaisante. Cette utilisation de LDR_CNTRL notifie AIX que vous voulez que le serveur rserve MAXDATA
octets pour le tas, allous en segments de 256 Mo. Quand vous avez trouv une configuration utilisable, ldedit peut tre utilis
pour modifier les binaires pour qu'ils utilisent par dfaut la taille de tas dsire. PostgreSQL peut aussi tre recompil, en passant
configure LDFLAGS="-Wl,-bmaxdata:0xn0000000" pour obtenir le mme rsultat.
Pour une compilation 64-bits, positionnez OBJECT_MODE 64 et passez CC="gcc -maix64" et LDFLAGS="-Wl,-bbigtoc" configure. (Les options pour xlc pourraient diffrer.) Si vous omettez les exports de OBJECT_MODE, votre compilation chouera avec des erreurs de l'diteur de liens. Quand OBJECT_MODE est positionn, il indique
aux outils de compilation d'AIX comme ar, as et ld quel types de fichiers manipuler par dfaut.
Par dfaut, de la surallocation d'espace de pagination peut se produire. Bien que nous ne l'ayons jamais constat, AIX tuera des
processus quand il se trouvera court de mmoire et que la zone suralloue est accde. Le comportement le plus proche de ceci
que nous ayons constat est l'chec de fork parce que le systme avait dcid qu'il n'y avait plus de suffisamment de mmoire disponible pour un nouveau processus. Comme beaucoup d'autres parties d'AIX, la mthode d'allocation de l'espace de pagination et
le out-of-memory kill sont configurables soit pour le systme soit pour un processus, si cela devient un problme.
Rfrences et ressources

Large Program Support . AIX Documentation: General Programming Concepts: Writing and Debugging Programs.
Program Address Space Overview . AIX Documentation: General Programming Concepts: Writing and Debugging Programs.
Performance Overview of the Virtual Memory Manager (VMM) . AIX Documentation: Performance Management Guide.
Page Space Allocation . AIX Documentation: Performance Management Guide.
Paging-space thresholds tuning . AIX Documentation: Performance Management Guide.
Developing and Porting C and C++ Applications on AIX. IBM Redbook.

15.9.2. Cygwin
PostgreSQL peut tre construit avec Cygwin, un environnement similaire Linux pour Windows, mais cette mthode est infrieure la version native Windows (voir Chapitre 16, Installation partir du code source sur Windows) et faire tourner un serveur sur Cygwin n'est plus recommand.
Quand vous compilez partir des sources, suivant la procdure normale d'installation (c'est--dire ./configure; make;
etc...), notez les diffrences suivantes spcifiques Cygwin :

Positionnez le path pour utiliser le rpertoire binaire Cygwin avant celui des utilitaires Windows. Cela permettra d'viter des
problmes avec la compilation.

La commande make GNU est appele make, pas gmake.

La commande adduser n'est pas supporte ; utilisez les outils appropris de gestion d'utilisateurs sous Windows NT, 2000 ou
XP. Sinon, sautez cette tape.

La commande su n'est pas supporte ; utilisez ssh pour simuler la commande su sous Windows NT, 2000 ou XP. Sinon, sautez
cette tape.

OpenSSL n'est pas support.

Dmarrez cygserver pour le support de la mmoire partage. Pour cela, entrez la commande /usr/sbin/cygserver &.
Ce programme doit fonctionner chaque fois que vous dmarrez le serveur PostgreSQL ou que vous initialisez un cluster de
bases de donnes (initdb). La configuration par dfaut de cygserver pourrait ncessiter des changements (par exemple, augmenter SEMMNS) pour viter PostgreSQL d'chouer en raison d'un manque de ressources systme.
297

Procdure d'installation de PostgreSQL du


code source

Il se peut que la construction choue sur certains systme quand une locale autre que C est utilise. Pour rsoudre ce problme,
positionnez la locale C avec la commande export LANG=C.utf8 avant de lancer la construction, et ensuite, une fois que
vous avez install PostgreSQL, repositionnez-l son ancienne valeur.

Les tests de rgression en parallle (make check) peuvent gnrer des checs de tests de rgression alatoires en raison d'un
dpassement de capacit de la file d'attente de listen() qui cause des erreurs de connexion refuse ou des blocages. Vous
pouvez limiter le nombre de connexion en utilisant la variable de make MAX_CONNECTIONS comme ceci :
make MAX_CONNECTIONS=5 check
(Sur certains systmes, vous pouvez avoir jusqu' 10 connexions simultanes).

Il est possible d'installer cygserver et le serveur PostgreSQL en tant que services Windows NT. Pour plus d'informations sur comment le faire, veuillez vous rfrer au document README inclus avec le package binaire PostgreSQL sur Cygwin. Il est install
dans le rpertoire /usr/share/doc/Cygwin.

15.9.3. HP-UX
PostgreSQL 7.3 et plus devraient fonctionner sur les machines PA-RISC Sries 700/800 sous HP-UX 10.X ou 11.X, si les correctifs appropris sur le systme et les outils de compilation sont bien appliqus. Au moins un dveloppeur teste de faon rgulire
sur HP-UX 10.20, et nous avons des rapports d'installations russies sur HP-UX 11.00 et 11.11.
En plus de la distribution source de PostgreSQL, vous aurez besoin de GNU make (le make HP ne fonctionnera pas) et soit GCC
soit le compilateur ANSI HP. Si vous avez l'intention de compiler partir des sources Git plutt que d'une distribution tar, vous
aurez aussi besoin de Flex (les GNU) et Bison (yacc GNU). Nous vous recommandons aussi de vous assurer que vous tes assez
jour sur les correctifs HP. Au minimum, si vous compilez des binaires 64 bits sur HP-UX 11.11, vous aurez probablement besoin
de PHSS_30966 (11.11) ou d'un correctif suprieur, sinon initdb pourrait bloquer :
PHSS_30966 s700_800 ld(1) and linker tools cumulative patch
De faon gnrale, vous devriez tre jour sur les correctifs libc et ld/dld, ainsi que sur les correctifs du compilateur si vous utilisez le compilateur C de HP. Voir les sites de support HP comme http://itrc.hp.com et ftp://us-ffs.external.hp.com/ pour tlcharger
gratuitement leurs derniers correctifs.
Si vous compilez sur une machine PA-RISC 2.0 et que vous voulez avoir des binaires 64 bits en utilisant GCC, vous devez utiliser
la version 64 bits de GCC. Des binaires GCC pour HP-UX PA-RISC et Itanium sont disponibles sur http://www.hp.com/go/gcc.
N'oubliez pas de rcuprer et d'installer les binutils en mme temps.
Si vous compilez sur une machine PA-RISC 2.0 et que vous voulez que les binaires compils fonctionnent sur une machine PARISC 1.1, vous devez spcifier +DAportable comme CFLAGS.
Si vous compilez sur une machine HP-UX Itanium, vous aurez besoin du dernier compilateur C ANSI HP avec les correctifs qui
en dpendent :
PHSS_30848 s700_800 HP C Compiler (A.05.57)
PHSS_30849 s700_800 u2comp/be/plugin library Patch
Si vous avez la fois le compilateur C HP et celui de GCC, vous voudrez peut tre spcifier explicitement le compilateur utiliser
quand vous excuterez configure :
./configure CC=cc
pour le compilateur HP, ou
./configure CC=gcc
pour GCC. Si vous omettez ce paramtre, configure choisira gcc s'il en a la possibilit.
Le rpertoire par dfaut d'installation est /usr/local/pgsql, que vous voudrez peut tre remplacer par quelque chose dans /
opt. Si c'est le cas, utilisez l'option --prefix de configure.
Dans les tests de rgression, il pourrait y avoir des diffrences dans les chiffres les moins significatifs des tests de gomtrie, qui
varient suivant les versions de compilateur et de bibliothque mathmatique utilises. Toute autre erreur est suspecte.

15.9.4. IRIX
298

Procdure d'installation de PostgreSQL du


code source
PostgreSQL a t rapport comme fonctionnant correctement sur les processeurs MIPS r8000, r10000 ( la fois ip25 et ip27) et
r120000 (ip35), sur IRIX 6.5.5m, 6.5.12, 6.5.13, et 6.5.26 avec les compilateurs MIPSPro de versions 7.30, 7.3.1.2m, 7.3, et
7.4.4m.
Vous aurez besoin du compilateur C ANSI MIPSPro. Il y a des problmes la compilation avec GCC. C'est d un bogue GCC
connu (non corrig en version 3.0), li l'utilisation de fonctions qui retournent certains types de structures. Ce bogue affecte des
fonctions telles que inet_ntoa, inet_lnaof, inet_netof, inet_makeaddr, et semctl. Il semblerait qu'on puisse rsoudre le problme en forant les fonctions l'diteur de liens avec libgcc, mais ceci n'a pas encore t test.
Il est connu que la version 7.4.1m du compilateur MIPSPro gnre du code incorrect. Le symptme est invalid primary checkpoint record quand on tente de dmarrer la base. La version 7.4.4m est OK ; le statut des versions intermdiaires est inconnu.
Il pourrait y avoir un problme de compilation comme celui-ci :
cc-1020 cc: ERROR File = pqcomm.c, Line = 427
The identifier "TCP_NODELAY" is undefined.
if (setsockopt(port->sock, IPPROTO_TCP, TCP_NODELAY,
Certaines versions incluent les dfinitions TCP dans sys/xti.h, il est alors ncessaire d'ajouter #include <sys/xti.h>
dans src/backend/libpq/pqcomm.c et dans src/interfaces/libpq/fe-connect.c. Si vous rencontrez ce problme, merci de nous le faire savoir, afin que nous puissions dvelopper un correctif appropri.
Dans les tests de rgression, il pourrait y avoir des diffrences dans les chiffres les moins significatifs des tests de gomtrie, suivant le FPU que vous utilisez. Toute autre erreur est suspecte.

15.9.5. MinGW/Windows Natif


PostgreSQL pour Windows peut tre compil en utilisant MinGW, un environnement de compilation similaire Unix pour les
systmes d'exploitation Microsoft, ou en utilisant la suite de compilation Visual C++ de Microsoft. La variante de compilation
MinGW utilise le systme de compilation normal dcrit dans ce chapitre ; la compilation via Visual C++ fonctionne de faon totalement diffrente et est dcrite dans la documentationChapitre 16, Installation partir du code source sur Windows. C'est une
compilation totalement native qui n'utilise aucun logiciel supplmentaire comme MinGW. Un installeur est disponible sur le serveur web officiel de PostgreSQL.
Le port natif Windows requiert un systme Microsoft 200 ou ultrieurs, 32 bits ou 64 bits. Les systmes plus anciens n'ont pas
l'infrastructure ncessaire (mais Cygwin peut tre utilis pour ceux-ci). MinGW, le systme de compilation similaire Unix, et
MSYS, une suite d'outils Unix ncessaires pour excuter des scripts shell tels que configure, peuvent tre tlchargs de
http://www.mingw.org/. Aucun de ces outils n'est ncessaire pour excuter les binaires gnrs ; ils ne sont ncessaires que pour
crer les binaires.
Pour construire les binaires 64 bits avec MinGW, installez l'ensemble d'outils 64 bits partir de
http://mingw-w64.sourceforge.net/, ajoutez le rpertoire des binaires de MinGW dans la variable d'environnement PATH, et lancez
la commande configure avec l'option --host=x86_64-w64-mingw.
Aprs que vous ayez tout install, il vous est conseill de lancer psql dans CMD.EXE, car la console MSYS a des problmes de
tampons.

15.9.5.1. Rcuprer des dumps suite aux plantages sous Windows


Si PostgreSQL sous Windows plante, il peut gnrer des minidumps qui peuvent tre utiliss pour dpister la cause du plantage ; ils sont semblables aux core dumps d'Unix. Vous pouvez lire ces dumps avec Windows Debugger Tools ou avec Visual
Studio. Pour permettre la gnration des dumps sous Windows, crz un sous-rpertoire nomm crashdumps dans le rpertoire des donnes du cluster. Ainsi les dumps seront crits dans ce rpertoire avec un nom unique gnr partir de l'identifiant du
process plant et le moment du plantage.

15.9.6. SCO OpenServer et SCO UnixWare


PostgreSQL peut tre compil sur SCO UnixWare 7 et SCO OpenServer 5. Sur OpenServer, vous pouvez utiliser soit
l'OpenServer Development Kit soit l'Universal Development Kit. Toutefois, quelques ajustements peuvent tre ncessaires,
comme dcrit ci-dessous.

15.9.6.1. Skunkware
Vous aurez besoin de votre copie du CD SCO Skunkware. Le CD Skunkware est inclus avec UnixWare 7 et les versions actuelles
d'OpenServer 5. Skunkware inclut des versions prtes l'installation de nombreux programmes populaires qui sont disponibles sur
Internet. Par exemple, sont inclus gzip, gunzip, GNU Make, Flex et Bison. Pour UnixWare 7.1, ce CD est maintenant appel
299

Procdure d'installation de PostgreSQL du


code source
Open License Software Supplement . Si vous n'avez pas ce CD, les logiciels qu'il contient sont disponibles sur le serveur FTP
anonyme http://www.sco.com/skunkware/.
Les versions de Skunkware sont diffrentes entre UnixWare et OpenServer. Faites attention installer la version correcte pour
votre systme d'exploitation, sauf pour les cas notifis ci-dessous.
Sous UnixWare 7.1.3 et suprieur, le compilateur GCC est inclus sur le CD UDK, ainsi que GNU Make.

15.9.6.2. GNU Make


Vous devez utiliser le programme GNU Make, qui est inclus sur le CD Skunkware. Par dfaut, il s'installe en tant que /
usr/local/bin/make. Pour viter la confusion avec le programme make SCO, vous pouvez renommer GNU make en
gmake.
partir d'UnixWare 7.1.3, le programme GNU Make est dans la portion OSTK du CD UDK, et est dans /
usr/gnu/bin/gmake.

15.9.6.3. Readline
La bibliothque Readline est disponible sur le CD Skunkware, mais pas sur le CD Skunkware d'UnixWare 7.1. Si vous avez UnixWare 7.0.0 ou 7.0.1, vous pouvez installer partir du CD, sinon essayez http://www.sco.com/skunkware/.
Par dfaut, Readline s'installe dans /usr/local/lib et /usr/local/include. Toutefois, le programme configure de
PostgreSQL ne la trouvera pas l sans aide. Si vous avez install Readline, alors utilisez les options suivantes avec configure :
./configure --with-libraries=/usr/local/lib --with-includes=/usr/local/include

15.9.6.4. Utilisation de l'UDK avec OpenServer


Si vous utilisez le nouveau compilateur Universal Development Kit (UDK) avec OpenServer, vous devez spcifier l'emplacement
des bibliothques UDK :
./configure --with-libraries=/udk/usr/lib --with-includes=/udk/usr/include
Ajout aux options Readline prcdentes, cela donne :
./configure --with-libraries="/udk/usr/lib /usr/local/lib"
--with-includes="/udk/usr/include /usr/local/include"

15.9.6.5. Lire les man pages de PostgreSQL


Par dfaut, les man pages PostgreSQL sont installes dans /usr/local/pgsql/man. Par dfaut, UnixWare ne recherche pas
de man pages cet endroit. Pour pouvoir les lire, vous devez modifier la variable MANPATH pour y inclure /
etc/default/man, par exemple :

MANPATH=/usr/lib/scohelp/%L/man:/usr/dt/man:/usr/man:/usr/share/man:scohelp:/usr/local/man:/
Sur OpenServer, un effort supplmentaire devra tre fait pour rendre les man pages utilisables, parce que le systme man est un
peu diffrent de celui des autres plateformes. l'heure actuelle, PostgreSQL ne les installera pas du tout.

15.9.6.6. Problmes C99 avec le 7.1.1b Feature Supplement


Pour les compilateurs antrieurs celui fourni avec OpenUNIX 8.0.0 (UnixWare 7.1.2), dont celui du 7.1.1b Feature Supplement,
vous pourriez avoir besoin de spcifier -Xb dans CFLAGS ou la variable d'environnement CC. Ce qui l'annonce est une erreur
dans la compilation de tuplesort.c, sur les fonctions inline. Apparemment, il y a eu un changement dans le compilateur 7.1.2
(8.0.0) et les suivants.

15.9.6.7. Threads avec UnixWare


Pour les threads, vous devez utiliser -Kpthread sur tous les programmes utilisant libpq. libpq utilise des appels pthread_*,
qui ne sont disponibles qu'avec l'option -Kpthread/-Kthread.

15.9.7. Solaris
PostgreSQL est bien support sous Solaris. Plus le systme d'exploitation est jour, moins de problmes vous aurez ; les dtails
300

Procdure d'installation de PostgreSQL du


code source
sont ci-dessous.

15.9.7.1. Outils requis


Vous pouvez compiler soit avec GCC, soit avec le compilateur de Sun. Pour une meilleure optimisation du code, le compilateur de
Sun est fortement recommand sur l'architecture SPARC. Il y a eu des problmes rapports l'utilisation de GCC 2.95.1 ; des versions de GCC 2.95.3 ou suprieure sont recommandes. Si vous utilisez le compilateur de Sun, attention ne pas slectionner /
usr/ucb/cc ; utilisez /opt/SUNWspro/bin/cc.
Vous pouvez tlcharger Sun Studio sur http://developers.sun.com/sunstudio/downloads/. De nombreux outils GNU sont intgrs
dans Solaris 10, ou sont prsents sur le Solaris companion CD. Si vous voulez des packages pour des plus anciennes versions de
Solaris, vous pouvez trouver ces outils sur http://www.sunfreeware.com ou http://www.blastwave.org. Si vous prfrez les
sources, allez sur http://www.gnu.org/order/ftp.html.

15.9.7.2. Problmes avec OpenSSL


Quand vous compilez PostgreSQL avec le support OpenSSL, vous pourriez rencontrer des erreurs de compilation dans les fichiers
suivants :

src/backend/libpq/crypt.c

src/backend/libpq/password.c

src/interfaces/libpq/fe-auth.c

src/interfaces/libpq/fe-connect.c

C'est en raison d'un conflit d'espace de nom entre l'en-tte standard /usr/include/crypt.h et les fichiers d'en-tte fournis
par OpenSSL.
La mise jour de l'installation d'OpenSSL vers la version 0.9.6a rsout ce problme. Solaris 9 et suprieurs ont une version plus
rcente d'OpenSSL.

15.9.7.3. configure se plaint d'un programme de test en chec


Si configure se plaint d'un programme de test en chec, c'est probablement un cas de l'diteur de lien l'excution qui ne trouve
pas une bibliothque, probablement libz, libreadline ou une autre bibliothque non standard telle que libssl. Pour l'amener au bon
endroit, positionnez la variable d'environnement LDFLAGS sur la ligne de commande de configure, par exemple,
configure ... LDFLAGS="-R /usr/sfw/lib:/opt/sfw/lib:/usr/local/lib"
Voir la man page de ld(1) pour plus d'informations.

15.9.7.4. La compilation 64-bit plante parfois


Dans Solaris 7 et prcdentes, la version 64 bits de la libc a une routine vsnprintf bogue, qui gnre des core dumps alatoires dans PostgreSQL. Le contournement le plus simple connu est de forcer PostgreSQL utiliser sa propre version de vsnprintf plutt que celle de la bibliothque. Pour faire ceci, aprs avoir excut configure, ditez un des fichiers produits par
configure. Dans src/Makefile.global, modifiez la ligne
LIBOBJS =
par
LIBOBJS = snprintf.o
(Il pourrait y avoir d'autres fichiers dj lists dans cette variable. L'ordre est sans importance.) Puis compilez comme d'habitude.

15.9.7.5. Compiler pour des performances optimales


Sur l'architecture SPARC, Sun Studio est fortement recommand pour la compilation. Essayez d'utiliser l'option d'optimisation xO5 pour gnrer des binaires sensiblement plus rapides. N'utilisez pas d'options qui modifient le comportement des oprations
virgule flottante et le traitement de errno (par exemple, -fast). Ces options pourraient amener des comportements PostgreSQL
non standard, par exemple dans le calcul des dates/temps.
Si vous n'avez pas de raison d'utiliser des binaires 64 bits sur SPARC, prfrez la version 32 bits. Les oprations et les binaires 64
bits sont plus lents que les variantes 32 bits. D'un autre ct, le code 32 bits sur un processeur de la famille AMD64 n'est pas natif,
ce qui fait que le code 32 bits est significativement plus lent sur cette famille de processeurs.
301

Procdure d'installation de PostgreSQL du


code source
Des astuces pour optimiser les performances de PostgreSQL sur Solaris peuvent tre trouves sur
http://www.sun.com/servers/coolthreads/tnb/applications_postgresql.jsp. Cet article se focalise principalement sur la plateforme
T2000, mais beaucoup des recommandations sont aussi utiles avec d'autres plateformes sous Solaris.

15.9.7.6. Utiliser DTrace pour tracer PostgreSQL


Oui, l'utilisation de DTrace est possible. Voir la documentation Section 27.4, Traces dynamiques pour davantage
d'informations.
Vous
pouvez
aussi
trouver
plus
d'informations
dans
cet
article
:
http://blogs.sun.com/robertlor/entry/user_level_dtrace_probes_in.
Si vous voyez l'dition de liens de l'excutable postgres chouer avec un message d'erreur similaire :
Undefined
first referenced
symbol
in file
AbortTransaction
utils/probes.o
CommitTransaction
utils/probes.o
ld: fatal: Symbol referencing errors. No output written to postgres
collect2: ld returned 1 exit status
gmake: *** [postgres] Error 1
l'installation DTrace est trop ancienne pour grer les sondes dans les fonctions statiques. Solaris 10u4 ou plus rcent est ncessaire.

302

Chapitre 16. Installation partir du code source sur


Windows
Il est recommand que la plupart des utilisateurs tlchargent la distribution binaire pour Windows, disponible sous la forme
d'un package d'installation one-click partir du site web de PostgreSQL. Construire partir des sources a pour seule cible
les personnes qui dveloppent PostgreSQL ou des extensions.
Il existe diffrentes faons de construire PostgreSQL sur Windows. La faon la plus simple de le faire est d'utiliser les outils
Microsoft. Pour cela, il faut installer une version supporte du Microsoft Platform SDK et d'utiliser le compilateur inclus. Il
est aussi possible de construire PostgreSQL avec Microsoft Visual C++ 2005 ou 2008. Dans certains cas, il faut installer le
Platform SDK en plus du compilateur.
Il est aussi possible de construire PostgreSQL en utilisant les outils de compilation GNU fournis par MinGW ou en utilisant
Cygwin pour les anciennes versions de Windows.
Enfin, la bibliothque d'accs pour les clients (libpq) peut tre construit en utilisant Visual C++ 7.1 ou Borland C++ pour la
compatibilit avec des applications lies statiquement en utilisant ces outils.
La construction par MinGW ou Cygwin utilise le systme habituel de construction, voir Chapitre 15, Procdure
d'installation de PostgreSQL du code source et les notes spcifiques dans Section 15.9.5, MinGW/Windows Natif et Section 15.9.2, Cygwin . Pour produire des binaires natifs 64 bits dans ces environnements, utilisez les outils de MinGW-w64.
Ces outils peuvent galement tre utiliss pour faire de la cross-compilation pour les systmes Windows 32 et 64 bits sur
d'autres machines, telles que Linux et Darwin. Il n'est pas recommand d'utiliser Cygwin pour faire fonctionner un serveur de production. Il devrait uniquement tre utilis pour le fonctionnement sur d'anciennes versions de Windows, o le
build natif ne fonctionne pas, comme Windows 98. Les excutables officiels sont construits avec Visual Studio.
Les builds natifs de psql ne supportent pas l'dition de la ligne de commande. La version de psql construite avec Cygwin supporte l'dition de ligne de commande, donc elle devrait tre utilise l o on a besoin de psql pour des besoins interactifs sous
Windows.

16.1. Construire avec Visual C++ ou le Platform SDK


PostgreSQL peut tre construit en utilisant la suite de compilation Visual C++ de Microsoft. Ces compilateurs peuvent tre soit
Visual Studio, soit Visual Studio Express soit certaines versions du Platform SDK. Si vous n'avez pas dj un environnement Visual Studio configur, la faon la plus simple est d'utiliser les compilateurs du Platform SDK, tlchargement libre
chez Microsoft.
PostgreSQL supporte les compilateurs de Visual Studio 2005 et Visual Studio 2008. Lors de l'utilisation du Platform SDK
seul ou lors de la construction pour Windows 64 bits, seul Visual Studio 2008 est support. Visual Studio 2010 n'est pas
encore support.
Lorsque vous construisez avec le Platform SDK, les versions 6.0 7.0 du SDK sont supportes. Les versions plus anciennes
ou plus rcentes ne fonctionneront pas. En particulier, les versions partir de la 7.0a ne fonctionneront par, car elles incluent des
compilateurs de Visual Studio 2010.
Les outils pour construire en utilisant Visual C++ se trouvent dans le rpertoire src/tools/msvc. Lors de la construction,
assurez-vous qu'il n'y a pas d'outils provenant de MinGW ou Cygwin dans le chemin (PATH) de votre environnement.
Dans Visual Studio, lancez l'invite de Visual Studio. Dans le Platform SDK, lancez le CMD shell list sous le rpertoire
SDL du menu de dmarrage. Si vous souhaitez construire une version 64-bits, vous devez utiliser la version 64-bit de la commande, et vice versa. Toutes les commandes devraient tre excutes partir du rpertoire src\tools\msvc.
Avant de lancer la construction, vous aurez besoin d'diter le fichier config.pl pour y modifier toutes les options de configuration ncessaires, ainsi que les chemins utiliss par les bibliothques de tierces parties. La configuration complte est dtermine tout d'abord en lisant et en analysant le fichier config_default.pl, puis en appliquant les modifications provenant du
fichier config.pl. Par exemple, pour indiquer l'emplacement de votre installation de Python, placez la ligne suivante dans
config.pl :
$config->{python} = 'c:\python26';
Vous avez seulement besoin de spcifier les paramtres qui sont diffrents de la configuration par dfaut, spcifie par le fichier
config_default.pl.
Si vous avez besoin de configurer d'autres variables d'environnement, crez un fichier appel buildenv.pl et placez-y les
commandes souhaites. Par exemple, pour ajouter le chemin vers bison s'il ne se trouve pas dans le PATH, crez un fichier
303

Installation partir du code source sur Windows


contenant :
$ENV{PATH}=$ENV{PATH} . ';c:\chemin\vers\bison\bin';

16.1.1. Pr-requis
Les outils supplmentaires suivants sont requis pour construire PostgreSQL. Utilisez le fichier config.pl pour indiquer les
rpertoires o se trouvent les bibliothques.
Microsoft Platform SDK
Il est recommand de mettre jour avec la dernire version supporte du Microsoft Platform SDK (actuellement la version
7.0), tlchargeable sur http://www.microsoft.com/downloads/.
Vous devez toujours inclure la partie Windows Headers and Libraries du SDK. Si vous installez le Platform SDK incluant
les compilateurs (Visual C++ Compilers), vous n'avez pas de Visual Studio.
ActiveState Perl
ActiveState Perl est requis pour excuter les scripts de construction. Le Perl de MinGW et de Cygwin ne fonctionnera pas. Il
doit aussi tre prsent dans le PATH. Les binaires de cet outil sont tlchargeables partir de http://www.activestate.com
(Note : la version 5.8 ou ultrieure est requise, la distribution standard libre est suffisante).
Les produits suivants ne sont pas ncessaires pour commencer, mais sont requis pour installer la distribution complte. Utilisez le
fichier config.pl pour indiquer les rpertoires o sont places les bibliothques.
ActiveState TCL
Requis pour construire PL/TCL (Note : la version 8.4 est requise, la distribution standard libre est suffisante).
Bison et Flex
Bison et Flex sont requis pour construire partir d'une extraction du Git, mais ils ne sont pas ncessaires si vous utilisez une
version package. Notez que seul Bison 1.875 ou les versions 2.2 et ultrieures fonctionneront. De plus, Flex version 2.5.31
ou une version ultrieure est requise. Bison est tlchargeable partir de http://gnuwin32.sourceforge.net. Flex est disponible
sur http://www.postgresql.org/ftp/misc/winflex/.

Note
La distribution Bison de GnuWin32 a apparemment un bug qui cause des disfonctionnements de Bison lorsqu'il est install dans un rpertoire dont le nom contient des espaces, tels que l'emplacement par dfaut dans les
installations en Anglais : C:\Program Files\GnuWin32. Installez donc plutt dans C:\GnuWin32.
Diff
Diff est ncessaire pour excuter les tests de rgression, et peut tre tlcharg partir de http://gnuwin32.sourceforge.net.
Gettext
Gettext est requis pour construire le support NLS, et peut tre tlcharg partir de http://gnuwin32.sourceforge.net. Notez
que les binaires, dpendances et fichiers dveloppeurs sont tous ncessaires.
MIT Kerberos
Requis
pour
le
support
de
l'authentification
http://web.mit.edu/Kerberos/dist/index.html.

Kerberos.

MIT

Kerberos

est

tlchargeable

sur

libxml2 et libxslt
Requis pour le support du XML. Les binaires sont disponibles sur http://zlatkovic.com/pub/libxml et les sources sur
http://xmlsoft.org. Notez que libxml2 ncessite iconv, qui est disponible sur le mme site web.
openssl
Requis
pour
le
support
de
SSL.
Les
binaires
peuvent
tre
tlchargs

partir
de
http://www.slproweb.com/products/Win32OpenSSL.html alors que les sources sont disponibles sur http://www.openssl.org.
ossp-uuid
Requis pour le support d'UUID-OSSP (seulement en contrib). Les sources peuvent tre rcupres sur le site ossp.org.
Python
Requis pour la construction de PL/Python. Les binaires sont tlchargeables sur http://www.python.org.
zlib
304

Installation partir du code source sur Windows


Requis pour le support de la compression dans pg_dump et pg_restore. Les binaires sont disponibles partir de
http://www.zlib.net.

16.1.2. Considrations spciales pour Windows 64-bits


PostgreSQL ne peut tre compil pour l'architecture x64 que sur Windows 64-bits, il n'y a pas de support pour les processeurs Itanium.
Mixer des versions 32-bits et des versions 64-bits dans le mme rpertoire de construction n'est pas support. Le systme de compilation dtectera automatiquement si l'environnement est 32-bits ou 64-bits, et construira PostgreSQL en accord. Pour cette raison, il est important de commencer avec la bonne invite de commande avant de lancer la compilation.
Pour utiliser une bibliothque de tierce partie ct serveur comme python ou openssl, cette bibliothque doit aussi tre en
64-bits. Il n'y a pas de support pour le chargement d'une bibliothque 32-bits sur un serveur 64-bits. Plusieurs bibliothques de
tierce partie que PostgreSQL supporte ne sont disponibles qu'en version 32-bits, auquel cas elles ne peuvent pas tre utilises avec
un PostgreSQL 64-bits.

16.1.3. Construction
Pour construire tout PostgreSQL dans la configuration par dfaut, excutez la commande :

build

Pour construire tout PostgreSQL dans la configuration de dbogage, excutez la commande :

build DEBUG

Pour construire un seul projet, par exemple psql, excutez les commandes :

build psql
build DEBUG psql

Pour modifier la configuration de construction par dfaut, placez ce qui suit dans le fichier buildenv.pl :

Il est aussi possible de construire partir de l'interface de Visual Studio. Dans ce cas, vous devez excuter :

perl mkvcbuild.pl

partir de l'invite, puis ouvrir le fichier pgsql.sln gnr (dans le rpertoire racine des sources) dans Visual Studio.

16.1.4. Nettoyage et installation


La plupart du temps, la rcupration automatique des dpendances dans Visual Studio prendra en charge les fichiers modifis.
Mais, s'il y a eu trop de modifications, vous pouvez avoir besoin de nettoyer l'installation. Pour cela, excutez simplement la commande clean.bat, qui nettoiera automatiquement les fichiers gnrs. Vous pouvez aussi l'excuter avec le paramtre dist,
auquel cas il se comporte comme make distclean et supprime les fichiers flex/bison en sortie.
Par dfaut, tous les fichiers sont crits dans un sous-rpertoire de debug ou release. Pour installer ces fichiers en utilisant les
emplacements standards et pour gnrer aussi les fichiers requis pour initialiser et utiliser la base de donnes, excutez la commande :
305

Installation partir du code source sur Windows

install c:\destination\directory

16.1.5. Excuter les tests de rgression


Pour excuter les tests de rgression, assurez-vous que vous avez termin la construction de toutes les parties requises. Ensuite, assurez-vous que les DLL ncessaires au chargement de toutes les parties du systme (comme les DLL Perl et Python pour les langages de procdure) sont prsentes dans le chemin systme. Dans le cas contraire, configurez-les dans le fichier buildenv.pl.
Pour lancer les tests, excutez une des commandes suivantes partir du rpertoire src\tools\msvc :

vcregress check
vcregress installcheck
vcregress plcheck
vcregress contribcheck

Pour modifier la planification utilise (en parallle par dfaut), ajoutez-la la ligne de commande, comme :

vcregress check serial

Pour plus d'informations sur les tests de rgression, voir Chapitre 30, Tests de rgression.

16.1.6. Construire la documentation


Construire la documentation PostgreSQL au format HTML ncessite plusieurs outils et fichiers. Crez un rpertoire racine pour
tous ces fichiers et stockez-les dans des sous-rpertoires conformment la liste ci-dessous.
OpenJade 1.3.1-2
tlcharger partir de http://sourceforge.net/projects/openjade/files/openjade/1.3.1/openjade-1_3_1-2-bin.zip/download et
dcompresser dans le sous-rpertoire openjade-1.3.1.
DocBook DTD 4.2
tlcharger partir de http://www.oasis-open.org/docbook/sgml/4.2/docbook-4.2.zip et dcompresser dans le sousrpertoire docbook.
DocBook DSSSL 1.79
tlcharger partir de http://sourceforge.net/projects/docbook/files/docbook-dsssl/1.79/docbook-dsssl-1.79.zip/download et
dcompresser dans le sous-rpertoire docbook-dsssl-1.79.
ISO character entities
tlcharger partir de http://www.oasis-open.org/cover/ISOEnts.zip et dcompresser dans le sous-rpertoire docbook.
Modifiez le fichier buildenv.pl et ajoutez une variable pour l'emplacement du rpertoire racine, par exemple :
$ENV{DOCROOT}='c:\docbook';
Pour construire la documentation, excutez la commande builddoc.bat. Notez que ceci excutera la construction une
deuxime fois, pour gnrer les index. Les fichiers HTML gnrs seront dans le rpertoire doc\src\sgml.

16.2. Construire libpq avec Visual C++ ou Borland C++


306

Installation partir du code source sur Windows


Utiliser Visual C++ 7.1-9.0 ou Borland C++ pour construire libpq est seulement recommand si vous avez besoin d'une version contenant des drapeaux dbogage/version finale, ou si vous avez besoin d'une bibliothque statique que vous lierez une application. Pour une utilisation normale, MinGW et Visual Studio 2005 or Platform SDK method sont recommands.
Pour construire la bibliothque client libpq en utilisant Visual Studio 7.1 (ou ultrieur), allez dans le rpertoire src et excutez
la commande :
nmake /f win32.mak
Pour construire une version 64-bit de la bibliothque client libpq en utilisant Visual Studio 8.0 (ou ultrieur), allez dans le rpertoire src et excutez la commande :
nmake /f win32.mak CPU=AMD64
Voir le fichier win32.mak pour plus de dtails sur les variables supportes.
Pour construire la bibliothque client libpq en utilisant Borland C++, allez dans le rpertoire src et excutez la commande :
make -N -DCFG=Release /f bcc32.mak

16.2.1. Fichiers gnrs


Les fichiers suivants seront produits :
interfaces\libpq\Release\libpq.dll
la bibliothque client ;
interfaces\libpq\Release\libpqdll.lib
la bibliothque d'import ncessaire l'dition de liens avec libpq.dll
interfaces\libpq\Release\libpq.lib
la version statique de la bibliothque d'interface client ;
Habituellement, vous n'avez pas besoin d'installer les fichiers client. Vous devez placer le fichier libpq.dll dans le mme rpertoire que vos applications. N'installez pas libpq.dll dans votre rpertoire Windows, System or System32, sauf en cas
d'absolue ncessit. S'il est install par un programme, ce dernier doit en contrler au pralable la ressource VERSIONINFO afin
d'viter l'crasement d'une version plus rcente.
Si l'on prvoit de dvelopper sur cette machine une application qui utilise libpq, il faut ajouter les sous-rpertoires
src\include et src\interfaces\libpq dans le chemin d'inclusion des sources de votre compilateur.
Pour utiliser la bibliothque, il faut ajouter libpqdll.lib au projet (sous Visual C++, clic droit sur le projet et choisir ajouter).

307

Chapitre 17. Configuration du serveur et mise en


place
Ce chapitre discute de la configuration, du lancement du serveur de bases de donnes et de ses interactions avec le systme
d'exploitation.

17.1. Compte utilisateur PostgreSQL


Comme avec tout dmon serveur accessible au monde externe, il est conseill de lancer PostgreSQL sous un compte utilisateur spar. Ce compte devrait seulement tre le propritaire des donnes gres par le serveur et ne devrait pas tre partag avec
d'autres dmons (par exemple, utiliser l'utilisateur nobody est une mauvaise ide). Il n'est pas conseill de changer le propritaire des excutables par cet utilisateur car les systmes compromis pourraient alors se voir modifier leur propres binaires.
Pour ajouter un compte utilisateur Unix, jetez un il la commande useradd ou adduser de votre systme. Le nom de
l'utilisateur postgres est souvent utilis et l'est sur tout le livre, mais vous pouvez utiliser un autre nom si vous le souhaitez.

17.2. Crer un groupe de base de donnes


Avant de faire quoi que ce soit, vous devez initialiser un emplacement de stockage pour la base de donnes. Nous appelons ceci
un groupe de bases de donnes (sql utilise le terme de groupe de catalogues). Un groupe de bases de donnes est une collection
de bases donnes et est gr par une seule instance d'un serveur de bases de donnes en cours d'excution. Aprs initialisation,
un groupe de bases de donnes contiendra une base de donnes nomme postgres, qui a pour but d'tre la base de donnes
par dfaut utilise par les outils, les utilisateurs et les applications tiers. Le serveur de la base de donnes lui-mme ne requiert
pas la prsence de la base de donnes postgres mais beaucoup d'outils supposent son existence. Une autre base de donnes
est cre l'intrieur de chaque groupe lors de l'initialisation. Elle est appele template1. Comme le nom le suggre, elle sera
utilise comme modle pour les bases de donnes cres aprs ; elle ne devrait pas tre utilise pour un vrai travail (voir le Chapitre 21, Administration des bases de donnes pour des informations sur la cration de nouvelles bases de donnes dans le
groupe).
En terme de systme de fichiers, un groupe de bases de donnes sera un simple rpertoire sous lequel les donnes seront stockes. Nous l'appelons le rpertoire de donnes ou l'emplacement des donnes. Le choix de cet emplacement vous appartient
compltement. Il n'existe pas de valeur par dfaut bien que les emplacements tels que /usr/local/pgsql/data ou /
var/lib/pgsql/data sont populaires. Pour initialiser un groupe de bases de donnes, utilisez la commande initdb(1), installe avec PostgreSQL. L'emplacement dsir sur le groupe de fichier est indiqu par l'option -d, par exemple
$ initdb -D /usr/local/pgsql/data
Notez que vous devez excuter cette commande en tant connect sous le compte de l'utilisateur PostgreSQL dcrit dans la
section prcdente.

Astuce
Comme alternative l'option -d, vous pouvez initialiser la variable d'environnement pgdata.
Autrement, vous pouvez excuter initdb via le programme pg_ctl(1) ainsi :
$ pg_ctl -D /usr/local/pgsql/data initdb
C'est peut-tre plus intuitif si vous utilisez dj pg_ctl pour dmarrer et arrter le serveur (voir Section 17.3, Lancer le serveur
de bases de donnes pour les dtails). Un gros intrt est de ne connatre que cette seule commande pour grer l'instance du
serveur de bases de donnes.
initdb tentera de crer le rpertoire que vous avez spcifi si celui-ci n'existe pas dj. Il est possible qu'il n'ait pas le droit de le
faire (si vous avez suivi notre conseil et cr un compte sans droits). Dans ce cas, vous devez crer le rpertoire vous-mme (en
tant que root) et modifier le propritaire pour qu'il corresponde l'utilisateur PostgreSQL. Voici comment raliser ceci :
root# mkdir /usr/local/pgsql/data
root# chown postgres /usr/local/pgsql/data
root# su postgres
postgres$ initdb -D /usr/local/pgsql/data
initdb refusera de s'excuter si le rpertoire des donnes semble tre dj initialis.

308

Configuration du serveur et mise en place

Comme le rpertoire des donnes contient toutes les donnes stockes par le systme de bases de donnes, il est essentiel qu'il soit
scuris par rapport des accs non autoriss. Du coup, initdb supprimera les droits d'accs tout le monde sauf l'utilisateur PostgreSQL.
Nanmoins, bien que le contenu du rpertoire soit scuris, la configuration d'authentification du client par dfaut permet tout
utilisateur local de se connecter la base de donnes et mme devenir le super-utilisateur de la base de donnes. Si vous ne faites
pas confiance aux utilisateurs locaux, nous vous recommandons d'utiliser une des options -w ou --pwprompt de la commande
initdb pour affecter un mot de passe au super-utilisateur de la base de donnes . De plus, spcifiez -a md5 ou -a
mot_de_passe de faon ce que la mthode d'authentification trust par dfaut ne soit pas utilise ; ou modifiez le fichier
pg_hba.conf gnr aprs l'excution d'initdb (d'autres approches raisonnables incluent l'utilisation de l'authentification peer
ou les droits du systme de fichiers pour restreindre les connexions. Voir le Chapitre 19, Authentification du client pour plus
d'informations).
initdb initialise aussi la locale par dfaut du groupe de bases de donnes. Normalement, elle prends seulement le paramtrage local dans l'environnement et l'applique la base de donnes initialise. Il est possible de spcifier une locale diffrente pour la base
de donnes ; la Section 22.1, Support des locales propose plus d'informations l-dessus. L'ordre de tri utilis par dfaut pour ce
cluster de bases de donnes est initialis par initdb et, bien que vous pouvez crer de nouvelles bases de donnes en utilisant des
ordres de tris diffrents, l'ordre utilis dans les bases de donnes modle que initdb a cr ne peut pas tre modifi sans les supprimer et les re-crer. Cela a aussi un impact sur les performances pour l'utilisation de locales autres que c ou posix. Du coup, il est
important de faire ce choix correctement la premire fois.
initdb configure aussi le codage par dfaut de l'ensemble de caractres pour le groupe de bases de donnes. Normalement, cela
doit tre choisi pour correspondre au paramtrage de la locale. Pour les dtails, voir la Section 22.3, Support des jeux de caractres .

17.2.1. Systmes de fichiers rseaux


Beaucoup d'installations crent les clusters de bases de donnes sur des systmes de fichiers rseau. Parfois, cela utilise directement par NFS. Cela peut aussi passer par un NAS (acronyme de Network Attached Storage), priphrique qui utilise NFS en interne. PostgreSQL ne fait rien de particulier avec les systmes de fichiers NFS, ceci signifiant que PostgreSQL suppose que
NFS se comporte exactement comme les lecteurs connects en local (DAS, acronyme de Direct Attached Storage). Si les implmentations du client et du serveur NFS ont une smantique non standard, cela peut poser des problmes de fiabilit (voir
http://www.time-travellers.org/shane/papers/NFS_considered_harmful.html). En particulier, des critures asynchrones (dcales
dans le temps) sur le serveur NFS peuvent poser des soucis de fiabilit. Si possible, montez les systmes de fichiers NFS en synchrone (autrement dit sans cache) pour viter cela. De mme, le montage NFS n'est pas recommand. Les SAN utilisent un protocole de communication bas-niveau plutt que NFS.

17.3. Lancer le serveur de bases de donnes


Avant qu'une personne ait accs la base de donnes, vous devez dmarrer le serveur de bases de donnes. Le programme serveur
est appel postgres. Le programme postgres doit savoir o trouver les donnes qu'il est suppos utiliser. Ceci se fait avec l'option
-d. Du coup, la faon la plus simple de lancer le serveur est :
$ postgres -D /usr/local/pgsql/data
qui laissera le serveur s'excuter en avant plan. Pour cela, vous devez tre connect en utilisant le compte de l'utilisateur PostgreSQL. Sans l'option -d, le serveur essaiera d'utiliser le rpertoire de donnes nomm par la variable d'environnement pgdata. Si
cette variable ne le fournit pas non plus, le lancement chouera.
Habituellement, il est prfrable de lancer postgres en tche de fond. Pour cela, utilisez la syntaxe shell Unix habituelle :
$ postgres -D /usr/local/pgsql/data >journaux_trace 2>&1 &
Il est important de sauvegarder les sorties stdout et stderr du serveur quelque part, comme montr ci-dessus. Cela vous aidera dans des buts d'audits ou pour diagnostiquer des problmes (voir la Section 23.3, Maintenance du fichier de traces pour une
discussion plus dtaille de la gestion de journaux de trace).
Le programme postgres prend aussi un certain nombre d'autres options en ligne de commande. Pour plus d'informations, voir la
page de rfrence postmaster(1) ainsi que le Chapitre 18, Configuration du serveur ci-dessous.
Cette syntaxe shell peut rapidement devenir ennuyante. Donc, le programme d'emballage pg_ctl(1) est fourni pour simplifier certaines tches. Par exemple :
pg_ctl start -l journaux_trace
lancera le serveur en tche de fond et placera les sorties dans le journal de trace indiqu. L'option -d a la mme signification ici
que pour postgres. pg_ctl est aussi capable d'arrter le serveur.
Normalement, vous lancerez le serveur de bases de donnes lors du dmarrage de l'ordinateur . Les scripts de lancement automa309

Configuration du serveur et mise en place

tique sont spcifiques au systme d'exploitation. Certains sont distribus avec PostgreSQL dans le rpertoire contrib/
start-scripts. En installer un demandera les droits de root.
Diffrents systmes ont diffrentes conventions pour lancer les dmons au dmarrage. La plupart des systmes ont un fichier /
etc/rc.local ou /etc/rc.d/rc.local. D'autres utilisent les rpertoires init.d ou rc.d. Quoi que vous fassiez, le
serveur doit tre excut par le compte utilisateur PostgreSQL et non pas par root ou tout autre utilisateur. Donc, vous devriez
probablement former vos commandes en utilisant su postgres -c '...' . Par exemple :
su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog'
Voici quelques suggestions supplmentaires par systme d'exploitation (dans chaque cas, assurez-vous d'utiliser le bon rpertoire
d'installation et le bon nom de l'utilisateur o nous montrons des valeurs gnriques).

Pour freebsd, regardez le fichier contrib/start-scripts/freebsd du rpertoire des sources de PostgreSQL.

Sur openbsd, ajoutez les lignes suivantes votre fichier /etc/rc.local :


if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then
su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log
-D /usr/local/pgsql/data'
echo -n ' PostgreSQL'
fi

Sur les systmes linux, soit vous ajoutez


/usr/local/pgsql/bin/pg_ctl start -l journaux_trace -D /usr/local/pgsql/data
/etc/rc.d/rc.local ou /etc/rc.local soit vous jetez un il contrib/start-scripts/linux dans le
rpertoire des sources de PostgreSQL.

Sur netbsd, vous pouvez utiliser les scripts de lancement de freebsd ou de linux suivant vos prfrences.

Sur solaris, crez un fichier appel /etc/init.d/PostgreSQL et contenant la ligne suivante :


su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l journaux_trace -D
/usr/local/pgsql/data"
Puis, crez un lien symbolique vers lui dans /etc/rc3.d de nom s99PostgreSQL.

Tant que le serveur est lanc, son pid est stock dans le fichier postmaster.pid du rpertoire de donnes. C'est utilis pour
empcher plusieurs instances du serveur d'tre excutes dans le mme rpertoire de donnes et peut aussi tre utilis pour arrter
le processus le serveur.

17.3.1. checs de lancement


Il existe de nombreuses raisons habituelles pour lesquelles le serveur chouerait au lancement. Vrifiez le journal des traces du
serveur ou lancez-le manuellement (sans redirection des sorties standard et d'erreur) et regardez les messages d'erreurs qui apparaissent. Nous en expliquons certains ci-dessous parmi les messages d'erreurs les plus communs.
LOG: could not bind IPv4 socket: Address already in use
HINT: Is another postmaster already running on port 5432? If not, wait a few seconds
and retry.
FATAL: could not create TCP/IP listen socket
Ceci signifie seulement ce que cela suggre : vous avez essay de lancer un autre serveur sur le mme port o un autre est en cours
d'excution. Nanmoins, si le message d'erreur du noyau n'est pas address already in use ou une quelconque variante, il
pourrait y avoir un autre problme. Par exemple, essayer de lancer un serveur sur un numro de port rserv pourrait avoir ce rsultat :
$ postgres -p 666
LOG: could not bind IPv4 socket: Permission denied
HINT: Is another postmaster already running on port 666? If not, wait a few seconds
and retry.
FATAL: could not create TCP/IP listen socket
Un message du type
FATAL: could not create shared memory segment: Invalid argument
DETAIL: Failed system call was shmget(key=5440001, size=4011376640, 03600).
signifie probablement que les limites de votre noyau sur la taille de la mmoire partage est plus petite que l'aire de fonctionne310

Configuration du serveur et mise en place

ment que PostgreSQL essaie de crer (4011376640 octets dans cet exemple). Ou il pourrait signifier que vous n'avez pas du tout
configur le support de la mmoire partage de type System-V dans votre noyau. Comme contournement temporaire, vous pouvez
essayer de lancer le serveur avec un nombre de tampons plus petit que la normale (shared_buffers). ventuellement, vous pouvez
reconfigurer votre noyau pour accrotre la taille de mmoire partage autorise. Vous pourriez voir aussi ce message en essayant
d'excuter plusieurs serveurs sur la mme machine si le total de l'espace qu'ils requirent dpasse la limite du noyau.
Une erreur du type
FATAL: could not create semaphores: No space left on device
DETAIL: Failed system call was semget(5440126, 17, 03600).
ne signifie pas qu'il vous manque de l'espace disque. Elle signifie que la limite de votre noyau sur le nombre de smaphores system v est infrieure au nombre que PostgreSQL veut crer. Comme ci-dessus, vous pouvez contourner le problme en lanant
le serveur avec un nombre rduit de connexions autorises (max_connections) mais vous voudrez ventuellement augmenter la limite du noyau.
Si vous obtenez une erreur illegal system call , il est probable que la mmoire partage ou les smaphores ne sont pas du tout
supports par votre noyau. Dans ce cas, votre seule option est de reconfigurer le noyau pour activer ces fonctionnalits.
Des dtails sur la configuration des capacits ipc System V sont donns dans la Section 17.4.1, Mmoire partage et smaphore .

17.3.2. Problmes de connexion du client


Bien que les conditions d'erreurs possibles du ct client sont assez varies et dpendantes de l'application, certaines pourraient
tre en relation direct avec la faon dont le serveur a t lanc. Les conditions autres que celles montres ici devraient tre documentes avec l'application client respective.
psql: could not connect to server: Connection refused
Is the server running on host "server.joe.com" and accepting
TCP/IP connections on port 5432?
Ceci est l'chec gnrique je n'ai pas trouv de serveur qui parler . Cela ressemble au message ci-dessus lorsqu'une connexion
TCP/IP est tente. Une erreur commune est d'oublier de configurer le serveur pour qu'il autorise les connexions TCP/IP.
Autrement, vous obtiendrez ceci en essayant une communication de type socket de domaine Unix vers un serveur local :
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
La dernire ligne est utile pour vrifier si le client essaie de se connecter au bon endroit. Si aucun serveur n'est excut ici, le message d'erreur du noyau sera typiquement soit connection refused soit no such file or directory, comme ce qui
est illustr (il est important de raliser que connection refused, dans ce contexte, ne signifie pas que le serveur a obtenu
une demande de connexion et l'a refus. Ce cas produira un message diffrent comme indiqu dans la Section 19.4, Problmes
d'authentification ). D'autres messages d'erreurs tel que connection timed out pourraient indiquer des problmes plus
fondamentaux comme un manque de connexion rseau.

17.4. Grer les ressources du noyau


Une installation importante de PostgreSQL peut rapidement puiser les limites des ressources du systme d'exploitation (Sur
certains systmes, les valeurs par dfaut sont trop basses que vous n'avez mme pas besoin d'une installation importante .). Si
vous avez rencontr ce type de problme, continuez votre lecture.

17.4.1. Mmoire partage et smaphore


La mmoire partage et les smaphores sont nomms collectivement ipc system v (ensemble avec les queues de messages,
qui n'ont pas d'importance pour PostgreSQL). Pratiquement, tous les systmes d'exploitation modernes fournissent ces fonctionnalits mais, parmi elles, toutes ne sont pas actives ou dimensionnes suffisamment par dfaut, car la mmoire disponible et la
demande des applications augmente. (Sur Windows, PostgreSQL fournit sa propre implmentation de remplacement de ces
fonctionnalits, du coup, ce qui suit peut tre ignor).
Le manque complet de fonctionnalits est gnralement manifest par une erreur illegal system call au lancement du serveur. Dans
ce cas, il n'y a rien faire part reconfigurer votre noyau. PostgreSQL ne fonctionnera pas sans. Nanmoins, cette situation est
rare parmi les systmes d'exploitation modernes.
Quand PostgreSQL dpasse une des nombreuses limites ipc, le serveur refusera de s'excuter et lvera un message d'erreur instructif dcrivant le problme rencontr et que faire avec (voir aussi la Section 17.3.1, checs de lancement ). Les paramtres
311

Configuration du serveur et mise en place

adquats du noyau sont nomms de faon cohrente parmi les diffrents systmes ; le Tableau 17.1, Paramtres system v
ipc donne un aperu. Nanmoins, les mthodes pour les obtenir varient. Les suggestions pour quelques plateformes sont donnes
ci-dessous.
Tableau 17.1. Paramtres system v ipc

Nom

Description

Valeurs raisonnables

shmmax

taille maximum du segment de mmoire partage (octets)

au moins plusieurs mo (voir texte)

shmmin

taille minimum du segment de mmoire partage (octets)

shmall

total de la mmoire partage disponible (octets ou pages)

si octets, identique shmmax ; si pages,


ceil(shmmax/page_size)

shmseg

nombre maximum de segments de mmoire partage par pro- seul un segment est ncessaire mais la valeur par
cessus
dfaut est bien plus importante

shmmni

nombre maximum de segments de mmoire partage pour tout comme shmseg plus la place pour les autres aple systme
plications

semmni

nombre maximum d'identifiants de smaphores (c'est--dire au moins ceil((max_connections + aud'ensembles)


tovacuum_max_workers + 4) / 16)

semmns

nombre maximum de smaphores rpartis dans le systme

ceil((max_connections
+
autovacuum_max_workers = 4) / 16) * 17
plus la place pour les autres applications

semmsl

nombre maximum de smaphores par ensemble

au moins 17

semmap

nombre d'entres dans la carte des smaphores

voir le texte

semvmx

valeur maximum d'un smaphore

au moins 1000 (vaut souvent par dfaut 32767, ne


pas changer sauf si vous tes forc.)

le paramtre de mmoire partag le plus important est shmmax, la taille maximum, en octets, d'un segment de mmoire partage.
Si vous obtenez un message d'erreur partir de shmget comme invalid argument , il est possible que cette limite soit dpasse. La taille du segment de mmoire partage requis dpend de plusieurs paramtres de configuration de PostgreSQL, comme
indiqu dans le Tableau 17.2, Usage de la mmoire partage PostgreSQL (tout message d'erreur obtenu incluera la taille
exacte utilise dans la requte d'allocation qui a chou). Temporairement, vous pouvez baisser certains de ces paramtres pour
viter un chec. Alors qu'il est possible d'obtenir de PostgreSQL qu'il fonctionne avec un shmmax de 2 Mo, vous avez besoin
de bien plus pour obtenir des performances acceptables. Les paramtrages dsirables sont plutt de l'ordre de centaines de Mo
quelques Go.
Certains systmes ont aussi une limite sur le nombre total de mmoire partage dans le systme (shmall). Assurez-vous que cela
soit suffisamment important pour PostgreSQL et quelque autres applications utilisant des segments de mmoire partage (notez
que shmall est mesur en pages plutt qu'en octets sur beaucoup de systmes).
La taille minimum des segments de mmoire partage (shmmin) est moins sensible aux problmes. Elle devrait tre au plus environ 500 Ko pour PostgreSQL (il est habituellement 1). Le nombre maximum de segments au travers du systme (shmmni)
ou par processus (shmseg) a peu de chances de causer un problme sauf s'ils sont configurs zro sur votre systme.
PostgreSQL utilise un smaphore par connexion autorise (max_connections) et par processus autovacuum autoris (autovacuum_max_workers), le tout par ensemble de 16. Chacun de ces ensembles contiendra aussi un 17 smaphore qui contient un
nombre magique pour dtecter la collision avec des ensembles de smaphore utiliss par les autres applications. Le nombre
maximum de smaphores dans le systme est initialis par semmns, qui en consquence doit tre au moins aussi haut que
max_connections plus autovacuum_max_workers plus un extra de chacune des 16 connexions autorises et des processus autovacuum (voir la formule dans le Tableau 17.1, Paramtres system v ipc ). Le paramtre semmni dtermine la limite
sur le nombre d'ensembles de smaphores qui peuvent exister sur le systme un instant prcis. Donc, ce paramtre doit tre au
moins gal ceil((max_connections + autovacuum_max_workers + 4) / 16). Baisser le nombre de
connexions autorises est un contournement temporaire pour les checs qui sont habituellement indiqus par le message no
space left on device , partir de la fonction semget.
Dans certains cas, il pourrait tre ncessaire d'augmenter semmap pour tre au moins dans l'ordre de semmns. Ce paramtre dfinit la taille de la carte de ressources de smaphores, dans laquelle chaque bloc contig de smaphores disponibles ont besoin d'une
entre. Lorsqu'un ensemble de smaphores est libr ou qu'il est enregistr sous une nouvelle entre de carte. Si la carte est pleine,
les smaphores librs sont perdus (jusqu'au redmarrage). La fragmentation de l'espace des smaphores pourrait amener dans le
temps moins de smaphores disponibles.
La paramtre semmsl, qui dtermine le nombre de smaphores dans un ensemble, pourrait valoir au moins 17 pour
312

Configuration du serveur et mise en place

.
D'autres paramtres en relation avec l' annulation de smaphores , tels que semmnu et semume, n'affectent pas PostgreSQL.
AIX
partir de la version 5.1, il ne doit plus tre ncessaire de faire une configuration spciale pour les paramtres tels que SHMMAX, car c'est configur de faon ce que toute la mmoire puisse tre utilise en tant que mmoire partage. C'est le type de
configuration habituellement utilise pour d'autres bases de donnes comme DB/2.
Nanmoins, il pourrait tre ncessaire de modifier l'information globale ulimit dans /etc/security/limits car les limites en dur par dfaut pour les tailles de fichiers (fsize) et les nombres de fichiers (nofiles) pourraient tre trop bas.
bsd/os
Mmoire partage. Par dfaut, seulement 4 Mo de mmoire partage est supporte. Gardez en tte que la mmoire partage
n'est pas paginable ; elle est verrouille en RAM. Pour accrotre la mmoire partage supporte par votre systme, ajoutez ce
qui suit la configuration de votre noyau. Une valeur de 1024 pour shmall reprsente 4 mo de mmoire partage. Pour argumenter la mmoire partage supporte par votre systme, ajoutez quelque chose comme ceci votre configuration du
noyau :
options "SHMALL=8192"
options "SHMMAX=\(SHMALL*PAGE_SIZE\)"
shmall est mesur en pages de 4 Ko, donc une valeur de 1024 reprsente 4 Mo de mmoire partage. Du coup, la configuration ci-dessus augmente l'aire de mmoire partage 32 Mo. Pour ceux utilisant une version 4.3 ou ultrieure, vous aurez probablement besoin d'augmenter kernel_virtual_mb au-dessus de la valeur par dfaut, 248. Une fois tous les changements effectus, recompilez le noyau et redmarrez.
Smaphores. Vous voudrez probablement aussi augmenter le nombre de smaphores ; la somme totale par dfaut du systme
(60) n'autorisera seulement que 50 connexions PostgreSQL. Initialisez les valeurs que vous souhaitez dans le fichier de
configuration du noyau :
options "SEMMNI=40"
options "SEMMNS=240"
freebsd
Les paramtres par dfaut sont seulement acceptables pour de petites installations (par exemple, la valeur par dfaut de shmmax est de 32 mo). Les modifications se font via les interfaces sysctl ou loader. Les paramtres suivants peuvent tre configurs en utilisant sysctl :
$ sysctl -w kern.ipc.shmall=32768
$ sysctl -w kern.ipc.shmmax=134217728
$ sysctl -w kern.ipc.semmap=256
Pour que ces paramtres persistent aprs les redmarrages, modifiez /etc/sysctl.conf.
Les paramtres restant, concernant les smaphores, sont en lecture seule en ce qui concerne sysctl mais peuvent tre modifis
avant le redmarrage en utilisant l'invite loader :
(loader) set kern.ipc.semmni=256
(loader) set kern.ipc.semmns=512
(loader) set kern.ipc.semmnu=256
De faon similaire, ils peuvent tre sauvegards entre les redmarrages dans /boot/loader.conf.
Vous pourriez aussi vouloir configurer votre noyau pour verrouiller la mmoire partage en RAM et l'empcher d'tre envoy
dans la swap. Ceci s'accomplit en utilisant le paramtre kern.ipc.shm_use_phys de sysctl.
En cas d'excution dans une cage FreeBSD en activant security.jail.sysvipc_allowed de sysctl, les postmaster
excuts dans diffrentes cages devront tre excuts par diffrents utilisateurs du systme d'exploitation. Ceci amliore la scurit car cela empche les utilisateurs non root d'interfrer avec la mmoire partage ou les smaphores d'une cage diffrente
et cela permet au code de nettoyage des IPC PostgreSQL de fonctionner correctement (dans FreeBSD 6.0 et ultrieurs, le code
de nettoyage IPC ne dtecte pas proprement les processus des autres cages, empchant les postmaster en cours d'excution
d'utiliser le mme port dans diffrentes cages).
Les FreeBSD, avant la 4.0, fonctionnent comme OpenBSD (voir ci-dessous).
NetBSD
Avec NetBSD 5.0 et ultrieur, les paramtres IPC peuvent tre ajusts en utilisant sysctl. Par exemple :

313

Configuration du serveur et mise en place

$ sysctl -w kern.ipc.shmmax=16777216
Pour que ce paramtrage persiste aprs un redmarrage, modifiez le fichier /etc/sysctl.conf.
Vous pourriez aussi vouloir configurer votre noyau pour verrouiller la mmoire partage en RAM et l'empcher d'tre mise
dans le swap. Cela peut se faire en utilisant le paramtre kern.ipc.shm_use_phys de sysctl.
Les versions de NetBSD antrieures la 5.0 fonctionnent comme OpenBSD (voir ci-dessous), sauf que les paramtres
doivent tre configurs avec le mot cl options, et non pas option.
OpenBSD
Les options sysvshm et sysvsem doivent tre actives la compilation du noyau (ils le sont par dfaut). La taille maximum de mmoire partage est dtermine par l'option shmmaxpgs (en pages). Ce qui suit montre un exemple de
l'initialisation des diffrents paramtres :
option
option
option

SYSVSHM
SHMMAXPGS=4096
SHMSEG=256

option
option
option
option
option

SYSVSEM
SEMMNI=256
SEMMNS=512
SEMMNU=256
SEMMAP=256

Vous pourriez aussi vouloir configurer votre noyau pour verrouiller la mmoire partage en RAM et l'empcher d'tre pagine
en swap. Ceci se fait en utilisant le paramtre kern.ipc.shm_use_phys de sysctl.
hp-ux
Les paramtres par dfaut tendent suffire pour des installations normales. Sur hp-ux 10, la valeur par dfaut de semmns
est 128, qui pourrait tre trop basse pour de gros sites de bases de donnes.
Les paramtres ipc peuvent tre initialiss dans system administration manager (sam) sous kernel configuration configurable Parameters. Allez sur create a new kernel une fois termine.
linux
La taille maximale du segment par dfaut est de 32 Mo, ce qui n'est adquat que pour les trs petites installations de PostgreSQL. La taille totale maximale par dfaut est de 2097152 pages. Une page quivaut pratiquement toujours 4096 octets sauf
pour certaines configurations inhabituelles du noyau comme huge pages (utilisez getconf PAGE_SIZE pour vrifier).
Cela donne une limite par dfaut de 8 Go, ce qui est souvent suffisant.
La configuration de la taille de mmoire partage peut tre modifie avec l'interface propose par la commande sysctl. Par
exemple, pour permettre l'utilisation de 16 Go :
$ sysctl -w kernel.shmmax=17179869184
$ sysctl -w kernel.shmall=4194304
De plus, ces paramtres peuvent tre prservs entre des redmarrages dans le fichier /etc/sysctl.conf. Il est recommand de le faire.
Les anciennes distributions pourraient ne pas avoir le programme sysctl mais des modifications quivalentes peuvent se faire
en manipulant le systme de fichiers /proc :
$ echo 17179869184 >/proc/sys/kernel/shmmax
$ echo 4194304 >/proc/sys/kernel/shmall
Les valeurs par dfaut restantes sont tailles de faon assez gnreuses pour ne pas ncessiter de modifications.
Mac OS X
La mthode recommande pour configurer la mmoire partage sous OS X est de crer un fichier nomm /
etc/sysctl.conf contenant des affectations de variables comme :
kern.sysv.shmmax=4194304
kern.sysv.shmmin=1
kern.sysv.shmmni=32
kern.sysv.shmseg=8
kern.sysv.shmall=1024
314

Configuration du serveur et mise en place

Notez que, dans certaines versions d'OS X, les cinq paramtres de mmoire partage doivent tre configurs dans /
etc/sysctl.conf, sinon les valeurs seront ignores.
Attention au fait que les versions rcentes d'OS X ignorent les tentatives de configuration de SHMMAX une valeur qui n'est
pas un multiple exact de 4096.
SHMALL est mesur en page de 4 Ko sur cette plateforme.
Dans les anciennes versions d'OS X, vous aurez besoin de redmarrer pour que les modifications de la mmoire partage
soient prises en considration. partir de la version 10.5, il est possible de tous les modifier en ligne sauf SHMMNI, grce
sysctl. Mais il est toujours prfrable de configurer vos valeurs prfres dans /etc/sysctl.conf, pour que les nouvelles
valeurs soient conserves aprs un redmarrage.
Le fichier /etc/sysctl.conf est seulement honor partir de la version 1.0.3.9 de OS X. Si vous utilisez une version
antrieure, vous devez modifier le fichier /etc/rc et changer les valeurs dans les commandes suivantes :
sysctl
sysctl
sysctl
sysctl
sysctl

-w
-w
-w
-w
-w

kern.sysv.shmmax
kern.sysv.shmmin
kern.sysv.shmmni
kern.sysv.shmseg
kern.sysv.shmall

Notez que /etc/rc est habituellement cras lors de mises jour systmes d'OS X, donc vous devez vous attendre les
modifier manuellement aprs chaque mise jour.
En
10.2
et
avant
cette
version,
modifiez
ces
commandes
tem/Library/StartupItems/SystemTuning/SystemTuning.

dans

le

fichier

/Sys-

sco openserver
Dans la configuration par dfaut, seuls 512 Ko de mmoire partage par segment est autoris. Pour augmenter ce paramtrage, allez tout d'abord dans le rpertoire /etc/conf/cf.d. Pour afficher la valeur courante de shmmax, lancez :
./configure -y SHMMAX
Pour configurer une nouvelle valeur de shmmax, lancez :
./configure SHMMAX=valeur
o value est la nouvelle valeur que vous voulez utiliser (en octets). Aprs avoir configur shmmax, reconstruisez le noyau :
./link_unix
et redmarrez.
solaris 2.6 2.9 (Solaris 6 Solaris 9)
La taille maximale par dfaut d'un segment de mmoire partage est trop bas pour PostgreSQL. La configuration est modifiable dans /etc/system, par exemple :
set
set
set
set

shmsys:shminfo_shmmax=0x2000000
shmsys:shminfo_shmmin=1
shmsys:shminfo_shmmni=256
shmsys:shminfo_shmseg=256

set
set
set
set

semsys:seminfo_semmap=256
semsys:seminfo_semmni=512
semsys:seminfo_semmns=512
semsys:seminfo_semmsl=32

Vous
avez
besoin
de
redmarrer
pour
que
les
modifications
prennent
effet.
Voir
aussi
http://sunsite.uakom.sk/sunworldonline/swol-09-1997/swol-09-insidesolaris.html pour des informations sur la configuration
de la mmoire partage sur des versions plus anciennes de Solaris.
Solaris 2.10 (Solaris 10), OpenSolaris
Dans Solaris 10 et OpenSolaris, la configuration de la mmoire partage et des smaphores par dfaut sont suffisamment
bonnes pour la majorit des configurations de PostgreSQL. La valeur par dfaut de Solaris pour SHMMAX correspond maintenant un quart de la mmoire disponible sur le systme. Si vous avez besoin d'augmenter cette configuration pour obtenir
un paramtrage lgrement suprieur, vous devez utiliser une configuration de projet associ l'utilisateur postgres. Par
exemple, excutez ce qui suit en tant qu'utilisateur root :

315

Configuration du serveur et mise en place

projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U


postgres -G postgres user.postgres
Cette commande ajoute le projet user.postgres et augmente le maximum de mmoire partage pour l'utilisateur
postgres 8 Go. Cela prend effet chaque fois que l'utilisateur se connecte et quand vous redmarrez PostgreSQL. La
ligne ci-dessus suppose que PostgreSQL est excut par l'utilisateur postgres dans le groupe postgres. Aucun redmarrage du serveur n'est requis.
Sur un serveur de bases de donnes ayant beaucoup de connexions, les autres modifications recommands pour le noyau
sont :
project.max-shm-ids=(priv,32768,deny)
project.max-sem-ids=(priv,4096,deny)
project.max-msg-ids=(priv,4096,deny)
De plus, si vous excutez PostgreSQL dans une zone, vous pourriez avoir besoin d'augmenter les limites d'utilisation des
ressources pour la zone. Voir Chapter2: Projects and Tasks dans Solaris 10 System Administrator's Guide pour plus
d'informations sur les projets et prctl.
unixware
Avec unixware 7, la taille maximum des segments de mmoire partage est de 512 Ko dans la configuration par dfaut.
Pour afficher la valeur courante de shmmax, lancez :
/etc/conf/bin/idtune -g SHMMAX
qui affiche la valeur courante, par dfaut, minimum et maximum. Pour configurer une nouvelle valeur de shmmax, lancez :
/etc/conf/bin/idtune SHMMAX valeur
o valeur est la nouvelle valeur que vous voulez utiliser (en octets). Aprs avoir initialis shmmax, reconstruisez le noyau :
/etc/conf/bin/idbuild -B
et relancez.
Tableau 17.2. Usage de la mmoire partage PostgreSQL

Usage

Nombre d'octets approximatifs pour la mmoire partage (en 8.3)

Connexions

(1800 + 270 * max_locks_per_transaction) * max_connections

Processus
travailleurs
l'autovacuum

de (1800 + 270 * max_locks_per_transaction) * autovacuum_max_workers

Transactions prpares

(770 + 270 * max_locks_per_transaction) * max_prepared_transactions

Tampons disque partags

(block_size + 208) * shared_buffers

Tampons WAL

(wal_block_size + 8) * wal_buffers

Espace fixe requis

770 kB

17.4.2. Limites de ressources


Les systmes d'exploitation style Unix renforcent diffrents types de limites de ressources qui pourraient interfrer avec les oprations de votre serveur PostgreSQL. Les limites sur le nombre de processus par utilisateur, le nombre de fichiers ouverts par un
processus et la taille mmoire disponible pour chaque processus sont d'une grande importance. Chacun d'entre elles ont une limite
dure et une limite souple . La limite souple est rellement ce qui compte mais cela pourrait tre chang par l'utilisateur jusqu' la limite dure. La limite dure pourrait seulement tre modifie par l'utilisateur root. L'appel systme setrlimit est responsable de l'initialisation de ces paramtres. La commande interne du shell ulimit (shells Bourne) ou limit (csh) est utilis pour
contrler les limites de ressource partir de la ligne de commande. Sur les systmes drivs BSD, le fichier /etc/login.conf
contrle les diffrentes limites de ressource initialises la connexion. Voir la documentation du systme d'exploitation pour les
dtails. Les paramtres en question sont maxproc, openfiles et datasize. par exemple :
default:\
...
:datasize-cur=256M:\
:maxproc-cur=256:\
316

Configuration du serveur et mise en place

:openfiles-cur=256:\
...
(-cur est la limite douce. Ajoutez -max pour configurer la limite dure.)
Les noyaux peuvent aussi avoir des limites sur le systme complet pour certaines ressources.

Sur linux, /proc/sys/fs/file-max dtermine le nombre maximum de fichiers ouverts que le noyau supportera. Ce
nombre est modifiable en crivant un autre nombre dans le fichier ou en ajoutant une affectation dans /etc/sysctl.conf.
La limite des fichiers par processus est fixe lors de la compilation du noyau ; voir /
usr/src/linux/documentation/proc.txt pour plus d'informations.

Le serveur PostgreSQL utilise un processus par connexion de faon ce que vous puissiez fournir au moins autant de processus
que de connexions autorises, en plus de ce dont vous avez besoin pour le reste de votre systme. Ceci n'est habituellement pas un
problme mais si vous excutez plusieurs serveurs sur une seule machine, cela pourrait devenir troit.
La limite par dfaut des fichiers ouverts est souvent initialise pour tre amicalement sociale , pour permettre de nombreux
utilisateurs de coexister sur une machine sans utiliser une fraction inapproprie des ressources du systme. Si vous lancez un grand
nombre de serveurs sur une machine, cela pourrait tre quelque chose que vous souhaitez mais sur les serveurs ddis, vous pourriez vouloir augmenter cette limite.
D'un autre ct, certains systmes autorisent l'ouverture d'un grand nombre de fichiers des processus individuels ; si un plus
grand nombre le font, alors les limites du systme peuvent facilement tre dpasses. Si vous rencontrez ce cas et que vous ne
voulez pas modifier la limite du systme, vous pouvez initialiser le paramtre de configuration max_files_per_process de PostgreSQL pour limiter la consommation de fichiers ouverts.

17.4.3. Linux memory overcommit


Dans Linux 2.4 et suivants, le comportement par dfaut de la mmoire virtuelle n'est pas optimal pour PostgreSQL. Du fait de
l'implmentation du memory overcommit par le noyau, celui-ci peut arrter le serveur PostgreSQL (le processus serveur
matre, postmaster ) si les demandes de mmoire de PostgreSQL ou d'un autre processus provoque un manque de mmoire
virtuelle au niveau du systme.
Si cela se produit, un message du noyau qui ressemble ceci (consulter la documentation et la configuration du systme pour savoir o chercher un tel message) :
Out of Memory: Killed process 12345 (postgres)
peut survenir. Ceci indique que le processus postgres a t termin cause d'un problme de mmoire. Bien que les
connexions en cours continuent de fonctionner normalement, aucune nouvelle connexion n'est accepte. Pour revenir un tat
normal, PostgreSQL doit tre relanc.
Une faon d'viter ce problme revient lancer PostgreSQL sur une machine o vous pouvez vous assurer que les autres processus ne mettront pas la machine en manque de mmoire. S'il y a peu de mmoire, augmenter la swap peut aider viter le problme car un systme peut tuer des processus lorsque la mmoire physique et la mmoire swap sont utilises entirement.
Si PostgreSQL est lui-mme la cause du manque mmoire du systme, vous pouvez viter le problme en modifiant votre configuration. Dans certains cas, il est intressant de baisser les paramtres relatifs la mmoire, en particulier shared_buffers et
work_mem. Dans d'autres cas, le problme peut tre caus en autorisant de trop nombreuses connexions au serveur. Dans un
grand nombre de cas, il est prfrable de rduire max_connections et d'utiliser la place un pooler de connexions.
Sur Linux 2.6 et ultrieur, il est possible de modifier le comportement du noyau avec le overcommit memory . Bien que ce paramtrage n'empchera pas ce comportement, il rduira sa frquence de faon significative et contribuera du coup un systme
plus robuste. Ceci se fait en slectionnant le mode strict de l'overcommit via sysctl :
sysctl -w vm.overcommit_memory=2
ou en plaant une entre quivalente dans /etc/sysctl.conf. Vous pourriez souhaiter modifier le paramtrage relatif
vm.overcommit_ratio.
Pour
les
dtails,
voir
la
documentation
du
noyau
(documentation/
vm/overcommit-accounting).
Une autre approche, qui peut aussi utiliser la modification de vm.overcommit_memory, est de configurer la valeur de la variable oom_adj, valeur par processus, pour le processus postmaster -17, garantissant ainsi qu'il ne sera pas la cible de OOM.
La faon la plus simple de le faire est d'excuter
echo -17 > /proc/self/oom_adj
dans le script de dmarrage de postmaster juste avant d'appeler postmaster. Notez que cette action doit tre faite en tant
qu'utilisateur root. Dans le cas contraire, elle n'aura aucun effet. Du coup, un script de dmarrage, excut par root, est le meilleur
317

Configuration du serveur et mise en place

endroit o placer ce code. Si vous le faites, vous pourriez aussi souhaiter construire PostgreSQL avec l'option -DLINUX_OOM_ADJ=0 ajoute CPPFLAGS. Cela fera en sorte que les processus enfants de postmaster seront excuts avec la valeur oom_adj normale de zro, pour que OOM puisse les cibler si ncessaire.

Note
Quelques noyaux 2.4 de vendeurs ont des pr-versions de l'overcommit du 2.6. Nanmoins, configurer
vm.overcommit_memory 2 sur un noyau 2.4 qui n'a pas le code correspondant rendra les choses pires
qu'elles n'taient. Il est recommand d'inspecter le code source du noyau (voir la fonction vm_enough_memory
dans le fichier mm/mmap.c) pour vrifier ce qui est support dans votre noyau avant d'essayer ceci avec une installation 2.4. La prsence du fichier de documentation overcommit-accounting ne devrait pas tre pris
comme une preuve de la prsence de cette fonctionnalit. En cas de doute, consultez un expert du noyau ou le vendeur de votre noyau.

17.5. Arrter le serveur


Il existe plusieurs faons d'arrter le serveur de bases de donnes. Vous contrlez le type d'arrt en envoyant diffrents signaux au
processus serveur matre.
sigterm
C'est le mode d'arrt intelligent. Aprs rception de sigterm, le serveur dsactive les nouvelles connexions mais permet
aux sessions en cours de terminer leur travail normalement. Il s'arrte seulement aprs que toutes les sessions se sont termines normalement. C'est l'arrt intelligent (smart shutdown). Si le serveur est en mode de sauvegarde en ligne, il attends en
plus la dsactivation du mot de sauvegarde en ligne. Lorsque le mode de sauvegarde est actif, les nouvelles connexions sont
toujours autorises, mais seulement pour les superutilisateurs (cette exception permet un superutilisateur de se connecter
pour terminer le mode de sauvegarde en ligne). Si le serveur est en restauration quand une demande d'arrt intelligent est envoye, la restauration et la rplication en flux seront stoppes seulement une fois que toutes les autres sessions ont termin.
sigint
C'est le mode d'arrt rapide. Le serveur dsactive les nouvelles connexions et envoie tous les processus serveur le signal
sigterm, qui les fera annuler leurs transactions courantes pour quitter rapidement. Il attend ensuite la fin de tous les processus serveur et s'arrte finalement. Si le serveur est en mode de sauvegarde en ligne, le mode est annul, rendant la sauvegarde
inutilisable.
sigquit
C'est le mode d'arrt immdiat. Le processus postgres matre envoie un signal sigquit tous les processus fils et quitter
immdiatement non proprement. Les processus fils quittent immdiatement rception du signal sigquit. ceci amnera
une tentative de rcupration (en rejouant les traces WAL) au prochain lancement. Ceci n'est recommand que dans les cas
d'urgence.
Le programme pg_ctl(1) fournit une interface agrable pour envoyer ces signaux dans le but d'arrter le serveur. Autrement, vous
pouvez envoyer le signal directement en utilisant kill sur les systmes autres que Windows. Le PID du processus postgres peut
tre trouv en utilisant le programme ps ou partir du fichier postmaster.pid dans le rpertoire des donnes. Par exemple,
pour excuter un arrt rapide :
$ kill -int `head -1 /usr/local/pgsql/data/postmaster.pid`

Important
Il vaux mieux de ne pas utiliser sigkill pour arrter le serveur. Le faire empchera le serveur de librer la mmoire partage et les smaphores, ce qui pourrait devoir tre fait manuellement avant qu'un nouveau serveur ne soit
lanc. De plus, SIGKILL tue le processus postgres sans que celui-ci ait le temps de relayer ce signal ses sousprocessus, donc il sera aussi ncessaire de tuer les sous-processus individuels la main.
Pour terminer une session individuelle tout en permettant aux autres de continuer, utilisez pg_terminate_backend() (voir
Tableau 9.55, Fonctions d'envoi de signal au serveur ) ou envoyez un signal SIGTERM au processus fils associ cette session.

17.6. Mise jour d'une instance PostgreSQL


Cette section concerne la mise jour des donnes de votre serveur d'une version de PostgreSQL vers une version ultrieure.
Les versions majeures de PostgreSQL sont reprsentes par les deux premiers groupes de chiffres du numro de version, par
exemple 8.4. Les versions mineures de PostgreSQL sont reprsentes par le troisime groupe de chiffres, par exemple 8.4.2 est
318

Configuration du serveur et mise en place

la deuxime version mineure de la 8.4. Les versions mineures ne modifient jamais le format de stockage interne et sont donc compatibles avec les versions antrieures et ultrieures de la mme version majeure. Par exemple, le format 8.4.2 est compatible avec
le format des versions 8.4, 8.4.1 et 8.4.6. Pour mettre jour entre des versions compatibles, vous devez simplement remplacer les
binaires une fois le serveur arrt, puis redmarrer le serveur. Le rpertoire des donnes ne doit pas tre modifi. Les mises jour
de versions mineures sont aussi simples que a.
Pour les versions majeures de PostgreSQL, le format de stockage interne des donnes est sujet modification, ce qui complique
les mises jour. La mthode traditionnelle de migration des donnes vers une nouvelle version majeure est de sauvegarder puis recharger la base de donnes. D'autres mthodes sont disponibles, ce qui est expliqu ci-dessous.
De plus, les nouvelles versions majeures introduisent gnralement des incompatibilits qui impactent les utilisateurs. Du coup,
des modifications peuvent tre ncessaires sur les applications clientes. Tous les changements visibles par les utilisateurs sont lists dans les notes de version (Annexe E, Notes de version). Soyez particulirement attentif la section Migration. Si vous mettez
jour en passant plusieurs versions majeures, assurez-vous de lire les notes de version de chaque version majeure que vous passez.
Les utilisateurs prcautionneux testeront leur applications clientes sur la nouvelle version avant de basculer compltement. Du
coup, il est souvent intressant de mettre en place des installations parallles des ancienne et nouvelle versions. Lors d'un test
d'une mise jour majeure de PostgreSQL, pensez aux diffrentes catgories suivantes :
Administration
Les fonctionnalits disponibles pour les administrateurs pour surveiller et contrler le serveur s'amliorent frquemment
chaque nouvelle version.
SQL
Cela inclut gnralement les nouvelles commandes ou clauses SQL, et non pas des changements de comportement sauf si
c'est spcifiquement prcis dans les notes de version.
API
Les bibliothques comme libpq se voient seulement ajouter de nouvelles fonctionnalits, sauf encore une fois si le contraire
est mentionn dans les notes de version.
Catalogues systmes
Les modifications dans les catalogues systmes affectent seulement les outils de gestion des bases de donnes.
API serveur pour le langage C
Ceci implique des modifications dans l'API des fonctions du moteur qui est crit en C. De telles modifications affectent le
code qui fait rfrence des fonctions du moteur.

17.6.1. Mise jour des donnes via pg_dump


Pour sauvegarder les donnes d'une version majeure de PostgreSQL et les recharger dans une autre, vous devez utiliser
pg_dump ; une sauvegarde au niveau systme de fichiers ne fonctionnera pas. Des vrifications sont faites pour vous empcher
d'utiliser un rpertoire de donnes avec une version incompatible de PostgreSQL, donc aucun mal ne sera fait si vous essayez de
lancer un serveur d'une version majeure sur un rpertoire de donnes cr par une autre version majeure.)
Il est recommand d'utiliser les programmes pg_dump et pg_dumpall provenant de la nouvelle version de PostgreSQL, pour bnficier des amliorations apportes ces programmes. Les versions actuelles de ces programmes peuvent lire des donnes provenant de tout serveur dont la version est suprieure ou gale la 7.0.
Ces instructions supposent que votre installation existante se trouve dans le rpertoire /usr/local/pgsql et que le rpertoire
des donnes est /usr/local/pgsql/data. Remplacez ces chemins pour correspondre votre installation.
1.

Si vous faites une sauvegarde, assurez-vous que votre base de donnes n'est pas en cours de modification. Cela n'affectera pas
l'intgrit de la sauvegarde mais les donnes modifies ne seront videmment pas incluses. Si ncessaire, modifiez les droits
dans le fichier /usr/local/pgsql/data/pg_hba.conf (ou quivalent) pour interdire l'accs tout le monde sauf
vous. Voir Chapitre 19, Authentification du client pour plus d'informations sur le contrle des accs.
Pour sauvegarder votre installation, excutez la commande suivante :
pg_dumpall > fichier_en_sortie
Si vous devez conserver les OID (parce que vous les utilisez en tant que cls trangres, par exemple), utilisez l'option -o
lors de l'excution de pg_dumpall.
Pour faire la sauvegarde, vous pouvez utiliser la commande pg_dumpall de la version en cours d'excution. Nanmoins, pour
de meilleurs rsultats, essayez d'utiliser la commande pg_dumpall provenant de la version 9.1.14 de PostgreSQL, car cette
319

Configuration du serveur et mise en place

version contient des corrections de bugs et des amliorations par rapport aux anciennes version. Bien que ce conseil peut
sembler tonnant, tant donn que vous n'avez pas encore t la nouvelle version, il est conseill de le suivre si vous souhaitez installer la nouvelle version en parallle de l'ancienne. Dans ce cas, vous pouvez terminer l'installation normalement et
transfrer les donnes plus tard. Cela diminuera aussi le temps d'immobilisation.
2.

Arrtez l'ancien serveur :


pg_ctl stop
Sur les systmes qui lancent PostgreSQL au dmarrage, il existe probablement un script de dmarrage qui fera la mme
chose. Par exemple, sur un systme Red Hat Linux, cette commande pourrait fonctionner :
/etc/rc.d/init.d/postgresql stop
Voir Chapitre 17, Configuration du serveur et mise en place pour des dtails sur le lancement et l'arrt d'un serveur.

3.

Lors de la restauration de la sauvegarde, renommez ou supprimez l'ancien rpertoire d'installation. Il est prfrable de le renommer car, en cas de problme, vous pourrez le rcuprer. Garder en tte que le rpertoire peut prendre beaucoup d'espace
disque. Pour renommer le rpertoire, utilisez une commande comme celle-ci :
mv /usr/local/pgsql /usr/local/pgsql.old
(Assurez-vous de dplacer le rpertoire en un seul coup, pour que les chemins relatifs restent inchangs.)

4.

Installez la nouvelle version de PostgreSQL comme indiqu dans la section suivante Section 15.4, Procdure
d'installation .

5.

Crez une nouvelle instance de bases de donnes si ncessaire. Rappelez-vous que vous devez excuter ces commandes une
fois connect en tant que l'utilisateur de bases de donnes (que vous devez dj avoir si vous faites une mise jour).
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data

6.

Restaurez vos modifications dans les fichiers pg_hba.conf et postgresql.conf.

7.

Dmarrez le serveur de bases de donnes, en utilisant encore une fois l'utilisateur de bases de donnes :
/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data

8.

Enfin, restaurez vos donnes partir de votre sauvegarde :


/usr/local/pgsql/bin/psql -d postgres -f outputfile
en utilisant le nouveau psql.

Il est possible de parvenir une immobilisation moins longue en installant le nouveau serveur dans un autre rpertoire et en excutant l'ancien et le nouveau serveur, en parallle, sur des ports diffrents. Vous pouvez ensuite utiliser quelque chose comme :
pg_dumpall -p 5432 | psql -d postgres -p 5433
pour transfrer vos donnes.

17.6.2. Mthodes de mise jour sans sauvegarde


Le module pg_upgrade permet la migration d'une installation d'une version majeure de PostgreSQL une autre, par modification des fichiers prsents. Les mises jour se ralisent en quelques minutes.
Il est aussi possible d'utiliser certaines mthodes de rplication, comme Slony, pour crer un serveur esclave avec la version
jour de PostgreSQL. Ceci est possible car Slony permet une rplication entre des versions majeures diffrentes de
PostgreSQL. L'esclave peut se trouver sur le mme serveur ou sur un autre. Une fois qu'il est synchronis avec le serveur matre
(qui utilise toujours l'ancienne version de PostgreSQL), vous pouvez basculer le serveur matre sur le nouveau serveur et arrter
l'ancien matre. Ce type de bascule fait que l'arrt requis pour la mise jour se mesure seulement en secondes.

320

Configuration du serveur et mise en place

17.7. Empcher l'usurpation de serveur


Quand le serveur est en cours d'excution, un utilisateur pernicieux ne peut pas interfrer dans les communications client/serveur.
Nanmoins, quand le serveur est arrt, un utilisateur local peut usurper le serveur normal en lanant son propre serveur. Le serveur usurpateur pourrait lire les mots de passe et requtes envoyes par les clients, mais ne pourrait pas renvoyer de donnes car le
rpertoire PGDATA serait toujours scuris grce aux droits d'accs du rpertoire. L'usurpation est possible parce que tout utilisateur peut lancer un serveur de bases de donnes ; un client ne peut pas identifier un serveur invalide sauf s'il est configur spcialement.
Le moyen le plus simple d'empcher les serveurs invalides pour des connexions locales est d'utiliser un rpertoire de socket de
domaine Unix (unix_socket_directory) qui a un droit en criture accessible seulement par un utilisateur local de confiance. Ceci
empche un utilisateur mal intentionn de crer son propre fichier socket dans ce rpertoire. Si vous tes concern que certaines
applications pourraient toujours rfrencer /tmp pour le fichier socket et, du coup, tre vulnrable au spoofing , lors de la cration du lien symbolique /tmp/.s.PGSQL.5432 pointant vers le fichier socket dplac. Vous pouvez aussi avoir besoin de modifier votre script de nettoyage de /tmp pour empcher la suppression du lien symbolique.
Pour empcher l'usurpation des connexions TCP, le mieux est d'utiliser des certificats SSL et de s'assurer que les clients vrifient
le certificat du serveur. Pour cela, le serveur doit tre configur pour accepter les connexions hostssl (Section 19.1, Le fichier
pg_hba.conf ) et avoir les fichiers SSL pour la cl, server.key, et pour le certificat, server.crt (Section 17.9,
Connexions tcp/ip scurises avec ssl ). Le client TCP doit se connecter en utilisant sslmode='verify-ca' ou 'verifyfull' et avoir le certificat racine install (Section 31.1, Fonctions de contrle de connexion la base de donnes ).

17.8. Options de chiffrement


PostgreSQL offre du chiffrement sur plusieurs niveaux et fournit une flexibilit pour protger les donnes d'tre rvles suite
un vol du serveur de la base de donnes, des administrateurs non scrupuleux et des rseaux non scuriss. Le chiffrement pourrait
aussi tre requis pour scuriser des donnes sensibles, par exemple des informations mdicales ou des transactions financires.
chiffrement du mot de passe stock
Par dfaut, les mots de passe des utilisateurs de la base de donnes sont stockes suivant des hachages MD5, donc
l'administrateur ne peut pas dterminer le mot de passe affect l'utilisateur. Si le cryptage MD5 est utilis pour
l'authentification du client, le mot de passe non crypt n'est jamais prsent temporairement sur le serveur parce que le client le
crypte en MD5 avant de l'envoyer sur le rseau.
chiffrement de colonnes spcifiques
Le module pgcrypto autorise le stockage crypt de certains champs. Ceci est utile si seulement certaines donnes sont sensibles. Le client fournit la cl de dcryptage et la donne est dcrypte sur le serveur puis elle est envoye au client.
La donne dcrypte et la cl de dchiffrement sont prsente sur le serveur pendant un bref moment o la donne est dcrypte, puis envoye entre le client et le serveur. Ceci prsente un bref moment o la donnes et les cls peuvent tre interceptes
par quelqu'un ayant un accs complet au serveur de bases de donnes, tel que l'administrateur du systme.
chiffrement de la partition de donnes
Sur Linux, le chiffrement peut se faire au niveau du montage d'un systme de fichiers en utilisant un priphrique loopback . Ceci permet une partition entire du systme de fichiers d'tre crypte et dcrypte par le systme d'exploitation. Sur
FreeBSD, la fonctionnalit quivalent est appel geom based disk encryption (gbde), et beaucoup d'autres systmes
d'exploitations, comme Windows, supportent cette fonctionnalit.
Ce mcanisme empche les donnes non cryptes d'tre lues partir des lecteurs s'ils sont vols. Ceci ne protge pas contre
les attaques quand le systme de fichiers est mont parce que, une fois mont, le systme d'exploitation fournit une vue non
crypte des donnes. Nanmoins, pour monter le systme de fichiers, vous avez besoin d'un moyen pour fournir la cl de chiffrement au systme d'exploitation et, quelque fois, la cl est stock quelque part prs de l'hte qui monte le disque.
chiffrement des mots de passe sur le rseau
La mthode d'authentification md5 crypte deux fois le mot de passe sur le client avant de l'envoyer au serveur. Il le crypte tout
d'abord partir du nom de l'utilisateur puis il le crypte partir d'un lment du hasard envoy par le serveur au moment de la
connexion. Cette valeur, deux fois crypte, est envoye sur le rseau au serveur. Le double chiffrement empche non seulement la dcouverte du mot de passe, il empche aussi une autre connexion en utilisant le mme mot de passe crypt pour se
connecter au serveur de bases de donnes lors d'une connexion future.
chiffrement des donnes sur le rseau
Les connexions SSL cryptent toutes les donnes envoyes sur le rseau : le mot de passe, les requtes et les donnes renvoyes. Le fichier pg_hba.conf permet aux administrateurs de spcifier quels htes peuvent utiliser des connexions non
cryptes (host) et lesquels requirent des connexions SSL (hostssl). De plus, les clients peuvent spcifier qu'ils se
connectent aux serveurs seulement via SSL. stunnel ou ssh peuvent aussi tre utiliss pour crypter les transmissions.

321

Configuration du serveur et mise en place

authentification de l'hte ssl


Il est possible que le client et le serveur fournissent des certificats SSL l'autre. Cela demande une configuration supplmentaire de chaque ct mais cela fournit une vrification plus forte de l'identit que la simple utilisation de mots de passe. Cela
empche un ordinateur de se faire passer pour le serveur assez longtemps pour lire le mot de passe envoy par le client. Cela
empche aussi les attaques du type man in the middle o un ordinateur, entre le client et le serveur, prtend tre le serveur,
lit et envoie les donnes entre le client et le serveur.
chiffrement ct client
Si vous n'avez pas confiance en l'administrateur systme du serveur, il est ncessaire que le client crypte les donnes ; de cette
faon, les donnes non cryptes n'apparaissent jamais sur le serveur de la base de donnes. Les donnes sont cryptes sur le
client avant d'tre envoy au serveur, et les rsultats de la base de donnes doivent tre dcrypts sur le client avant d'tre utiliss.

17.9. Connexions tcp/ip scurises avec ssl


PostgreSQL dispose d'un support natif pour l'utilisation de connexions ssl, cryptant ainsi les communications clients/serveurs
pour une scurit amliore. Ceci requiert l'installation d'openssl la fois sur le systme client et sur le systme serveur et que
ce support soit activ au moment de la construction de PostgreSQL (voir le Chapitre 15, Procdure d'installation de
PostgreSQL du code source).
Avec le support ssl compil, le serveur PostgreSQL peut tre lanc avec ssl activ en activant ssl dans PostgreSQL.conf.
Le serveur coutera les deux connexions, standard et SSL sur le mme port TCP, et ngociera avec tout client l'utilisation de SSL.
Par dfaut, le client peut choisir cette option ; voir Section 19.1, Le fichier pg_hba.conf sur la faon de configurer le serveur pour rclamer l'utilisation de SSL pour certaines, voire toutes les connexions.
PostgreSQL lit le fichier de configuration d'OpenSSL pour le serveur. Par dfaut, ce fichier est nomm openssl.cnf et est
situ dans le rpertoire indiqu par openssl version -d. Cette valeur par dfaut peut tre surcharge en configurant la variable d'environnement OPENSSL_CONF avec le nom du fichier de configuration dsir.
OpenSSL accepte une gamme tendue d'algorithmes de chiffrement et d'authentification, de diffrentes forces. Bien qu'une liste
d'algorithmes de chiffrement peut tre indique dans le fichier de configuration d'OpenSSL, vous pouvez spcifier des algorithmes spcifiques utiliser par le serveur de la base de donnes en modifiant le paramtre ssl_ciphers dans postgresql.conf.

Note
Il est possible d'avoir une authentification sans le chiffrement en utilisant les algorithmes NULL-SHA ou NULLMD5. Nanmoins, une attaque du type man-in-the-middle pourrait lire et passer les communications entre client et
serveur. De plus, le temps pris par le chiffrement est minimal compar celui pris par l'authentification. Pour ces
raisons, les algorithmes NULL ne sont pas recommands.
Pour dmarrer le mode SSL, les fichiers server.crt et server.key doivent exister dans le rpertoire de donnes du serveur.
Ces fichiers doivent contenir, respectivement, le certificat et la cl prive du serveur. Sur les systmes Unix, les droits de server.key doivent interdire l'accs au groupe et au reste du monde ; cela se fait avec la commande chmod 0600 server.key. Si la
cl prive est protge par une phrase de passe, le serveur la demandera et ne se lancera pas tant qu'elle n'aura pas t saisie.
Dans certains cas, le certificat du serveur peut tre sign par une autorit intermdiaire de certificats, plutt que par un qui soit
directement de confiance par les clients. Pour utiliser un tel certificat, ajoutez le certificat de l'autorit signataire au fichier server.crt, puis le certificat de l'autorit parente, et ainsi de suite jusqu' l'autorit racine qui est accepte par les clients. Le certificat racine doit tre inclus dans chaque cas o server.crt contient plus d'un certificat.

17.9.1. Utiliser des certificats clients


Pour rclamer l'envoi d'un certificat de confiance par le client, placez les certificats des autorits (CA) de confiance dans le fichier
root.crt du rpertoire des donnes, et configurez le paramtre clientcert 1 sur la ligne hostssl approprie dans le fichier pg_hba.conf. Un certificat pourra ensuite tre rclam lors du lancement de la connexion SSL. (Voir Section 31.17,
Support de SSL pour une description de la configuration de certificats sur le client.) Le serveur vrifiera que le certificat du
client est sign par une des autorits de confiance. Les entres de la liste de rvocation des certificats sont aussi vrifies si le fichier root.crl existe. (Voir les diagrammes montrant l'utilisation des certificats SSL.)
L'option clientcert de pg_hba.conf est disponible pour toutes les mthodes d'authentification, mais seulement pour les
lignes spcifies hostssl. Quand clientcert n'est pas prcis ou qu'il est configur 0, le serveur vrifiera toujours les certificats clients prsents avec root.crt si ce fichier existe -- mais il ne forcera pas la prsentation d'un certificat client.
Notez que root.crt liste les autorits de certificats de haut-niveau, ceux suffisamment de confiance pour signer les certificats
322

Configuration du serveur et mise en place

des clients. En principe, il n'a pas besoin de lister l'autorit de certificats qui a sign le certificat du serveur bien que dans la plupart des cas, cette autorit sera aussi de confiance pour les certificats de clients.
Si vous configurez les certificats de clients, vous pouvez utiliser la mthode d'authentification cert, de faon ce que les certificats soient aussi utiliss pour contrler l'authentification de l'utilisateur, tout en fournissant une scurit de connexion. Voir Section 19.3.10, Authentification de certificat pour les dtails.

17.9.2. Utilisation des fichiers serveur SSL


Tableau 17.3, Utilisation des fichiers serveur SSL rsume les fichiers qui ont un lien avec la configuration de SSL sur le serveur.
Tableau 17.3. Utilisation des fichiers serveur SSL

Fichier

Contenu

Effet

$PGDATA/server.crt

certificat du serveur

envoy au client pour indiquer l'identit


du serveur

$PGDATA/server.key

cl prive du serveur

prouve que le certificat serveur est envoy


par son propritaire n'indique pas que le
propritaire du certificat est de confiance

$PGDATA/root.crt

autorits de confiance pour les certificats

vrifie le certificat du client ; vrifie que


le certificat du client est sign par une autorit de confiance

$PGDATA/root.crl

certificats rvoqus par les autorits de le certificat du client ne doit pas tre sur
confiance
cette liste

Les fichiers server.key, server.crt, root.crt et root.crl sont seulement examins au dmarrage du serveur ; donc
vous devez dmarrer le serveur pour que les changements prennent effet.

17.9.3. Crer un certificat auto-sign


Pour crer rapidement un certificat sign soi-mme pour le serveur, utilisez la commande OpenSSL suivante :
openssl req -new -text -out server.req
Remplissez l'information que openssl demande. Assurez-vous de saisir le nom de l'hte local dans Common Name ; le mot de
passe peut ne pas tre saisi. Le programme gnrera une cl qui est protge par une phrase de passe ; il n'acceptera pas une phrase
de passe qui fait moins de quatre caractres de long. Pour la supprimer (vous le devez si vous voulez un dmarrage automatique
du serveur), excutez les commandes suivantes :
openssl rsa -in privkey.pem -out server.key
rm privkey.pem
Saisissez l'ancienne phrase de passe pour dverrouiller la cl existante. Maintenant, lancez :
openssl req -x509 -in server.req -text -key server.key -out server.crt
pour transformer le certificat en un certificat auto-sign et pour copier la cl et le certificat l o le serveur les cherchera. Enfin,
faites :
chmod og-rwx server.key
car le serveur rejetera le fichier si ses droits sont plus importants. Pour plus de dtails sur la faon de crer la cl prive et le certificat de votre serveur, rfrez-vous la documentation d'OpenSSL.
Un certificat auto-sign peut tre utilis pour tester, mais un certificat sign par une autorit (CA) (un des CAs global ou un local)
devra tre utilis lorsque le serveur sera en production pour que le client puisse vrifier l'identit du serveur. Si tous les clients sont
locaux l'organisation, utiliser un CA local est recommand.

17.10. Connexions tcp/ip scurises avec des tunnels ssh tunnels


Il est possible d'utiliser ssh pour chiffrer la connexion rseau entre les clients et un serveur PostgreSQL. Ralis correctement,
323

Configuration du serveur et mise en place

ceci fournit une connexion rseau scurise, y compris pour les clients non SSL.
Tout d'abord, assurez-vous qu'un serveur ssh est en cours d'excution sur la mme machine que le serveur PostgreSQL et que
vous pouvez vous connecter via ssh en tant qu'un utilisateur quelconque. Ensuite, vous pouvez tablir un tunnel scuris avec une
commande comme ceci sur la machine cliente :
ssh -L 63333:localhost:5432 joe@foo.com
Le premier numro de l'argument -l, 63333, est le numro de port de votre bout du tunnel ; il peut tre choisi parmi tous les ports
non utiliss. (IANA rserve les ports 49152 65535 pour une utilisation prive.) Le second numro, 5432, est le bout distant du
tunnel : le numro de port que votre serveur utilise. Le nom ou l'adresse entre les numros de port est l'hte disposant du serveur
de bases de donnes auquel vous souhaitez vous connecter, comme vu partir de l'hte o vous vous connectez, qui est foo.com
dans cet exemple. Pour vous connecter au serveur en utilisant ce tunnel, vous vous connectez au port 63333 de la machine locale :
psql -h localhost -p 63333 postgres
Sur le serveur de bases de donnes, il semblera que vous tes rellement l'utilisateur joe sur l'hte foo.com en vous connectant
localhost dans ce contexte, et il utilisera la procdure d'authentification configure pour les connexions de cet utilisateur et
de cet hte. Notez que le serveur ne pensera pas que la connexion est chiffre avec SSL car, en effet, elle n'est pas chiffre entre le
serveur SSH et le serveur PostgreSQL. Cela ne devrait pas poser un risque de scurit supplmentaire si les deux serveurs sont
sur la mme machine.
Pour russir la configuration du tunnel, vous devez tre autoris pour vous connecter via ssh sur joe@foo.com, comme si vous
aviez tent d'utiliser ssh pour crer une session de terminal.
Vous pouvez aussi configurer la translation de port de cette faon :
ssh -L 63333:foo.com:5432 joe@foo.com
mais alors le serveur de la base de donnes verra la connexion venir de son interface foo.com qui n'est pas ouverte par son paramtrage par dfaut listen_addresses = 'localhost'. Ceci n'est pas habituellement ce que vous tes.
Si vous devez vous connecter au serveur de bases de donnes via un hte de connexion, une configuration possible serait :
ssh -L 63333:db.foo.com:5432 joe@shell.foo.com
Notez que de cette faon la connexion de shell.foo.com db.foo.com ne sera pas chiffre par le tunnel SSH. SSH offre
un certain nombre de possibilits de configuration quand le rseau est restreint. Merci de vous rfrer la documentation de SSH
pour les dtails.

Astuce
Plusieurs autres applications existantes peuvent fournir des tunnels scuriss en utilisant une procdure similaire
dans le concept celle que nous venons de dcrire.

324

Chapitre 18. Configuration du serveur


Un grand nombre de paramtres de configuration permettent de modifier le comportement du systme de bases de donnes.
Dans la premire section de ce chapitre, les mthodes de configuration de ces paramtres sont dcrites ; les sections suivantes
discutent de chaque paramtre en dtail.

18.1. Paramtres de configuration


Tous les noms de paramtres sont insensibles la casse. Chaque paramtre prend une valeur d'un de ces cinq types : boolen,
entier, nombre virgule flottante, chane de caractres ou numration. Les units par dfaut peuvent tre rcupres en rfrenant pg_settings.unit. Les valeurs boolennes peuvent tre on, off, true, false, yes, no, 1, 0 ou tout prfixe
non ambig de celles-ci (toutes ces critures sont insensibles la casse).
Certains paramtres indiquent une valeur de taille mmoire ou de dure. Ils ont chacun une unit implicite, soit Ko, soit blocs
(typiquement 8 Ko), soit millisecondes, soit secondes, soit minutes. Les units par dfaut peuvent tre obtenues en interrogeant
pg_settings.unit. Pour simplifier la saisie, une unit diffrente peut tre indique de faon explicite. Les units mmoire valides sont kB (kilo-octets), MB (Mga-octets) et GB (Giga-octets) ; les units de temps valides sont ms (millisecondes), s
(secondes), min (minutes), h (heures), et d (jours). Les units de mmoire sont des multiples de 1024, pas de 1000.
Les paramtres de type enum sont spcifis de la mme faon que les paramtres de type chane, mais sont restreints un
jeu limit de valeurs. Les valeurs autorises peuvent tre obtenues de pg_settings.enumvals. Les paramtres enum sont insensibles la casse.
Une faon d'initialiser ces paramtres est d'diter le fichier postgresql.conf qui est normalement plac dans le rpertoire
des donnes (une copie par dfaut est install ici quand le rpertoire des donnes est initialis). Un exemple de contenu peut
tre :
# Ceci est un commentaire
log_connections = yes
log_destination = 'syslog'
search_path = '"$user", public'
shared_buffers = 128MB
Un paramtre est indiqu par ligne. Le signe gal entre le nom et la valeur est optionnel. Les espaces n'ont pas de signification et
les lignes vides sont ignores. Les symboles dise (#) dsignent le reste de la ligne comme un commentaire. Les valeurs des paramtres qui ne sont pas des identificateurs simples ou des nombres doivent tre places entre guillemets simples. Pour intgrer
un guillemet simple dans la valeur d'un paramtre, on crit soit deux guillemets (c'est la mthode prfre) soit un antislash suivi
du guillemet.
En plus de la configuration des paramtres, le fichier postgresql.conf peut contenir des directives d'inclusion indiquant un
autre fichier lire et dont le contenu doit tre trait ce niveau comme partie intgrante du fichier de configuration. Les directives d'inclusion ressemblent simplement :
include 'nom_fichier'
Si le nom du fichier n'est pas un chemin absolu, il est pris comme relatif au rpertoire contenant le fichier de configuration le rfrenant. Les inclusions peuvent tre imbriques.
Le fichier de configuration est relu chaque fois que le processus serveur principal reoit un signal SIGHUP (pg_ctl reload est le moyen le plus simple de l'envoyer). Le processus serveur principal propage aussi ce signal aux processus serveur en
cours d'excution de faon ce que les sessions existantes obtiennent aussi la nouvelle valeur. Il est galement possible
d'envoyer le signal directement un seul processus serveur. Quelques paramtres ne peuvent tre initialiss qu'au lancement du
serveur ; tout changement de leur valeur dans le fichier de configuration est ignor jusqu'au prochain dmarrage du serveur.
Une autre faon de configurer ces paramtres est de les passer comme option de la commande postgres :
postgres -c log_connections=yes -c log_destination='syslog'
Les options de la ligne de commande surchargent le paramtrage effectu dans le fichier postgresql.conf. Ce qui signifie
que la valeur d'un paramtre pass en ligne de commande ne peut plus tre modifie et recharge la vole l'aide du fichier
postgresql.conf. C'est pourquoi, bien que la mthode de la ligne de commande paraisse pratique, elle peut coter en flexibilit par la suite.
Il est parfois utile de donner une option en ligne de commande pour une session particulire unique. La variable
d'environnement PGOPTIONS est utilise ct client ce propos :
env PGOPTIONS='-c geqo=off' psql
325

Configuration du serveur

(Cela fonctionne pour toute application client fonde sur libpq, et non pas seulement pour psql.) Cela ne fonctionne pas pour les
paramtres fixs au dmarrage du serveur ou qui doivent tre prciss dans postgresql.conf.
De plus, il est possible d'affecter un ensemble de paramtres un utilisateur ou une base de donnes. Quand une session est lance, les paramtres par dfaut de l'utilisateur et de la base de donnes impliqus sont chargs. Les commandes ALTER ROLE(7)
et ALTER DATABASE(7) sont respectivement utilises pour configurer ces paramtres. Les paramtres par base de donnes surchargent ceux passs sur la ligne de commande de postgres ou du fichier de configuration et sont leur tour surchargs par ceux
de l'utilisateur ; les deux sont surchargs par les paramtres de session.
Quelques paramtres peuvent tre modifis dans les sessions SQL individuelles avec la commande SET(7), par exemple :
SET ENABLE_SEQSCAN TO OFF;
Si SET est autoris, il surcharge toutes les autres sources de valeurs pour le paramtre. Quelques paramtres ne peuvent pas tre
changs via SET : s'ils contrlent un comportement qui ne peut pas tre modifi sans relancer le serveur PostgreSQL, par
exemple. De plus, quelques paramtres peuvent tre modifis via SET ou ALTER par les superutilisateurs.
La commande SHOW(7) permet d'inspecter les valeurs courantes de tous les paramtres.
La table virtuelle pg_settings autorise aussi l'affichage et la mise jour de paramtres de session l'excution ; voir Section 45.62,
pg_settings pour les dtails et une description des diffrents types de variable et de comment ils peuvent tre changs.
pg_settings est quivalente SHOW et SET mais peut tre plus facile utiliser parce qu'elle peut tre jointe avec d'autres tables
et que ses lignes peuvent tre slectionnes en utilisant des conditions personnalises. Elle contient aussi davantage d'informations
sur les valeurs autorises pour les paramtres.

18.2. Emplacement des fichiers


En plus du fichier postgresql.conf dj mentionn, PostgreSQL utilise deux autres fichiers de configuration ditables manuellement. Ces fichiers contrlent l'authentification du client (leur utilisation est discute dans le Chapitre 19, Authentification du
client). Par dfaut, les trois fichiers de configuration sont stocks dans le rpertoire data du cluster de bases de donnes. Les paramtres dcrits dans cette section permettent de dplacer les fichiers de configuration. Ce qui peut en faciliter l'administration. Il
est, en particulier, souvent plus facile de s'assurer que les fichiers de configuration sont correctement sauvegards quand ils sont
conservs part.
data_directory (string)
Indique le rpertoire utiliser pour le stockage des donnes. Ce paramtre ne peut tre initialis qu'au lancement du serveur.
config_file (string)
Indique le fichier de configuration principal du serveur (appel postgresql.conf). Ce paramtre ne peut tre initialis
que sur la ligne de commande de postgres.
hba_file (string)
Indique le fichier de configuration de l'authentification fonde sur l'hte (appel pg_hba.conf). Ce paramtre ne peut tre
initialis qu'au lancement du serveur.
ident_file (string)
Indique le fichier de configuration pour la correspondance des noms d'utilisateurs, fichier appel pg_ident.conf). Voir
Section 19.2, Correspondances d'utilisateurs pour plus de dtails. Ce paramtre ne peut tre initialis qu'au lancement du
serveur.
external_pid_file (string)
Indique le nom d'un fichier supplmentaire d'identifiant de processus (PID) cr par le serveur l'intention des programmes
d'administration du serveur. Ce paramtre ne peut tre initialis qu'au lancement du serveur.
Dans une installation par dfaut, aucun des paramtres ci-dessus n'est configur explicitement. la place, le rpertoire des donnes est indiqu par l'option -D en ligne de commande ou par la variable d'environnement PGDATA. Les fichiers de configuration
sont alors tous disponibles dans le rpertoire des donnes.
Pour conserver les fichiers de configuration dans un rpertoire diffrent de data, l'option -D de la ligne de commande postgres ou
la variable d'environnement PGDATA doit pointer sur le rpertoire contenant les fichiers de configuration. Le paramtre data_directory doit alors tre configur dans le fichier postgresql.conf (ou sur la ligne de commande) pour prciser o
est rellement situ le rpertoire des donnes. data_directory surcharge -D et PGDATA pour l'emplacement du rpertoire des
donnes, mais pas pour l'emplacement des fichiers de configuration.
les noms des fichiers de configuration et leur emplacement peuvent tre indiqus individuellement en utilisant les paramtres
326

Configuration du serveur

config_file, hba_file et/ou ident_file. config_file ne peut tre indiqu que sur la ligne de commande de
postgres mais les autres peuvent tre placs dans le fichier de configuration principal. Si les trois paramtres et data_directory sont configurs explicitement, alors il n'est pas ncessaire d'indiquer -D ou PGDATA.
Lors de la configuration de ces paramtres, un chemin relatif est interprt d'aprs le rpertoire d'o est lanc postgres.

18.3. Connexions et authentification


18.3.1. Paramtres de connexion
listen_addresses (string)
Indique les adresses TCP/IP sur lesquelles le serveur coute les connexions en provenance d'applications clientes. La valeur
prend la forme d'une liste de noms d'hte ou d'adresses IP numriques spars par des virgules. L'entre spciale * correspond
toutes les interfaces IP disponibles. L'enregistrement 0.0.0.0 permet l'coute sur toutes les adresses IPv4 et :: permet
l'coute sur toutes les adresses IPv6. Si la liste est vide, le serveur n'coute aucune interface IP, auquel cas seuls les sockets de
domaine Unix peuvent tre utilises pour s'y connecter. La valeur par dfaut est localhost, ce qui n'autorise que les
connexions TCP/IP locales de type loopback . Bien que l'authentification client (Chapitre 19, Authentification du client)
permet un contrle trs fin sur les accs au serveur, listen_addresses contrle les interfaces pouvant accepter des tentatives de connexion, ce qui permet d'empcher des demandes de connexion amlignes sur des interfaces rseau non scurises.
Ce paramtre ne peut tre configur qu'au lancement du serveur.
port (integer)
Le port TCP sur lequel le serveur coute ; 5432 par dfaut. Le mme numro de port est utilis pour toutes les adresses IP que
le serveur coute. Ce paramtre ne peut tre configur qu'au lancement du serveur.
max_connections (integer)
Indique le nombre maximum de connexions concurrentes au serveur de base de donnes. La valeur par dfaut typique est de
100 connexions, mais elle peut tre moindre si les paramtres du noyau ne le supportent pas (ce qui est dtermin lors de
l'initdb). Ce paramtre ne peut tre configur qu'au lancement du serveur.
L'augmentation de ce paramtre peut obliger PostgreSQL rclamer plus de mmoire partage System V ou de smaphores que ne le permet la configuration par dfaut du systme d'exploitation. Voir la Section 17.4.1, Mmoire partage et
smaphore pour plus d'informations sur la faon d'ajuster ces paramtres, si ncessaire.
Lors de l'excution d'un serveur en attente, vous devez configurer ce paramtre la mme valeur ou une valeur plus importante que sur le serveur matre. Sinon, des requtes pourraient ne pas tre autorises sur le serveur en attente.
superuser_reserved_connections (integer)
Indique le nombre de connecteurs ( slots ) rservs aux connexions des superutilisateurs PostgreSQL. Au plus
max_connections connexions peuvent tre actives simultanment. Ds que le nombre de connexions simultanment actives
atteint max_connections moins superuser_reserved_connections, les nouvelles connexions ne sont plus acceptes que pour les superutilisateurs, et aucune nouvelle connexion de rplication ne sera accepte.
La valeur par dfaut est de trois connexions. La valeur doit tre plus petite que la valeur de max_connections. Ce paramtre ne peut tre configur qu'au lancement du serveur.
unix_socket_directory (string)
Indique le rpertoire du socket de domaine Unix sur lequel le serveur coute les connexions des applications client. Par dfaut, il s'agit de /tmp mais cela peut tre modifi au moment de la construction. Ce paramtre ne peut tre configur qu'au
lancement du serveur.
En plus du fichier socket, qui est nomm .s.PGSQL.nnnn o nnnn est le numro de port du serveur, un fichier ordinaire
nomm .s.PGSQL.nnnn.lock sera cr dans le rpertoire unix_socket_directory. Les deux fichiers ne doivent
pas tre supprims manuellement.
Ce paramtre n'a aucun intrt sous Windows car ce systme n'a pas de sockets domaine Unix.
unix_socket_group (string)
Configure le groupe propritaire du socket de domaine Unix (l'utilisateur propritaire de la socket est toujours l'utilisateur qui
lance le serveur). En combinaison avec le paramtre unix_socket_permissions, ceci peut tre utilis comme un mcanisme de contrle d'accs supplmentaire pour les connexions de domaine Unix. Par dfaut, il s'agit d'une chane vide, ce
qui slectionne le groupe par dfaut de l'utilisateur courant. Ce paramtre ne peut tre configur qu'au lancement du serveur.
Ce paramtre n'a aucun intrt sous Windows car ce systme n'a pas de sockets domaine Unix.
327

Configuration du serveur

unix_socket_permissions (integer)
Configure les droits d'accs au socket de domaine Unix. Ce socket utilise l'ensemble habituel des droits du systme de fichiers
Unix. Ce paramtre doit tre indiqu sous une forme numrique telle qu'accepte par les appels systme chmod et umask
(pour utiliser le format octal, ce nombre doit commencer avec un 0 (zro)).
Les droits par dfaut sont 0777, signifiant que tout le monde peut se connecter. Les alternatives raisonnables sont 0770
(utilisateur et groupe uniquement, voir aussi unix_socket_group) et 0700 (utilisateur uniquement) (pour un socket de
domaine Unix, seul le droit d'accs en criture importe ; il n'est donc pas ncessaire de donner ou de rvoquer les droits de
lecture ou d'excution).
Ce mcanisme de contrle d'accs est indpendant de celui dcrit dans le Chapitre 19, Authentification du client.
Ce paramtre ne peut tre configur qu'au lancement du serveur.
Ce paramtre n'a aucun intrt sous Windows car ce systme n'a pas de sockets domaine Unix.
bonjour (boolean)
Active la promotion de l'existence du serveur via le protocole Bonjour. Dsactiv par dfaut, ce paramtre ne peut tre
configur qu'au lancement du serveur.
bonjour_name (string)
Indique le nom du service Bonjour. Le nom de l'ordinateur est utilis si ce paramtre est configur avec une chane vide (ce
qui est la valeur par dfaut). Ce paramtre est ignor si le serveur n'est pas compil avec le support Bonjour. Ce paramtre
ne peut tre configur qu'au lancement du serveur.
Ce paramtre n'a pas de sens sur certains systmes, notamment Solaris depuis la version 10, qui ignore compltement les
droits sur les sockets. Il est possible d'arriver au mme rsultat en faisant pointer unix_socket_directory vers un rpertoire ayant des droits limits pour une audience particulire. Ce paramtre est aussi inutile pour Windows qui ne dispose
pas des sockets de domaine Unix.
tcp_keepalives_idle (integer)
Indique le nombre de secondes avant l'envoi d'un paquet keepalive sur une connexion qui semble inutilise. Une valeur de 0
revient utiliser la valeur systme par dfaut. Ce paramtre est seulement support par les systmes qui supportent les symboles TCP_KEEPIDLE ou TCP_KEEPALIVE et sur Windows ; sur les autres systmes, ce paramtre doit valoir zro. Pour
les sessions connectes via une socket de domaine Unix, ce paramtre est ignor et vaut toujours zro.

Note
Sur Windows, une valeur de 0 configurera ce paramtre deux heures car Windows ne fournit pas un moyen
de lire la valeur par dfaut du systme.
tcp_keepalives_interval (integer)
Indique le nombre de secondes entre chaque envoi d'un paquet keepalives sur une connexion qui semble inutilise. Une valeur
de 0 revient utiliser la valeur systme par dfaut. Ce paramtre est seulement support par les systmes qui supportent le
symbole TCP_KEEPINTVL et sur Windows ; sur les autres systmes, ce paramtre doit valoir zro. Pour les sessions connectes via une socket de domaine Unix, ce paramtre est ignor et vaut toujours zro.

Note
Sur Windows, une valeur de 0 configurera ce paramtre une seconde car Windows ne fournit pas un moyen
de lire la valeur par dfaut du systme.
tcp_keepalives_count (integer)
Indique le nombre de paquets TCP keepalive packets envoyer sur une connexion qui semble inutilise. Une valeur de 0 revient utiliser la valeur systme par dfaut. Ce paramtre est seulement support par les systmes qui supportent le symbole
TCP_KEEPCNT ; sur les autres systmes, ce paramtre doit valoir zro. Pour les sessions connectes via une socket de domaine Unix, ce paramtre est ignor et vaut toujours zro.

Note
Ce paramtre n'est pas support sur Windows et doit donc valoir zro.

328

Configuration du serveur

18.3.2. Scurit et authentification


authentication_timeout (integer)
Temps maximum pour terminer l'authentification du client, en secondes. Si un client n'a pas termin le protocole
d'authentification dans ce dlai, le serveur ferme la connexion. Cela protge le serveur des clients bloqus occupant une
connexion indfiniment. La valeur par dfaut est d'une minute. Ce paramtre peut tre configur au lancement du serveur et
dans le fichier postgresql.conf.
ssl (boolean)
Active les connexions SSL. Lire la Section 17.9, Connexions tcp/ip scurises avec ssl avant de l'utiliser. Dsactiv par
dfaut. Ce paramtre ne peut tre configur qu'au lancement du serveur. La communication SSL n'est possible qu'avec des
connexions TCP/IP.
ssl_ciphers (string)
Indique une liste de chiffrements SSL dont l'utilisation est autorise sur des connexions scurises. Voir la page de manuel
openssl pour la liste des chiffrements supports.
ssl_renegotiation_limit (integer)
Specifies how much data can flow over an SSL-encrypted connection before renegotiation of the session keys will take place.
Renegotiation decreases an attacker's chances of doing cryptanalysis when large amounts of traffic can be examined, but it also carries a large performance penalty. The sum of sent and received traffic is used to check the limit. If this parameter is set
to 0, renegotiation is disabled. The default is 512MB.

Note
SSL libraries from before November 2009 are insecure when using SSL renegotiation, due to a vulnerability in
the SSL protocol. As a stop-gap fix for this vulnerability, some vendors shipped SSL libraries incapable of
doing renegotiation. If any such libraries are in use on the client or server, SSL renegotiation should be disabled.
password_encryption (boolean)
Ce paramtre dtermine si un mot de passe, indiqu dans CREATE USER(7) ou ALTER ROLE(7) sans qu'il soit prcis ENCRYPTED ou UNENCRYPTED, doit tre chiffr. Actif par dfaut (chiffre le mot de passe).
krb_server_keyfile (string)
Configure l'emplacement du fichier contenant la cl secrte du serveur Kerberos. Voir la Section 19.3.5, Authentification
Kerberos et la Section 19.3.3, Authentification GSSAPI pour les dtails. Ce paramtre ne peut tre configur que dans le
fichier postgresql.conf ou indiqu sur la ligne de commande.
krb_srvname (string)
Configure le nom du service Kerberos. Voir la Section 19.3.5, Authentification Kerberos pour les dtails. Ce paramtre ne
peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
krb_caseins_users (boolean)
Indique si les noms des utilisateurs Kerberos et GSSAPI doivent tre traits en respectant la casse. Dsactiv par dfaut
(insensible la casse, valeur off), Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu
sur la ligne de commande.
db_user_namespace (boolean)
Active les noms d'utilisateur par base de donnes. Dsactiv par dfaut, ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
Si ce paramtre est activ, les utilisateurs doivent tre crs sous la forme nomutilisateur@nom_base. Quand nomutilisateur est pass par un client se connectant, @ et le nom de la base de donnes sont ajouts au nom de l'utilisateur et
ce nom d'utilisateur spcifique la base est recherch par le serveur. Lorsque des utilisateurs dont le nom contient un @ sont
crs dans l'environnement SQL, ce nom doit tre plac entre guillemets.
db_user_namespace permet aux reprsentations des noms d'utilisateurs du client et du serveur de diffrer. Les vrifications sont toujours faites avec les noms d'utilisateurs du serveur, ce qui fait que les mthodes d'authentification doivent tre
configures pour le nom d'utilisateur du serveur, pas pour celui du client. Comme md5 utilise le nom d'utilisateur comme sel
la fois sur le client et le serveur, md5 ne peut pas tre utilis conjointement avec db_user_namespace.
329

Configuration du serveur

Ce paramtre activ, il reste possible de crer des utilisateurs globaux ordinaires. Il suffit pour cela d'ajouter @ au nom du
client, e.g. joe@. Le @ est supprim avant que le serveur ne recherche ce nom.

Note
Cette fonctionnalit, temporaire, sera supprime lorsqu'une solution complte sera trouve.

18.4. Consommation des ressources


18.4.1. Mmoire
shared_buffers (integer)
Initialise la quantit de mmoire que le serveur de bases de donnes utilise comme mmoire partage. La valeur par dfaut, en
gnral 32 Mo, peut tre automatiquement abaisse si la configuration du noyau ne la supporte pas (dtermin lors de
l'excution de l'initdb). Ce paramtre doit tre au minimum de 128 Ko + 16 Ko par max_connections. (Des valeurs personnalises de BLCKSZ agissent sur ce minimum.) Des valeurs significativement plus importantes que ce minimum sont gnralement ncessaires pour de bonnes performances. Ce paramtre ne peut tre configur qu'au lancement du serveur.
Si vous disposez d'un serveur ddi la base de donnes, avec 1 Go de mmoire ou plus, une valeur de dpart raisonnable
pour ce paramtre est de 25% la mmoire de votre systme. Certains cas peuvent ncessiter une valeur encore plus importante
pour le shared_buffers mais comme PostgreSQL profite aussi du cache du systme d'exploitation, il est peu probable
qu'une allocation de plus de 40% de la mmoire fonctionnera mieux qu'une valeur plus restreinte. Des valeurs importantes
pour le paramtre shared_buffers requirent gnralement une augmentation proportionnelle du checkpoint_segments, pour tendre dans le temps les critures de grandes quantits de donnes, nouvelles ou modifies.
Sur des systmes comprenant moins d'1 Go de mmoire, un pourcentage plus restreint est appropri pour laisser une place
suffisante au systme d'exploitation. De plus, sur Windows, les grandes valeurs pour shared_buffers ne sont pas aussi
efficaces. Vous pouvez avoir de meilleurs rsultats en conservant un paramtrage assez bas et en utilisant le cache du systme
d'exploitation la place. L'chelle habituelle pour shared_buffers sur des systmes Windows va de 64 Mo 512 Mo.
L'augmentation de ce paramtre peut obliger PostgreSQL rclamer plus de mmoire partage System V que ce que la
configuration par dfaut du systme d'exploitation ne peut grer. Voir la Section 17.4.1, Mmoire partage et smaphore
pour de plus amples informations sur l'ajustement de ces paramtres, si ncessaire.
temp_buffers (integer)
Configure le nombre maximum de tampons temporaires utiliss par chaque session de la base de donnes. Ce sont des tampons locaux la session utiliss uniquement pour accder aux tables temporaires. La valeur par dfaut est de 8 Mo. Ce paramtre peut tre modifi l'intrieur de sessions individuelles mais seulement jusqu' la premire utilisation des tables temporaires dans une session ; les tentatives suivantes de changement de cette valeur n'ont aucun effet sur cette session.
Une session alloue des tampons temporaires en fonction des besoins jusqu' atteindre la limite donne par temp_buffers.
Positionner une valeur importante pour les sessions qui ne le ncessitent pas ne cote qu'un descripteur de tampon, soit environ 64 octets, par incrment de temp_buffers. Nanmoins, si un tampon est rellement utilis, 8192 autres octets sont
consomms pour celui-ci (ou, plus gnralement, BLCKSZ octets).
max_prepared_transactions (integer)
Configure le nombre maximum de transactions simultanment dans l'tat prpares (voir PREPARE
TRANSACTION(7)). Zro, la configuration par dfaut, dsactive la fonctionnalit des transactions prpares Ce paramtre ne
peut tre configur qu'au lancement du serveur.
Si vous ne prvoyez pas d'utiliser les transactions prpares, ce paramtre devrait tre positionn zro pour viter toute cration accidentelle de transactions prpares. Au contraire, si vous les utilisez, il peut tre intressant de positionner
max_prepared_transactions au minimum au moins max_connections pour que chaque session puisse avoir sa transaction prpare.
Augmenter ce paramtre peut conduire PostgreSQL rclamer plus de mmoire partage System V que ne le permet la
configuration par dfaut du systme d'exploitation. Voir la Section 17.4.1, Mmoire partage et smaphore pour les informations concernant la faon d'ajuster ces paramtres, si ncessaire.
Lors de l'excution d'un serveur en attente, vous devez configurer ce paramtre la mme valeur ou une valeur plus importante que sur le serveur matre. Sinon, des requtes pourraient ne pas tre autorises sur le serveur en attente.
work_mem (integer)
330

Configuration du serveur

Indique la quantit de mmoire que les oprations de tri interne et les tables de hachage peuvent utiliser avant de basculer sur
des fichiers disque temporaires. La valeur par dfaut est de 1 Mo. Pour une requte complexe, il peut y avoir plusieurs oprations de tri ou de hachage excutes en parallle ; chacune peut utiliser de la mmoire hauteur de cette valeur avant de commencer placer les donnes dans des fichiers temporaires. De plus, de nombreuses sessions peuvent excuter de telles oprations simultanment. La mmoire totale utilise peut, de ce fait, atteindre plusieurs fois la valeur de work_mem ; il est ncessaire de garder cela l'esprit lors du choix de cette valeur. Les oprations de tri sont utilises pour ORDER BY, DISTINCT et
les jointures de fusion. Les tables de hachage sont utilises dans les jointures de hachage, les agrgations et le traitement des
sous-requtes IN fonds sur le hachage.
maintenance_work_mem (integer)
Indique la quantit maximale de mmoire que peuvent utiliser les oprations de maintenance telles que VACUUM,
CREATE INDEX et ALTER TABLE ADD FOREIGN KEY. La valeur par dfaut est de 16 Mo. Puisque seule une de ces
oprations peut tre excute la fois dans une session et que, dans le cadre d'un fonctionnement normal, peu d'oprations de
ce genre sont excutes concurrentiellement sur une mme installation, il est possible d'initialiser cette variable une valeur
bien plus importante que work_mem. Une grande valeur peut amliorer les performances des oprations VACUUM et de la
restauration des sauvegardes.
Quand autovacuum fonctionne, un maximum de autovacuum_max_workers fois cette quantit de mmoire peut tre utilis. Il
convient donc de s'assurer de ne pas configurer la valeur par dfaut de faon trop importante.
max_stack_depth (integer)
Indique la profondeur maximale de la pile d'excution du serveur. La configuration idale pour ce paramtre est la limite
relle de la pile assure par le noyau (configure par ulimit -s ou quivalent local) laquelle est soustraite une marge de
scurit d'un Mo environ. La marge de scurit est ncessaire parce que la profondeur de la pile n'est pas vrifie dans chaque
routine du serveur mais uniquement dans les routines cls potentiellement rcursives telles que l'valuation d'une expression.
Le paramtrage par dfaut est de 2 Mo, valeur faible qui implique peu de risques. Nanmoins, elle peut s'avrer trop petite
pour autoriser l'excution de fonctions complexes. Seuls les superutilisateurs peuvent modifier ce paramtre.
Configurer ce paramtre une valeur plus importante que la limite relle du noyau signifie qu'une fonction rcursive peut occasionner un arrt brutal d'un processus serveur particulier. Sur les plateformes o PostgreSQL peut dterminer la limite du
noyau, il interdit de positionner cette variable une valeur inadquate. Nanmoins, toutes les plateformes ne fournissent pas
cette information, et une grande attention doit tre porte au choix de cette valeur.

18.4.2. Usage des ressources du noyau


max_files_per_process (integer)
Positionne le nombre maximum de fichiers simultanment ouverts par sous-processus serveur. La valeur par dfaut est de
1000 fichiers. Si le noyau assure une limite par processus, il n'est pas ncessaire de s'intresser ce paramtre. Toutefois, sur
certaines plateformes (notamment les systmes BSD) le noyau autorise les processus individuels ouvrir plus de fichiers que
le systme ne peut effectivement en supporter lorsqu'un grand nombre de processus essayent tous d'ouvrir ce nombre de fichiers. Si le message Too many open files ( Trop de fichiers ouverts ) apparat, il faut essayer de rduire ce paramtre.
Ce paramtre ne peut tre configur qu'au lancement du serveur.
shared_preload_libraries (string)
Indique les bibliothques partages prcharger au dmarrage du serveur. Par exemple, '$libdir/malib' implique le
prchargement de malib.so (ou, sur certaines plateformes, malib.sl) depuis le rpertoire d'installation des bibliothques
standard. Tous les noms de bibliothques sont convertis en minuscule sauf s'ils sont compris entre des guillemets doubles. S'il
faut prcharger plusieurs bibliothques, leurs noms doivent tre spars par des virgules. Ce paramtre ne peut tre configur
qu'au lancement du serveur.
Les bibliothques des langages procduraux de PostgreSQL peuvent tre prcharges ainsi, typiquement en utilisant la syntaxe '$libdir/plXXX' o XXX est pgsql, perl, tcl ou python.
Le prchargement d'une bibliothque partage permet d'viter le temps de chargement de la bibliothque sa premire utilisation. Toutefois, la dure de dmarrage de chaque nouveau processus serveur peut augmenter lgrement, mme si aucun de
ces processus n'utilise la bibliothque. Ce paramtre n'est rellement recommand que pour les bibliothques utilises dans la
plupart des sessions.

Note
Sur un hte Windows, le prchargement d'une bibliothque au lancement du serveur ne rduit pas le temps ncessaire au lancement de chaque nouveau processus serveur ; chaque processus serveur recharge toutes les bi331

Configuration du serveur

bliothques dj charges. Nanmoins, shared_preload_libraries est toujours utile sur les htes
Windows car certaines bibliothques partages peuvent ncessiter des oprations qui ne peuvent avoir lieu
qu'au lancement du serveur (par exemple, une bibliothque partage peut rserver des verrous lgers ou de la
mmoire partage, ce qui ne peut tre fait une fois le serveur dmarr).
Si une bibliothque indique est introuvable, le dmarrage du serveur choue.
Chaque bibliothque supporte par PostgreSQL possde un bloc magique qui est vrifi pour garantir la compatibilit.
Pour cette raison, seules les bibliothques PostgreSQL peuvent tre charges de cette faon.

18.4.3. Report du VACUUM en fonction de son cot


Lors de l'excution des commandes VACUUM(7) et ANALYZE(7), le systme maintient un compteur interne qui conserve la
trace du cot estim des diffrentes oprations d'entre/sortie ralises. Quand le cot accumul atteint une limite (indique par
vacuum_cost_limit), le processus traitant l'opration s'arrte un court moment (prcis par vacuum_cost_delay). Puis,
il rinitialise le compteur et continue l'excution.
Le but de cette fonctionnalit est d'autoriser les administrateurs rduire l'impact des entres/sorties de ces commandes en fonction de l'activit des bases de donnes. Nombreuses sont les situations pour lesquelles il n'est pas trs important que les commandes de maintenance telles que VACUUM et ANALYZE se finissent rapidement, mais il est gnralement trs important que
ces commandes n'interfrent pas de faon significative avec la capacit du systme raliser d'autres oprations sur les bases de
donnes. Le report du VACUUM en fonction de son cot fournit aux administrateurs un moyen d'y parvenir.
Cette fonctionnalit est dsactive par dfaut pour les commandes VACUUM lances manuellement. Pour l'activer, la variable
vacuum_cost_delay doit tre initialise une valeur diffrente de zro.
vacuum_cost_delay (integer)
Indique le temps, en millisecondes, de repos du processus quand la limite de cot a t atteinte. La valeur par dfaut est zro,
ce qui dsactive la fonctionnalit de report du VACUUM en fonction de son cot. Une valeur positive active cette fonctionnalit. Sur de nombreux systmes, la rsolution relle du sleep est de 10 millisecondes ; configurer vacuum_cost_delay
une valeur qui n'est pas un multiple de 10 conduit alors au mme rsultat que de le configurer au multiple de 10 suprieur.
Lors d'utilisation de vacuum base sur le cot, les valeurs appropries pour vacuum_cost_delay sont habituellement assez petites, de l'ordre de 10 20 millisecondes. Il est prfrable d'ajuster la consommation de ressource de vacuum en changeant les autres paramtres de cot de vacuum.
vacuum_cost_page_hit (integer)
Indique Le cot estim du nettoyage par VACUUM d'un tampon trouv dans le cache des tampons partags. Cela reprsente
le cot de verrouillage de la rserve de tampons, la recherche au sein de la table de hachage partage et le parcours du contenu
de la page. La valeur par dfaut est 1.
vacuum_cost_page_miss (integer)
Indique le cot estim du nettoyage par VACUUM d'un tampon qui doit tre lu sur le disque. Cela reprsente l'effort fournir
pour verrouiller la rserve de tampons, rechercher dans la table de hachage partage, lire le bloc dsir sur le disque et parcourir son contenu. La valeur par dfaut est 10.
vacuum_cost_page_dirty (integer)
Indique le cot estim de modification par VACUUM d'un bloc prcdemment vide (clean block). Cela reprsente les entres/sorties supplmentaires ncessaires pour vider nouveau le bloc modifi (dirty block) sur le disque. La valeur par dfaut
est 20.
vacuum_cost_limit (integer)
Indique Le cot cumul qui provoque l'endormissement du processus de VACUUM. La valeur par dfaut est 200.

Note
Certaines oprations dtiennent des verrous critiques et doivent donc se terminer le plus vite possible. Les reports
de VACUUM en fonction du cot ne surviennent pas pendant ces oprations. De ce fait, il est possible que le cot
cumul soit bien plus important que la limite indique. Pour viter des dlais inutilement longs dans de tels cas, le
dlai rel est calcul de la faon suivante : vacuum_cost_delay * accumulated_balance / vacuum_cost_limit avec un maximum de vacuum_cost_delay * 4.
332

Configuration du serveur

18.4.4. Processus d'criture en arrire-plan


Il existe un processus serveur spar appel background writer dont le but est d'crire les tampons sales (parce que nouveaux
ou modifis). Ce processus crit les tampons partags pour que les processus serveur grant les requtes des utilisateurs n'aient jamais ou peu frquemment attendre qu'une criture se termine. Nanmoins, ce processus d'criture en tche de fond implique une
augmentation globale de la charge des entres/sorties disque car, quand une page frquemment modifie pourrait n'tre crite
qu'une seule fois par CHECKPOINT, le processus d'criture en tche de fond pourrait l'avoir crit plusieurs fois si cette page a t
modifie plusieurs fois dans le mme intervalle. Les paramtres discuts dans cette sous-section peuvent tre utiliss pour configurer finement son comportement pour les besoins locaux.
bgwriter_delay (integer)
Indique le dlai entre les tours d'activit du processus d'criture en arrire-plan. chaque tour, le processus crit un certain
nombre de tampons modifis (contrlable par les paramtres qui suivent). Puis, il s'endort pour bgwriter_delay millisecondes et recommence. La valeur par dfaut est de 200 millisecondes. Sur de nombreux systmes, la rsolution relle du sleep
est de 10 millisecondes ; positionner bgwriter_delay une valeur qui n'est pas un multiple de 10 peut avoir le mme rsultat que de le positionner au multiple de 10 suprieur. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
bgwriter_lru_maxpages (integer)
Nombre maximum de tampons qui peuvent tre crits chaque tour par le processus d'criture en tche de fond. Le configurer
zro dsactive l'criture en tche de fond (sauf en ce qui concerne l'activit des points de vrification). La valeur par dfaut
est de 100 tampons. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de
commande.
bgwriter_lru_multiplier (floating point)
Le nombre de tampons sales crits chaque tour est bas sur le nombre de nouveaux tampons qui ont t requis par les processus serveur lors des derniers tours. Le besoin rcent moyen est multipli par bgwriter_lru_multiplier pour arriver une estimation du nombre de tampons ncessaire au prochain tour. Les tampons sales sont crits pour qu'il y ait ce
nombre de tampons propres, rutilisables. (Nanmoins, au maximum bgwriter_lru_maxpages tampons sont crits par
tour.) De ce fait, une configuration de 1.0 reprsente une politique d'criture juste temps d'exactement le nombre de tampons prdits. Des valeurs plus importantes fournissent une protection contre les pics de demande, alors qu'une valeur plus petite laisse intentionnellement des critures aux processus serveur. La valeur par dfaut est de 2. Ce paramtre ne peut tre
configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
Des valeurs plus faibles de bgwriter_lru_maxpages et bgwriter_lru_multiplier rduisent la charge supplmentaire des entres/sorties induite par le processus d'criture en arrire-plan. En contrepartie, la probabilit que les processus serveurs
effectuent plus d'critures par eux-mmes augmente, ce qui retarde les requtes interactives.

18.4.5. Comportement asynchrone


effective_io_concurrency (integer)
Positionne le nombre d'oprations d'entres/sorties disque concurrentes que PostgreSQL pense pouvoir excuter simultanment. Augmenter cette valeur va augmenter le nombre d'oprations d'entre/sortie que chaque session PostgreSQL individuelle essayera d'excuter en parallle. Les valeurs autorises vont de 1 1000, ou zro pour dsactiver l'excution de requtes d'entre/sortie asynchrones. Actuellement, ce paramtre ne concerne que les parcours de type bitmap heap.
Un bon point dpart pour ce paramtre est le nombre de disques que comprend un agrgat par bande RAID 0 ou miroir RAID
1 utilis pour la base de donnes. (Pour du RAID 5, le disque de parit ne devrait pas tre pris en compte.) Toutefois, si la
base est souvent occupe par de nombreuses requtes excutes dans des sessions concurrentes, des valeurs plus basses
peuvent tre suffisantes pour maintenir le groupe de disques occup. Une valeur plus leve que ncessaire pour maintenir les
disques occups n'aura comme seul rsultat que de surcharger le processeur.
Pour des systmes plus exotiques, comme du stockage mmoire ou un groupement RAID qui serait limit par la bande passante du bus, la valeur correcte pourrait tre le nombre de chemins d'entres/sorties disponibles. Il pourrait tre ncessaire
d'exprimenter afin d'obtenir la valeur idale.
Les entres/sorties asynchrones dpendent de la prsence d'une fonction posix_fadvise efficace, ce que n'ont pas certains
systmes d'exploitation. Si la fonction n'est pas prsente, alors positionner ce paramtre une valeur autre que zro entranera
une erreur. Sur certains systmes (par exemple Solaris), cette fonction est prsente mais n'a pas d'effet.

18.5. Write Ahead Log


333

Configuration du serveur

Voir aussi la Section 29.4, Configuration des journaux de transaction pour les dtails concernant l'optimisation des WAL.

18.5.1. Paramtres
wal_level (enum)
wal_level dtermine la quantit d'informations crite dans les journaux de transactions. La valeur par dfaut est
minimal, ce qui permet d'crire seulement les informations ncessaires pour survivre un arrt brutal ou un arrt immdiat. archive ajoute quelques enregistrements supplmentaires pour permettre l'archivage des journaux de transactions.
hot_standby en ajoute encore plus pour permettre l'excution de requtes en lecture seule sur le serveur en attente. Ce paramtre peut seulement tre configur au lancement du serveur.
Au niveau minimal, certains enregistrements dans les journaux de transactions peuvent tre vits, ce qui peut rendre ces
oprations plus rapides (voir Section 14.4.7, Dsactiver l'archivage des journaux de transactions et la rplication en flux ).
Les oprations concernes par cette optimisation incluent :
CREATE TABLE AS
CREATE INDEX
CLUSTER
COPY dans des tables qui ont t cres ou tronques dans la mme transaction
Mais, du coup, les journaux au niveau minimal ne contiennent pas suffisamment d'informations pour reconstruire les donnes
partir d'une sauvegarde de base et des journaux de transactions. Donc, les niveaux archive ou hot_standby doivent
tre utiliss pour activer l'archivage des journaux de transactions (archive_mode) et la rplication en flux.
Au niveau hot_standby, en plus des informations que trace dj le niveau archive, plus d'informations sont ncessaires
pour reconstruire le statut des transactions en cours partir du journal de transactions. Pour activer les requtes en lecture
seule sur un serveur en attente, wal_level doit tre configur hot_standby sur le serveur principal et hot_standby doit
tre activ sur le serveur en attente. Il existe une diffrence mesurable de performances entre l'utilisation des niveaux
hot_standby et archive, donc un retour d'exprience serait apprci si l'impact est ressenti en production.
fsync (boolean)
Si ce paramtre est activ, le serveur PostgreSQL tente de s'assurer que les mises jour sont crites physiquement sur le
disque l'aide d'appels systme fsync() ou de mthodes quivalentes (voir wal_sync_method). Cela permet de s'assurer
que le cluster de bases de donnes peut revenir un tat cohrent aprs une panne matrielle ou du systme d'exploitation.
Bien que dsactiver fsync amliore frquemment les performances, cela peut avoir pour consquence une corruption des
donnes non rcuprables dans le cas d'une perte de courant ou d'un crash du systme. Donc, il est seulement conseill de
dsactiver fsync si vous pouvez facilement recrer la base de donnes complte partir de donnes externes.
Quelques exemples de circonstances permettant de dsactiver fsync : le chargement initial d'une nouvelle instance partir
d'une sauvegarde, l'utilisation de l'instance pour traiter un flot de donnes aprs quoi la base sera supprime puis recre, la
cration d'un clone d'une base en lecture seule, clone qui serait recr frquemment et n'est pas utilis pour du failover. La
haute qualit du matriel n'est pas une justification suffisante pour dsactiver fsync.
Dans de nombreuses situations, dsactiver synchronous_commit pour les transactions non critiques peut fournir une grande
partie des performances de la dsactivation de fsync, sans les risques associs de corruption de donnes.
fsync ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande. Si ce paramtre est dsactiv (off), il est intressant de dsactiver aussi full_page_writes.
synchronous_commit (enum)
Indique si la validation des transactions doit attendre l'criture des enregistrements WAL avant que la commande ne renvoie
une indication de russite au client. Les valeurs valides sont on, local et off. La configuration par dfaut, et la plus
sre, est on. Quand ce paramtre est dsactiv (off), il peut exister un dlai entre le moment o le succs est rapport et le
moment o la transaction est vraiment protge d'un arrt brutal du serveur. (Le dlai maximum est de trois fois
wal_writer_delay.) Contrairement fsync, la configuration de ce paramtre off n'implique aucun risque d'incohrence dans
la base de donnes : un arrt brutal du systme d'exploitation ou d'une base de donnes peut rsulter en quelques transactions
rcentes prtendument valides perdues malgr tout. Cependant, l'tat de la base de donnes est identique celui obtenu si les
transactions avaient t correctement annules. C'est pourquoi la dsactivation de synchronous_commit est une alternative utile quand la performance est plus importante que la sret de la transaction. Pour plus de discussion, voir Section 29.3,
Validation asynchrone (Asynchronous Commit) .
Si synchronous_standby_names est configur, ce paramtre contrle aussi si la validation d'une transaction attend que les enregistrements de journaux de transactions pour cette transaction soient bien vids sur disque et rpliqus sur le serveur en
standby. L'attente de la validation durera jusqu' ce qu'une rponse du serveur en standby synchrone indique qu'il a crit
l'enregistrement sur le disque. Si la rplication synchrone est utilis, il serait logique soit d'attendre que les enregistrements
334

Configuration du serveur

des journaux de transactions soient crits sur les disques local et distant, soit de permettre la transaction de valider en asynchrone. Nanmoins, la valeur spciale local est disponible pour les transactions qui souhaiente attendre le vidage local sur
disque et non pas la rplication synchrone.
Ce paramtre peut tre chang tout moment ; le comportement pour toute transaction est dtermin par la configuration en
cours lors de la validation. Il est donc possible et utile d'avoir certaines validations valides en synchrone et d'autres en asynchrone. Par exemple, pour raliser une validation asynchrone de transaction plusieurs instructions avec une valeur par dfaut
inverse, on excute l'instruction SET LOCAL synchronous_commit TO OFF dans la transaction.
wal_sync_method (enum)
Mthode utilise pour forcer les mises jour des WAL sur le disque. Si fsync est dsactiv, alors ce paramtre est inapplicable, car les mises jour des journaux de transactions ne sont pas du tout forces. Les valeurs possibles sont :

open_datasync (crit les fichiers WAL avec l'option O_DSYNC de open())

fdatasync (appelle fdatasync() chaque validation)

fsync_writethrough (appelle fsync() chaque validation, forant le mode write-through de tous les caches
disque en criture)

fsync (appelle fsync() chaque validation)

open_sync (crit les fichiers WAL avec l'option O_SYNC de open())

Ces options ne sont pas toutes disponibles sur toutes les plateformes. La valeur par dfaut est la premire mthode de la liste
ci-dessus supporte par la plateforme. Les options open_* utilisent aussi O_DIRECT s'il est disponible. L'outil src/
tools/fsync disponible dans le code source de PostgreSQL permet de tester les performances des diffrentes mthodes de
synchronisation. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de
commande.
full_page_writes (boolean)
Quand ce paramtre est activ, le serveur crit l'intgralit du contenu de chaque page disque dans les WAL lors de la premire modification de cette page qui intervient aprs un point de vrification. C'est ncessaire car l'criture d'une page lors
d'un plantage du systme d'exploitation peut n'tre que partielle, ce qui conduit une page sur disque qui contient un mlange
d'anciennes et de nouvelles donnes. Les donnes de modification de niveau ligne stockes habituellement dans les WAL ne
sont pas suffisantes pour restaurer compltement une telle page lors de la rcupration qui suit la panne. Le stockage de
l'image de la page complte garantit une restauration correcte de la page, mais au prix d'un accroissement de la quantit de
donnes crire dans les WAL. (Parce que la relecture des WAL dmarre toujours un point de vrification, il suffit de faire
cela lors de la premire modification de chaque page survenant aprs un point de vrification. De ce fait, une faon de rduire
le cot d'criture de pages compltes consiste augmenter le paramtre rglant les intervalles entre points de vrification.)
La dsactivation de ce paramtre acclre les oprations normales, mais peut aboutir soit une corruption impossible corriger soit une corruption silencieuse, aprs un chec systme. Les risques sont similaires la dsactivation de fsync, bien
que moindres. Sa dsactivation devrait se faire en se basant sur les mmes recommandations que cet autre paramtre.
La dsactivation de ce paramtre n'affecte pas l'utilisation de l'archivage des WAL pour la rcupration d'un instantan, aussi
appel PITR (voir Section 24.3, Archivage continu et rcupration d'un instantan (PITR) ).
Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande. Activ
par dfaut (on).
wal_buffers (integer)
La quantit de mmoire partage utilise pour les donnes des journaux de transactions qui n'ont pas encore t crites sur
disque. La configuration par dfaut de -1 slectionne une taille gale 1/32 (environ 3%) de shared_buffers, mais pas moins
64kB et pas plus que la taille d'un journal de transactions, soit gnralement 16MB. Cette valeur peut tre configur manuellement si le choix automatique est trop gros ou trop petit, mais tout valeur positive infrieure 32kB sera traite comme tant
exactement 32kB. Ce paramtre ne peut tre configur qu'au dmarrage du serveur.
Le contenu du cache des journaux de transactions est crit sur le disque chaque validation d'une transaction, donc des valeurs trs importantes ont peu de chance d'apporter un gain significatif. Nanmoins, configurer cette valeur au moins
quelques mgaoctets peut amliorer les performances en criture sur un serveur charg quand plusieurs clients valident en
mme temps. La configuration automatique slectionn par dfaut avec la valeur -1 devrait tre convenable.
L'augmentation de ce paramtre peut conduire PostgreSQL rclamer plus de tampons partags System V que ne le permet la configuration par dfaut du systme d'exploitation. Voir la Section 17.4.1, Mmoire partage et smaphore pour les
informations sur la faon d'ajuster ces paramtres, si ncessaire.

335

Configuration du serveur

wal_writer_delay (integer)
Indique le dlai entre les tours d'activit pour l'enregistreur des WAL. chaque tour, l'enregistreur place les WAL sur disque.
Il s'endort ensuite pour wal_writer_delay millisecondes et recommence. La valeur par dfaut est de 200 millisecondes
(200ms). Pour de nombreux systmes, la rsolution relle du sleep est de 10 millisecondes ; configurer
wal_writer_delay une valeur qui n'est pas un multiple de 10 a le mme rsultat que de le configurer au multiple de 10
immdiatement suprieur. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la
ligne de commande.
commit_delay (integer)
Dlai entre l'enregistrement d'une validation dans le tampon WAL et le vidage du tampon sur le disque, en microsecondes. Un
dlai diffrent de zro peut autoriser la validation de plusieurs transactions en un seul appel systme fsync(), si la charge
systme est assez importante pour que des transactions supplmentaires soient prtes dans l'intervalle donn. Mais le dlai est
perdu si aucune autre transaction n'est prte tre valide. De ce fait, le dlai n'est trait que si, au minimun, commit_siblings autres transactions sont actives au moment o le processus serveur a crit son enregistrement de validation.
La valeur par dfaut est zro (pas de dlai).
commit_siblings (integer)
Nombre minimum de transactions concurrentes ouvertes en mme temps ncessaires avant d'attendre le dlai commit_delay. Une valeur plus importante rend plus probable le fait qu'au moins une autre transaction soit prte valider pendant le dlai. La valeur par dfaut est de cinq transactions.

18.5.2. Points de vrification


checkpoint_segments (integer)
Nombre maximum de journaux de transaction entre deux points de vrification automatique des WAL (chaque segment fait
normalement 16 Mo). La valeur par dfaut est de trois segments. Augmenter ce paramtre peut accroitre le temps ncessaire
une rcupration aprs un arrt brutal. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
checkpoint_timeout (integer)
Temps maximum entre deux points de vrification automatique des WAL, en secondes. La valeur par dfaut est de cinq minutes. Augmenter ce paramtre peut accroitre le temps ncessaire une rcupration aprs un arrt brutal. Ce paramtre ne
peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
checkpoint_completion_target (floating point)
Prcise la cible pour la fin du CHECKPOINT, sous la format d'une fraction de temps entre deux CHECKPOINT. La valeur
par dfaut est 0.5. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de
commande.
checkpoint_warning (integer)
Si deux points de vrification imposs par le remplissage des fichiers segment interviennent dans un dlai plus court que celui
indiqu par ce paramtre (ce qui laisse supposer qu'il faut augmenter la valeur du paramtre checkpoint_segments), un
message est crit dans le fichier de traces du serveur. Par dfaut, 30 secondes. Une valeur nulle (0) dsactive cet avertissement. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.

18.5.3. Archivage
archive_mode (boolean)
Quand archive_mode est activ, les segments WAL remplis peuvent tre archivs en configurant archive_command. archive_mode et archive_command sont des variables spares de faon ce que archive_command puisse tre modifie sans quitter le mode d'archivage. Ce paramtre ne peut tre configur qu'au lancement du serveur. archive_mode ne
peut pas tre activ quand wal_level est configur minimal.
archive_command (string)
Commande shell excuter pour archiver un segment termin de la srie des fichiers WAL. Tout %p dans la chane est remplac par le chemin du fichier archiver et tout %f par le seul nom du fichier. (Le chemin est relatif au rpertoire de travail du
serveur, c'est--dire le rpertoire de donnes du cluster.) %% est utilis pour intgrer un caractre % dans la commande. Il est
important que la commande renvoit un code zro seulement si elle a russit l'archivage. Pour plus d'informations, voir Sec336

Configuration du serveur

tion 24.3.1, Configurer l'archivage WAL .


Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande. Il est
ignor sauf si archive_mode a t activ au lancement du serveur. Si archive_command est une chane vide (la valeur
par dfaut) alors que archive_mode est activ, alors l'archivage des journaux de transactions est dsactiv temporairement
mais le serveur continue d'accumuler les fichiers des journaux de transactions dans l'espoir qu'une commande lui soit rapidement propose. Configurer archive_command une commande qui ne fait rien tout en renvoyant true, par exemple /
bin/true (REM sur Windows), dsactive l'archivage mais casse aussi la chane des fichiers des journaux de transactions ncessaires pour la restauration d'une archive. Cela ne doit donc tre utilis quand lors de circonstances inhabituelles.
archive_timeout (integer)
Le archive_command n'est appel que pour les segments WAL remplis. De ce fait, si le serveur n'engendre que peu de trafic
WAL (ou qu'il y a des priodes de plus faible activit), il se peut qu'un long moment s'coule entre la fin d'une transaction et
son archivage certain. Pour limiter l'ge des donnes non encore archives, archive_timeout peut tre configur pour
forcer le serveur basculer priodiquement sur un nouveau segment WAL. Lorsque ce paramtre est positif, le serveur bascule sur un nouveau segment chaque fois que archive_timeout secondes se sont coules depuis le dernier changement de segment et qu'il n'y a pas eu d'activit de la base de donnes, y compris un seul CHECKPOINT. (augmenter checkpoint_timeout rduira les CHECKPOINT inutiles sur un systme non utilis.) Les fichiers archivs clos par anticipation
suite une bascule impose sont toujours de la mme taille que les fichiers complets. Il est donc dconseill de configurer un
temps trs court pour archive_timeout -- cela va faire exploser la taille du stockage des archives. Un paramtrage d'archive_timeout de l'ordre de la minute est habituellement raisonnable. Cependant, vous devriez considrer l'utilisation de
la rplication en flux la place de l'archivage si vous voulez que les donnes soient envoyes du serveur matre plus rapidement que cela. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.

18.6. Rplication
Ces paramtres contrlent le comportement de la fonctionnalit interne de rplication en flux (voir Section 25.2.5, Streaming
Replication ). Ces paramtres sont configurer sur le serveur matre alors que d'autres sont configurer sur le ou les serveurs en
standby qui recevront les donnes de rplication.

18.6.1. Serveur matre


Ces paramtres peuvent tre configurs sur le serveur primaire qui va envoyer les donnes de rplication un ou plusieurs serveurs. Notez qu'en plus de ces paramtres, wal_level doit tre configur correctement sur le serveur matre, et vous voudrez aussi
typiquement activer l'archivage des journaux de transactions (voir Section 18.5.3, Archivage ). Les valeurs de ces paramtres
sur les serveurs en standby n'ont pas d'importance. Il est cependant intressant de les configurer en prvision du basculement d'un
serveur standby en serveur matre.
max_wal_senders (integer)
Indique le nombre maximum de connexions concurrentes partir des serveurs en attente (c'est--dire le nombre maximum de
processus walsender en cours d'excution). La valeur par dfaut est zro, signifiant que la rplication est dsactive. Les processus walsender sont lanables jusqu atteindre le nombre total de connexions, donc ce paramtre ne peut pas tre suprieur
max_connections. Ce paramtre peut seulement tre configur au lancement du serveur. wal_level doit tre configur
archive ou hot_standby pour permettre les connexions des serveurs en attente.
wal_sender_delay (integer)
Prcise le dlai entre deux tours d'activit des processus walsender. chaque tour, le processus walsender envoie tous les enregistrements WAL accumuls depuis sont dernier tour. Il s'endort ensuite pour wal_sender_delay millisecondes et recommence. L'attente est interrompue par une validation de transaction, donc les effets d'une transaction valide sont envoys
aux serveurs en attente ds que la validation survient, quelque soit la configuration de ce paramtre. La valeur par dfaut est
de une seconde (1s). Notez que sur de nombreux systmes la rsolution relle du dlai d'endormissement en de 10 millisecondes ; configurer wal_sender_delay une valeur qui n'est pas un multiple de 10 pourrait avoir le mme rsultat que
de le configurer la valeur suivante multiple de 10. Ce paramtre peut seulement tre configur dans le fichier postgresql.conf ou sur la ligne de commande du serveur.
wal_keep_segments (integer)
Indique le nombre minimum de journaux de transactions passs conserver dans le rpertoire pg_xlog, au cas o un serveur en attente a besoin de les rcuprer pour la rplication en flux. Chaque fichier fait normalement 16 Mo. Si un serveur en
attente connect au primaire se laisse distancer par le primaire pour plus de wal_keep_segments fichiers, le primaire
pourrait supprimer un journal de transactions toujours utile au serveur en attente, auquel cas la connexion de rplication serait
ferme. (Nanmoins, le serveur en attente peut continuer la restauration en rcuprant le segment des archives si l'archivage
des journaux de transactions est utilis.)
337

Configuration du serveur

Cela configure seulement le nombre minimum de fichiers conserver dans pg_xlog ; le systme pourrait avoir besoin de
conserver plus de fichiers pour l'archivage ou pour restaurer partir d'un CHECKPOINT. Si wal_keep_segments vaut
zro (ce qui est la valeur par dfaut), le systme ne conserve aucun fichier supplmentaire pour les serveurs en attente et le
nombre des anciens journaux disponibles pour les serveurs en attente est seulement bas sur l'emplacement du dernier
CHECKPOINT ainsi que sur l'tat de l'archivage des journaux de transactions. Ce paramtre n'a aucun effet sur les restartpoints. Ce paramtre peut seulement tre configur dans le fichier postgresql.conf ou sur la ligne de commande du serveur.
vacuum_defer_cleanup_age (integer)
Indique le nombre de transactions pendant lesquelles les VACUUM et les mises jour HOT reporteront plus tard le nettoyage des versions de lignes mortes. La valeur par dfaut est de zro transaction. Cela veut dire que les versions de lignes
mortes peuvent tre supprimes ds que possible, autrement dit partir du moment o elles ne sont plus visibles par les transactions en cours d'excution. Vous pourriez augmenter la valeur de ce paramtre sur un serveur matre qui accepte des serveurs en attente de type hotstandby, comme dcrit dans Section 25.5, Hot Standby . Ceci donne plus de temps aux requtes
sur les serveurs hotstandby pour qu'elles se terminent avec succs, sans conflit relatif un nettoyage des lignes. Nanmoins,
comme la valeur est mesure en terme de nombres de transactions en criture survenant sur le serveur matre, il est difficile de
prdire le temps supplmentaire que cela met disposition des requtes sur les serveurs hotstandby. Ce paramtre peut seulement tre configur dans le fichier postgresql.conf ou sur la ligne de commande du serveur.
Pensez configurer hot_standby_feedback comme alternative ce paramtre.
replication_timeout (integer)
Termine les connexions de rplication inactives depuis au moins ce nombre de millisecondes. C'est utile pour que le serveur
matre dtecte un arrt brutal du serveur en standby ou un problme rseau. Une valeur de zro dsactive ce mcanisme. Ce
paramtre peut seulement tre configur dans le fichier postgresql.conf ou sur la ligne de commande du serveur. La valeur par dfaut est de 60 secondes.
Pour empcher l'arrt prmatur des connexions, wal_receiver_status_interval doit tre activ sur le serveur en standby et sa
valeur doit tre infrieur la valeur de replication_timeout.
synchronous_standby_names (string)
Prcise une liste de noms de serveur en standby, chacun spar par une virgule, acceptant une rplication synchrone, comme
dcrite dans Section 25.2.6, Rplication synchrone . tout moment, il y aura au maximum un serveur standby synchrone
actif ; les transactions en attente de validation seront autorises continuer aprs que le serveur standby aura confirm la rception des donnes. Le standby synchrone est le premier serveur standby nomm dans cette liste, qui est la fois connect et
qui rcupre les donnes en temps rel (comme indiqu par l'tat streaming dans la vue pg_stat_replication). Les
autres serveurs standards apparaissant plus tard dans cette liste sont des serveurs standbys synchrones potentiels. Si le serveur
standby synchrone se dconnecte, quel qu'en soit la raison, il sera immdiatement remplac par le prochain standby dans
l'ordre des priorits. Indiquer plus qu'un nom de standby peut augmenter fortement la haute disponibilit.
Dans ce cadre, le nom d'un serveur standby correspond au paramtre application_name du standby, qui est configurable
dans primary_conninfo du walreceiver du standby. Il n'existe aucun paramtre pour s'assurer de l'unicit. Dans le cas o
des serveurs ont le mme nom, un des serveurs standby sera choisi pour tre le serveur standby synchrone mais il est impossible de dterminer lequel sera choisi. L'entre spciale * correspond tout application_name, cela incluant le nom de
l'application par dfaut de walreceiver.
Si aucun nom de serveur en standby synchrone n'est indiqu ici, alors la rplication synchrone n'est pas active et la validation
des transactions n'attendra jamais la rplication. Ceci est la configuration par dfaut. Mme si la rplication synchrone est active, les transactions individuelles peuvent tre configures pour ne pas avoir attendre la rplication en configurant le paramtre synchronous_commit local ou off.
Ce paramtre peut seulement tre configur dans le fichier postgresql.conf ou sur la ligne de commande du serveur.

18.6.2. Serveurs standby (en attente)


Ces paramtres contrlent le comportement d'un serveur en attente pour qu'il puisse recevoir les donnes de rplication. Leur
configuration sur le serveur matre n'a aucune importance.
hot_standby (boolean)
Indique si vous pouvez vous connecter et excuter des requtes lors de la restauration, comme indiqu dans Section 25.5,
Hot Standby . Dsactiv par dfaut. Ce paramtre peut seulement tre configur au lancement du serveur. Il a un effet
seulement lors de la restauration des archives ou en mode serveur en attente.
max_standby_archive_delay (integer)
Quand le Hot Standby est activ, ce paramtre dtermine le temps maximum d'attente que le serveur esclave doit observer
avant d'annuler les requtes en lecture qui entreraient en conflit avec des enregistrements des journaux de transactions appli338

Configuration du serveur

quer, comme c'est dcrit dans Section 25.5.2, Gestion des conflits avec les requtes . max_standby_archive_delay
est utilis quand les donnes de journaux de transactions sont lues partir des archives de journaux de transactions (et du
coup accuse un certain retard par rapport au serveur matre). La valeur par dfaut est de 30 secondes. L'unit est la milliseconde si cette dernire n'est pas spcifie. Une valeur de -1 autorise le serveur en attente attendre indfiniment la fin
d'excution des requtes en conflit. Ce paramtre peut seulement tre configur dans le fichier postgresql.conf ou sur
la ligne de commande du serveur.
Notez que max_standby_archive_delay ne correspond pas au temps d'excution maximum d'une requte avant son
annulation ; il s'agit plutt du temps maximum autoris pour enregistrer les donnes d'un journal de transactions. Donc, si une
requte a occasionn un dlai significatif au dbut du traitement d'un journal de transactions, les requtes suivantes auront un
dlai beaucoup moins important.
max_standby_streaming_delay (integer)
Quand Hot Standby est activ, ce paramtre dtermine le dlai maximum d'attente que le serveur esclave doit observer avant
d'annuler les requtes en lecture qui entreraient en conflit avec les enregistrements de transactions appliquer, comme c'est
dcrit dans Section 25.5.2, Gestion des conflits avec les requtes . max_standby_streaming_delay est utilis
quand les donnes des journaux de donnes sont reues via la connexion de la rplication en flux. La valeur par dfaut est de
30 secondes. L'unit est la milliseconde si cette dernire n'est pas spcifie. Une valeur de -1 autorise le serveur en attente
attendre indfiniment la fin d'excution des requtes en conflit. Ce paramtre peut seulement tre configur dans le fichier
postgresql.conf ou sur la ligne de commande du serveur.
Notez que max_standby_streaming_delay ne correspond pas au temps d'excution maximum d'une requte avant son
annulation ; il s'agit plutt du temps maximum autoris pour enregistrer les donnes d'un journal de transactions une fois
qu'elles ont t rcupres du serveur matre. Donc, si une requte a occasionn un dlai significatif au dbut du traitement
d'un journal de transactions, les requtes suivantes auront un dlai beaucoup moins important.
wal_receiver_status_interval (integer)
Indique la frquence minimale pour que le processus de rception (walreceiver) sur le serveur de standby envoie des informations sur la progression de la rplication au serveur principal, o elles sont disponibles en utilisant la vue
pg_stat_replication. Le serveur en standby renvoie la dernire position crite dans le journal de transactions, la dernire position vide sur disque du journal de transactions, et la dernire position rejoue. La valeur de ce paramtre est
l'intervalle maximum, en secondes, entre les rapports. Les mises jour sont envoyes chaque fois que les positions d'criture
ou de vidage ont changes et de toute faon au moins aussi frquemment que l'indique ce paramtre. Du coup, la position de
rejeu pourrait avoir un certain retard par rapport la vraie position. Configurer ce paramtre zro dsactive compltement
les mises jour de statut. Ce paramtre peut seulement tre configur dans le fichier postgresql.conf ou sur la ligne de
commande du serveur. La valeur par dfaut est de dix secondes.
Quand replication_timeout est activ sur le serveur principal, wal_receiver_status_interval doit tre activ et sa
valeur doit tre infrieure la valeur de replication_timeout.
hot_standby_feedback (boolean)
Spcifie si un serveur en Hot Standby enverra des informations au serveur principal sur les requtes en cours d'excution sur
le serveur en standby. Ce paramtre peut tre utilis pour liminer les annulations de requtes ncessaires au nettoyage des
enregistrements. Par contre, il peut causer une fragmentation plus importante sur le serveur principal pour certaines charges.
Les
messages
d'informations
ne
seront
pas
envoys
plus
frquemment
qu'une
fois
par
wal_receiver_status_interval. La valeur par dfaut est off. Ce paramtre peut seulement tre configur dans le
fichier postgresql.conf ou sur la ligne de commande du serveur.

18.7. Planification des requtes


18.7.1. Configuration de la mthode du planificateur
Ces paramtres de configuration fournissent une mthode brutale pour influencer les plans de requte choisis par l'optimiseur de
requtes. Si le plan choisi par dfaut par l'optimiseur pour une requte particulire n'est pas optimal, une solution temporaire peut
provenir de l'utilisation de l'un de ces paramtres de configuration pour forcer l'optimiseur choisir un plan diffrent. De
meilleures faons d'amliorer la qualit des plans choisis par l'optimiseur passent par l'ajustement des constantes de cot du planificateur (voir Section 18.7.2, Constantes de cot du planificateur ), le lancement plus frquent de ANALYZE(7),
l'augmentation de la valeur du paramtre de configuration default_statistics_target et l'augmentation du nombre de statistiques rcupres pour des colonnes spcifiques en utilisant ALTER TABLE SET STATISTICS.
enable_bitmapscan (boolean)
Active ou dsactive l'utilisation des plans de parcours de bitmap (bitmap-scan) par le planificateur de requtes. Activ par dfaut (on).

339

Configuration du serveur

enable_hashagg (boolean)
Active ou dsactive l'utilisation des plans d'agrgation hache (hashed aggregation) par le planificateur. Activ par dfaut
(on).
enable_hashjoin (boolean)
Active ou dsactive l'utilisation des jointures de hachage (hash-join) par le planificateur. Activ par dfaut (on).
enable_indexscan (boolean)
Active ou dsactive l'utilisation des parcours d'index (index-scan) par le planificateur. Activ par dfaut (on).
enable_material (boolean)
Active ou dsactive l'utilisation de la matrialisation par le planificateur. Il est impossible de supprimer compltement son utilisation mais la dsactivation de cette variable permet d'empcher le planificateur d'insrer des nuds de matrialisation sauf
dans le cas o son utilisation est obligatoire pour des raisons de justesse de rsultat. Activ par dfaut (on).
enable_mergejoin (boolean)
Active ou dsactive l'utilisation des jointures de fusion (merge-join)par le planificateur. Activ par dfaut (on).
enable_nestloop (boolean)
Active ou dsactive l'utilisation des jointures de boucles imbriques (nested-loop) par le planificateur. Il n'est pas possible de
supprimer compltement les jointures de boucles imbriques mais la dsactivation de cette variable dcourage le planificateur
d'en utiliser une si d'autres mthodes sont disponibles. Activ par dfaut (on).
enable_seqscan (boolean)
Active ou dsactive l'utilisation des parcours squentiels (sequential scan) par le planificateur. Il n'est pas possible de supprimer compltement les parcours squentiels mais la dsactivation de cette variable dcourage le planificateur d'n utiliser un si
d'autres mthodes sont disponibles. Activ par dfaut (on).
enable_sort (boolean)
Active ou dsactive l'utilisation des tapes de tri explicite par le planificateur. Il n'est pas possible de supprimer compltement
ces tris mais la dsactivation de cette variable dcourage le planificateur d'en utiliser un si d'autres mthodes sont disponibles.
Activ par dfaut (on).
enable_tidscan (boolean)
Active ou dsactive l'utilisation des parcours de TID par le planificateur. Activ par dfaut (on).

18.7.2. Constantes de cot du planificateur


Les variables de cot dcrites dans cette section sont mesures sur une chelle arbitraire. Seules leurs valeurs relatives ont un intrt. De ce fait, augmenter ou diminuer leurs valeurs d'un mme facteur n'occasione aucun changement dans les choix du planificateur. Par dfaut, ces variables de cot sont bases sur le cot de rcupration squentielle d'une page ; c'est--dire que
seq_page_cost est, par convention, positionn 1.0 et les autres variables de cot sont configures relativement cette rfrence. Il est toutefois possible d'utiliser une autre chelle, comme les temps d'excution rels en millisecondes sur une machine
particulire.

Note
Il n'existe malheureuresement pas de mthode bien dfinie pour dterminer les valeurs idales des variables de
cot. Il est prfrable de les considrer comme moyennes sur un jeu complet de requtes d'une installation particulire. Cela signifie que modifier ces paramtres sur la seule base de quelques expriences est trs risqu.
seq_page_cost (floating point)
Initialise l'estimation faite par le planificateur du cot de rcupration d'une page disque incluse dans une srie de rcuprations squentielles. La valeur par dfaut est 1.0. Cette valeur peut tre surcharg par un tablespace spcifique en configurant
le paramtre du mme nom pour un tablespace (voir ALTER TABLESPACE(7)).
random_page_cost (floating point)
Initialise l'estimation faite par le planificateur du cot de rcupration non-squentielle d'une page disque. Mesure comme un
multiple du cot de rcupration d'une page squentielle, sa valeur par dfaut est 4.0. Cette valeur peut tre surcharg par un
tablespace spcifique en configurant le paramtre du mme nom pour un tablespace (voir ALTER TABLESPACE(7)).
340

Configuration du serveur

Rduire cette valeur par rapport seq_page_cost incite le systme privilgier les parcours d'index ; l'augmenter donne
l'impression de parcours d'index plus coteux. Les deux valeurs peuvent tre augmentes ou diminues concomitament pour
modifier l'importance des cots d'entres/sorties disque par rapport aux cots CPU, dcrits par les paramtres qui suivent.

Astuce
Bien que le systme permette de configurer random_page_cost une valeur infrieure celle de
seq_page_cost, cela n'a aucun intrt. En revanche, les configurer des valeurs identiques prend tout son
sens si la base tient entirement dans le cache en RAM. En effet, dans ce cas, il n'est pas pnalisant d'atteindre
des pages qui ne se suivent pas. De plus, dans une base presque entirement en cache, ces valeurs peuvent tre
abaisses relativement aux paramtres CPU car le cot de rcupration d'une page dj en RAM est bien
moindre celui de sa rcupration sur disque.
cpu_tuple_cost (floating point)
Initialise l'estimation faite par le planificateur du cot de traitement de chaque ligne lors d'une requte. La valeur par dfaut
est 0.01.
cpu_index_tuple_cost (floating point)
Initialise l'estimation faite par le planificateur du cot de traitement de chaque entre de l'index lors d'un parcours d'index. La
valeur par dfaut est 0.005.
cpu_operator_cost (floating point)
Initialise l'estimation faite par le planificateur du cot de traitement de chaque oprateur ou fonction excute dans une requte. La valeur par dfaut est 0.0025.
effective_cache_size (integer)
Initialise l'estimation faite par le planificateur de la taille relle du cache disque disponible pour une requte. Ce paramtre est
li l'estimation du cot d'utilisation d'un index ; une valeur importante favorise les parcours d'index, une valeur faible les
parcours squentiels. Pour configurer ce paramtre, il est important de considrer la fois les tampons partags de PostgreSQL et la portion de cache disque du noyau utilise pour les fichiers de donnes de PostgreSQL. Il faut galement tenir
compte du nombre attendu de requtes concurrentes sur des tables diffrentes car elles partagent l'espace disponible. Ce paramtre n'a pas d'inluence sur la taille de la mmoire partage alloue par PostgreSQL, et ne rserve pas non plus le cache
disque du noyau ; il n'a qu'un rle estimatif. Le systme ne suppose pas non plus que les donnes reste dans le cache du
disque entre des requtes. La valeur par dfaut est de 128 Mo.

18.7.3. Optimiseur gntique de requtes


L'optimiseur gntique de requte (GEQO) est un algorithme qui fait la planification d'une requte en utilisant une recherche heuristique. Cela rduit le temps de planification pour les requtes complexes (celles qui joignent de nombreuses relations), au prix de
plans qui sont quelques fois infrieurs ceux trouver par un algorithme exhaustif. Pour plus d'informations, voir Chapitre 51, Optimiseur gntique de requtes (Genetic Query Optimizer).
geqo (boolean)
Active ou dsactive l'optimisation gntique des requtes. Activ par dfaut. Il est gnralement prfrable de ne pas le dsactiver sur un serveur en production. La variable geqo_threshold fournit un moyen plus granulaire de dsactiver le GEQO.
geqo_threshold (integer)
L'optimisation gntique des requtes est utilise pour planifier les requtes si, au minimum, ce nombre d'lments est impliqu dans la clause FROM (une construction FULL OUTER JOIN ne compte que pour un lment du FROM). La valeur par
dfaut est 12. Il est gnralement prfrable d'utiliser le planificateur standard, exhaustif, pour les requtes plus simples, mais
pour les requtes impliquant autant de tables, celui-ci prend trop de temps, frquemment plus longtemps que la pnalit d
l'excution d'un plan non optimal. Du coup, une limite sur la taille de la requte est un moyen simple de contrler l'utilisation
de GEQO.
geqo_effort (integer)
Contrle le compromis entre le temps de planification et l'efficacit du plan de requte dans GEQO. Cette variable est un entier entre 1 et 10. La valeur par dfaut est de cinq. Des valeurs plus importantes augmentent le temps pass la planification
de la requte mais aussi la probabilit qu'un plan de requte efficace soit choisi.
geqo_effort n'a pas d'action directe ; il est simplement utilis pour calculer les valeurs par dfaut des autres variables in341

Configuration du serveur

fluenant le comportement de GEQO (dcrites ci-dessous). Il est galement possible de les configurer manuellement.
geqo_pool_size (integer)
Contrle la taille de l'ensemble utilis par GEQO. C'est--dire le nombre d'individus au sein d'une population gntique. Elle
doit tre au minimum gale deux, les valeurs utiles tant gnralement comprises entre 100 et 1000. Si elle est configure
zro (valeur par dfaut), alors une valeur convenable est choisie en fonction de geqo_effort et du nombre de tables dans
la requte.
geqo_generations (integer)
Contrle le nombre de gnrations utilises par GEQO. C'est--dire le nombre d'itrations de l'algorithme. Il doit tre au minimum de un, les valeurs utiles se situent dans la mme plage que la taille de l'ensemble. S'il est configur zro (valeur par dfaut), alors une valeur convenable est choisie en fonction de geqo_pool_size.
geqo_selection_bias (floating point)
Contrle le biais de slection utilis par GEQO. C'est--dire la pression de slectivit au sein de la population. Les valeurs
s'tendent de 1.50 2.00 (valeur par dfaut).
geqo_seed (floating point)
Contrle la valeur initiale du gnrateur de nombres alatoires utilis par GEQO pour slectionner des chemins au hasard
dans l'espace de recherche des ordres de jointures. La valeur peut aller de zro (valeur par dfaut) un. Varier la valeur modifie l'ensemble des chemins de jointure explors et peut rsulter en des chemins meilleurs ou pires.

18.7.4. Autres options du planificateur


default_statistics_target (integer)
Initialise la cible de statistiques par dfaut pour les colonnes de table pour lesquelles aucune cible de colonne spcifique n'a
t configure via ALTER TABLE SET STATISTICS. Des valeurs leves accroissent le temps ncessaire l'excution
d'ANALYZE mais peuvent permettre d'amliorer la qualit des estimations du planificateur. La valeur par dfaut est 100.
Pour plus d'informations sur l'utilisation des statistiques par le planificateur de requtes, se rfrer la Section 14.2,
Statistiques utilises par le planificateur .
constraint_exclusion (enum)
Contrle l'utilisation par le planificateur de requte des contraintes pour optimiser les requtes. Les valeurs autorises de
constraint_exclusion sont on (examiner les contraintes pour toutes les tables), off (ne jamais examiner les
contraintes) et partition (n'examiner les contraintes que pour les tables enfants d'un hritage et pour les sous-requtes
UNION ALL). partition est la valeur par dfaut. C'est souvent utilis avec l'hritage et les tables partitionnes pour amliorer les performances.
Quand ce paramtre l'autorise pour une table particulire, le planificateur compare les conditions de la requte avec les
contraintes CHECK sur la table, et omet le parcourt des tables pour lesquelles les conditions contredisent les contraintes. Par
exemple :
CREATE
CREATE
CREATE
...
SELECT

TABLE parent(clef integer, ...);


TABLE fils1000(check (clef between 1000 and 1999)) INHERITS(parent);
TABLE fils2000(check (clef between 2000 and 2999)) INHERITS(parent);
* FROM parent WHERE clef = 2400;

Avec l'activation de l'exclusion par contraintes, ce SELECT ne parcourt pas fils1000, ce qui amliore les performances.
l'heure actuelle, l'exclusion de contraintes est active par dfaut seulement pour les cas qui sont souvent utiliss pour implmenter le partitionnement de tables. L'activer pour toutes les tables impose un surcot pour la planification qui est assez mesurable pour des requtes simples, et le plus souvent n'apportera aucun bnfice aux requtes simples. Si vous n'avez pas de
tables partitionnes, vous voudrez peut-tre le dsactiver entirement.
Reportez vous Section 5.9.4, Partitionnement et exclusion de contrainte pour plus d'informations sur l'utilisation
d'exclusion de contraintes et du partitionnement.
cursor_tuple_fraction (floating point)
Positionne la fraction, estime par le planificateur, de la fraction d'enregistrements d'un curseur qui sera rcupre. La valeur
par dfaut est 0.1. Des valeurs plus petites de ce paramtre rendent le planificateur plus enclin choisir des plans dmarrage
rapide ( fast start ), qui rcupreront les premiers enregistrement rapidement, tout en mettant peut tre un temps plus long
rcuprer tous les enregistrements. Des valeurs plus grandes mettent l'accent sur le temps total estim. la valeur maximum
1.0 du paramtre, les curseurs sont planifis exactement comme des requtes classiques, en ne prenant en compte que le
temps total estim et non la vitesse laquelle les premiers enregistrements seront fournis.
342

Configuration du serveur

from_collapse_limit (integer)
Le planificateur assemble les sous-requtes dans des requtes suprieures si la liste FROM rsultante contient au plus ce
nombre d'lments. Des valeurs faibles rduisent le temps de planification mais conduisent des plans de requtes infrieurs.
La valeur par dfaut est de 8. Pour plus d'informations, voir Section 14.3, Contrler le planificateur avec des clauses JOIN
explicites .
Configurer cette valeur geqo_threshold ou plus pourrait dclencher l'utilisation du planificateur GEQO, ce qui pourrait
aboutir la gnration de plans non optimaux. Voir Section 18.7.3, Optimiseur gntique de requtes .
join_collapse_limit (integer)
Le planificateur rcrit les constructions JOIN explicites ( l'exception de FULL JOIN) en une liste d'lments FROM
chaque fois qu'il n'en rsulte qu'une liste ne contenant pas plus de ce nombre d'lments. Des valeurs faibles rduisent le
temps de planification mais conduisent des plans de requtes infrieurs.
Par dfaut, cette variable a la mme valeur que from_collapse_limit, valeur adapte la plupart des utilisations.
Configurer cette variable 1 empche le rordonnancement des JOINtures explicites. De ce fait, l'ordre des jointures explicites indiqu dans la requte est l'ordre rel dans lequel les relations sont jointes. Le planificateur de la requte ne choisit pas
toujours l'ordre de jointure optimal ; les utilisateurs aguerris peuvent choisir d'initialiser temporairement cette variable 1 et
d'indiquer explicitement l'ordre de jointure souhait. Pour plus d'informations, voir Section 14.3, Contrler le planificateur
avec des clauses JOIN explicites .
Configurer cette valeur geqo_threshold ou plus pourrait dclencher l'utilisation du planificateur GEQO, ce qui pourrait
aboutir la gnration de plans non optimaux. Voir Section 18.7.3, Optimiseur gntique de requtes .

18.8. Remonter et tracer les erreurs


18.8.1. O tracer
log_destination (string)
PostgreSQL supporte plusieurs mthodes pour la journalisation des messages du serveur, dont stderr, csvlog et syslog. Sur Windows, eventlog est aussi support. Ce paramtre se configure avec la liste des destinations souhaites spares par des virgules. Par dfaut, les traces ne sont diriges que vers stderr. Ce paramtre ne peut tre configur que dans le
fichier postgresql.conf ou indiqu sur la ligne de commande.
Si csvlog est la valeur de log_destination, les entres du journal applicatif sont enregistres dans le format CSV
( comma separated value ), ce qui est bien pratique pour les charger dans des programmes. Voir Section 18.8.4, Utiliser
les journaux au format CSV pour les dtails. logging_collector doit tre activ pour produire des journaux applicatifs au format CSV.

Note
Sur la plupart des systmes Unix, il est ncessaire de modifier la configuration du dmon syslog pour utiliser
l'option syslog de log_destination. PostgreSQL peut tracer dans les niveaux syslog LOCAL0 LOCAL7 (voir syslog_facility) mais la configuration par dfaut de syslog sur la plupart des plateformes ignore de
tels messages. Il faut ajouter une ligne similaire :
local0.*

/var/log/postgresql

dans le fichier de configuration de syslog pour obtenir ce type de journalisation.


logging_collector (boolean)
Ce paramtre active le processus logging collector, qui est un processus en tche de fond dont le but est de capturer les traces
envoyes sur la sortie des erreurs (stderr) et de les rediriger vers des fichiers de traces. Cette approche est souvent plus
utile que la journalisation avec syslog, car certains messages peuvent ne pas apparatre dans syslog. (Un exemple typique
concerne les messages d'chec de l'diteur de liens dynamiques ; un autre exemple concerne les messages d'erreurs produits
par les scripts comme celui configur avec le paramtre archive_command.) Ce paramtre ne peut tre configur qu'au
lancement du serveur.

343

Configuration du serveur

Note
Il est possible d'envoyer les traces sur stderr sans utiliser le collecteur des traces. Les messages iront
l'endroit o la sortie des erreurs est dirige. Nanmoins, cette mthode est seulement intressante en cas d'un
faible volume de traces car elle ne propose aucun moyen simple pour raliser une rotation des journaux applicatifs. De plus, sur certaines plateformes, ne pas utiliser le collecteur de traces peut rsulter en une perte des
traces en sortie car l'criture de plusieurs processus sur le mme fichier en mme temps peut faire en sorte que
certaines critures soient perdues ou entremles.

Note
Le collecteur des traces est conu pour ne jamais perdre de messages. Cela signifie que, dans le cas d'une
charge extrmement forte, les processus serveur pourraient se trouver bloqus lors de l'envoi de messages de
trace supplmentaires. Le collecteur pourrait accumuler dans ce cas du retard. syslog prfre ignorer des messages s'il ne peut pas les crire, mais il ne bloquera pas le reste du systme.
log_directory (string)
Lorsque logging_collector est activ, ce paramtre dtermine le rpertoire dans lequel les fichiers de trace sont crs.
Il peut s'agir d'un chemin absolu ou d'un chemin relatif au rpertoire des donnes du cluster. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande. La valeur par dfaut est pg_log.
log_filename (string)
Lorsque logging_collector est activ, ce paramtre indique les noms des journaux applicatifs crs. La valeur est traite comme un motif strftime. Ainsi les chappements % peuvent tre utiliss pour indiquer des noms de fichiers horodats. (S'il y a des chappements % dpendant des fuseaux horaires, le calcul se fait dans le fuseau prcis par log_timezone.)
Les chappements % supports sont similaires ceux lists dans la spcification de strftime par l'Open Group. Notez que la
fonction strftime du systme n'est pas utilise directement, ce qui entrane que les extensions spcifiques la plateforme
(non-standard) ne fonctionneront pas. La valeur par dfaut est postgresql-%Y-%m-%d_%H%M%S.log.
Si vous spcifiez un nom de fichier sans chappements, vous devriez prvoir d'utiliser un utilitaire de rotation des journaux
pour viter le risque de remplir le disque entier. Dans les versions prcdentes 8.4, si aucun chappement % n'tait prsent,
PostgreSQL aurait ajout l'epoch de la date de cration du nouveau journal applicatif mais ce n'est plus le cas.
Si la sortie au format CSV est active dans log_destination, .csv est automatiquement ajout au nom du journal horodat. (Si log_filename se termine en .log, le suffixe est simplement remplac.)
Ce paramtre ne peut tre positionn que dans le fichier postgresql.conf ou en ligne de commande.
log_file_mode (integer)
Sur les systmes Unix, ce paramtre configure les droits pour les journaux applicatifs quand logging_collector est activ. (Sur Microsoft Windows, ce paramtre est ignor.) La valeur de ce paramtre doit tre un mode numrique spcifi dans
le format accept par les appels systmes chmod et umask. (Pour utiliser le format octal, ce nombre doit tre prcd d'un
zro, 0.)
Les droits par dfaut sont 0600, signifiant que seul l'utilisateur qui a lanc le serveur peut lire ou crire les journaux applicatifs. Un autre paramtrage habituel est 0640, permettant aux membres du groupe propritaire de lire les fichiers. Notez nanmoins que pour utiliser ce paramtre, vous devez modifier log_directory pour enregistrer les fichiers en dehors du rpertoire
des donnes de l'instance. Dans ce cas, il est dconseill de rendre les journaux applicatifs lisibles par tout le monde car ils
pourraient contenir des donnes sensibles.
Ce paramtre ne peut tre positionn que dans le fichier postgresql.conf ou en ligne de commande.
log_rotation_age (integer)
Lorsque logging_collector est activ, ce paramtre dtermine la dure de vie maximale (en minutes) d'un journal individuel. Pass ce dlai, un nouveau journal est cr. Initialiser ce paramtre zro dsactive la cration en temps compt de
nouveaux journaux. Ce paramtre ne peut qu'tre configur dans le fichier postgresql.conf ou indiqu sur la ligne de
commande.
log_rotation_size (integer)
Lorsque logging_collector est activ, ce paramtre dtermine la taille maximale (en kilooctets) d'un journal individuel. Pass cette taille, un nouveau journal est cr. Initialiser cette taille zro dsactive la cration en taille compte de nouveaux journaux. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de
commande.
344

Configuration du serveur

log_truncate_on_rotation (boolean)
Lorsque logging_collector est activ, ce paramtre impose PostgreSQL de vider (craser), plutt qu'ajouter , tout
fichier journal dont le nom existe dj. Toutefois, cet crasement ne survient qu' partir du moment o un nouveau fichier doit
tre ouvert du fait d'une rotation par temps compt, et non pas la suite du dmarrage du serveur ou d'une rotation par taille
compte. Si ce paramtre est dsactiv (off), les traces sont, dans tous les cas, ajoutes aux fichiers qui existent dj.
Par exemple, si ce paramtres est utilis en combinaison avec un log_filename tel que postgresql-%H.log, il en rsulte la gnration de 24 journaux (un par heure) crass de faon cyclique.
Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
Exemple : pour conserver sept jours de traces, un fichier par jour nomm server_log.Mon, server_log.Tue, etc. et
craser automatiquement les traces de la semaine prcdente avec celles de la semaine courante, on positionne
log_filename server_log.%a, log_truncate_on_rotation on et log_rotation_age 1440.
Exemple : pour conserver 24 heures de traces, un journal par heure, toute en effectuant la rotation plus tt si le journal dpasse 1 Go, on positionne log_filename server_log.%H%M, log_truncate_on_rotation on,
log_rotation_age 60 et log_rotation_size 1000000. Inclure %M dans log_filename permet toute rotation par taille compte qui survient d'utiliser un nom de fichier distinct du nom initial horodat.
syslog_facility (enum)
Lorsque les traces syslog sont actives, ce paramtre fixe le niveau ( facility ) utilis par syslog. Les diffrentes possibilits
sont LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7 ; LOCAL0 tant la valeur par dfaut.
Voir aussi la documentation du dmon syslog du serveur. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
syslog_ident (string)
Si syslog est activ, ce paramtre fixe le nom du programme utilis pour identifier les messages PostgreSQL dans les traces
de syslog. La valeur par dfaut est postgres. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf
ou indiqu sur la ligne de commande.
silent_mode (boolean)
Excute silencieusement le serveur. Si ce paramtre est configur, le serveur dmarre automatiquement en tche de fond et
tout terminal de contrle est dissoci. Ce paramtre ne peut tre configur qu'au dmarrage du serveur.

Attention
Quand ce paramtre est activ, la sortie standard et l'erreur standard sont rediriges vers le fichier postmaster.log dans le rpertoire des donnes. Ce fichier ne bnficie pas du systme de rotation, donc il grossira
indfiniment sauf si la sortie du serveur est renvoye ailleurs par d'autres paramtrages. Il est recommand de
configurer log_destination syslog ou que logging_collector soit activ lors de l'utilisation
de cette option. Mme avec ces mesures, les erreurs rapportes trs tt lors du dmarrage pourraient apparatre
dans le fichier postmaster.log plutt que dans la destination normal des traces.

18.8.2. Quand tracer


client_min_messages (enum)
Contrle les niveaux de message envoys au client. Les valeurs valides sont DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, LOG, NOTICE, WARNING, ERROR, FATAL, et PANIC. Chaque niveau inclut tous les niveaux qui le suivent. Plus on
progresse dans la liste, plus le nombre de messages envoys est faible. NOTICE est la valeur par dfaut. LOG a ici une porte
diffrente de celle de log_min_messages.
log_min_messages (enum)
Contrle les niveaux de message crits dans les traces du serveur. Les valeurs valides sont DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, INFO, NOTICE, WARNING, ERROR, LOG, FATAL et PANIC. Chaque niveau inclut tous les niveaux qui le
suivent. Plus on progresse dans la liste, plus le nombre de messages envoys est faible. WARNING est la valeur par dfaut.
LOG a ici une porte diffrente de celle de client_min_messages. Seuls les superutilisateurs peuvent modifier la valeur
de ce paramtre.
log_min_error_statement (enum)
Contrle si l'instruction SQL l'origine d'une erreur doit tre enregistre dans les traces du serveur. L'instruction SQL en
345

Configuration du serveur

cours est incluse dans les traces pour tout message de svrit indique ou suprieure. Les valeurs valides sont DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, INFO, NOTICE, WARNING, ERROR, LOG, FATAL et PANIC. ERROR est la valeur par
dfaut, ce qui signifie que les instructions l'origine d'erreurs, de messages applicatifs, d'erreurs fatales ou de paniques sont
traces. Pour rellement dsactiver le traage des instructions choues, ce paramtre doit tre positionn PANIC. Seuls les
superutilisateurs peuvent modifier la valeur de ce paramtre.
log_min_duration_statement (integer)
Trace la dure de toute instruction termine dont le temps d'excution gale ou dpasse ce nombre de millisecondes. Positionn zro, les dures de toutes les instructions sont traces. -1 (valeur par dfaut) dsactive ces traces.
Par exemple, si le paramtre est positionn 250ms, alors toutes les instructions SQL dont la dure est suprieure ou gale
250 ms sont traces.
Il est utile d'activer ce paramtre pour tracer les requtes non optimises des applications. Seuls les superutilisateurs peuvent
modifier cette configuration.
Pour les clients utilisant le protocole de requtage tendu, les dures des tapes Parse (analyse), Bind (lien) et Execute
(excution) sont traces indpendamment.

Note
Lorsque cette option est utilise avec log_statement, le texte des instructions traces du fait de
log_statement n'est pas rpt dans le message de trace de la dure. Si syslog n'est pas utilis, il est recommand de tracer le PID ou l'ID de session l'aide de log_line_prefix de faon pouvoir lier le message de
l'instruction au message de dure par cet identifiant.
Tableau 18.1, Niveaux de svrit des messages explique les niveaux de svrit des messages utiliss par PostgreSQL. Si
la journalisation est envoye syslog ou l'eventlog de Windows, les niveaux de svrit sont traduits comme indiqu cidessous.
Tableau 18.1. Niveaux de svrit des messages

Svrit

Usage

DEBUG1..DEBUG5

Fournit des informations suc- DEBUG


cessivement plus dtailles
destination des dveloppeurs.

INFORMATION

INFO

Fournit des informations impli- INFO


citement
demandes
par
l'utilisateur, par exemple la sortie de VACUUM VERBOSE.

INFORMATION

NOTICE

Fournit des informations ven- NOTICE


tuellement utiles aux utilisateurs, par exemple la troncature
des identifiants longs.

INFORMATION

WARNING

Fournit
des
messages NOTICE
d'avertissement sur d'ventuels
problmes. Par exemple, un
COMMIT en dehors d'un bloc
de transaction.

WARNING

ERROR

Rapporte l'erreur qui a caus WARNING


l'annulation de la commande
en cours.

ERROR

LOG

Rapporte des informations INFO


destination des administrateurs.
Par exemple, l'activit des
points de vrification.

INFORMATION

FATAL

Rapporte l'erreur qui a caus la ERR


fin de la session en cours.

ERROR

PANIC

Rapporte l'erreur qui a caus la CRIT


fin de toutes les sessions.

ERROR

syslog

346

eventlog

Configuration du serveur

18.8.3. Que tracer


application_name (string)
Le paramtre application_name peut tre tout chane de moins de NAMEDATALEN caractres (64 caractres aprs
une compilation standard). Il est typiquement configur lors de la connexion d'une application au serveur. Le nom sera affich
dans la vue pg_stat_activity et inclus dans les traces du journal au format CSV. Il peut aussi tre inclus dans les autres formats
de traces en configurant le paramtre log_line_prefix. Tout caractre ASCII affichable peut tre utilis. Les autres caractres
seront remplacs par des points d'interrogation (?).
debug_print_parse (boolean), debug_print_rewritten (boolean), debug_print_plan (boolean)
Ces paramtres activent plusieurs sorties de dbogage. Quand positionns, il affichent l'arbre d'interprtation rsultant, la sortie de la rcriture de requte, ou le plan d'excution pour chaque requte excute. Ces messages sont mis au niveau de trace
LOG , par consquent ils apparatront dans le journal applicatif du serveur, mais ne seront pas envoys au client. Vous pouvez
changer cela en ajustant client_min_messages et/ou log_min_messages. Ces paramtres sont dsactivs par dfaut.
debug_pretty_print (boolean)
Quand positionn, debug_pretty_print indente les messages produits par debug_print_parse, debug_print_rewritten, ou debug_print_plan. Le rsultat est une sortie plus lisible mais plus verbeuse que le format compact utilis quand ce paramtre est off. La valeur par dfaut est 'on'.
log_checkpoints (boolean)
Trace les points de vrification and restartpoints dans les journaux applicatifs. Diverses statistiques sont incluses dans les
journaux applicatifs, dont le nombre de tampons crits et le temps pass les crire. Dsactiv par dfaut, ce paramtre ne
peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
log_connections (boolean)
Trace chaque tentative de connexion sur le serveur, ainsi que la russite de l'authentification du client. Dsactiv par dfaut,
ce paramtre ne peut pas tre dsactiv aprs le dmarrage de la session.

Note
Quelques programmes clients, comme psql, tentent de se connecter deux fois pour dterminer si un mot de
passe est ncessaire, des messages connection received dupliqus n'indiquent donc pas forcment un problme.
log_disconnections (boolean)
Affiche dans les traces du serveur une ligne similaire log_connections mais la fin d'une session, en incluant la dure
de la session. Dsactiv par dfaut, ce paramtre ne peut pas tre dsactiv aprs le dmarrage de la session.
log_duration (boolean)
Trace la dure de toute instruction excute. Dsactiv par dfaut (off), seuls les superutilisateurs peuvent modifier ce paramtre.
Pour les clients utilisant le protocole de requtage tendu, les dures des tapes Parse (analyse), Bind (lien) et Execute
(excution) sont traces indpendamment.

Note
la diffrence de log_min_duration_statement, ce paramtre ne force pas le traage du texte des requtes. De
ce fait, si log_duration est activ (on) et que log_min_duration_statement a une valeur positive,
toutes les dures sont traces mais le texte de la requte n'est inclus que pour les instructions qui dpassent la
limite. Ce comportement peut tre utile pour rcuprer des statistiques sur les installations forte charge.
log_error_verbosity (enum)
Contrle la quantit de dtails crit dans les traces pour chaque message trac. Les valeurs valides sont TERSE, DEFAULT et
VERBOSE, chacun ajoutant plus de champs aux messages affichs. TERSE exclut des traces les informations de niveau DETAIL, HINT, QUERY et CONTEXT. La sortie VERBOSE inclut le code d'erreur SQLSTATE (voir aussi Annexe A, Codes
d'erreurs de PostgreSQL), le nom du code source, le nom de la fonction et le numro de la ligne qui a gnr l'erreur. Seuls
les superutilisateurs peuvent modifier ce paramtre.
log_hostname (boolean)
Par dfaut, les traces de connexion n'affichent que l'adresse IP de l'hte se connectant. Activer ce paramtre permet de tracer
347

Configuration du serveur

aussi le nom de l'hte. En fonction de la configuration de la rsolution de nom d'hte, les performances peuvent tre pnalises. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
log_line_prefix (string)
Il s'agit d'une chane de style printf affiche au dbut de chaque ligne de trace. Les caractres % dbutent des squences
d'chappement qui sont remplaces avec l'information de statut dcrite ci-dessous. Les chappement non reconnus sont
ignors. Les autres caractres sont copis directement dans la trace. Certains chappements ne sont reconnus que par les processus de session et ne s'appliquent pas aux processus en tche de fond comme le processus serveur principal. Ce paramtre
ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande. La valeur par dfaut est
une chane vide.
chappement

Produit

Session seule

%a

Nom de l'application

yes

%u

Nom de l'utilisateur

oui

%d

Nom de la base de donnes

oui

%r

Nom ou adresse IP de l'hte distant et port distant

oui

%h

Nom d'hte distant ou adresse IP

yes

%p

ID du processus

non

%t

Estampille temporelle sans millisecondes

non

%m

Estampille temporelle avec millisecondes

non

%i

Balise de commande : type de commande

oui

%e

code d'erreur correspondant l'tat SQL

no

%c

ID de session : voir ci-dessous

non

%l

Numro de la ligne de trace de chaque session ou processus, commenant 1

non

%s

Estampille temporelle du lancement du processus

oui

%v

Identifiant virtuel de transaction (backendID/localXID)

no

%x

ID de la transaction (0 si aucune affecte)

non

%q

Ne produit aucune sortie, mais indique aux autres processus de stopper cet endroit non
de la chane. Ignor par les processus de session.

%%

non

L'chappement %c affiche un identifiant de session quasi-unique constitu de deux nombres hexadcimaux sur quatre octets
(sans les zros initiaux) et spars par un point. Les nombres reprsentent l'heure de lancement du processus et l'identifiant du
processus, %c peut donc aussi tre utilis comme une manire de raccourcir l'affichage de ces lments. Par exemple, pour
gnrer l'identifiant de session partir de pg_stat_activity, utilisez cette requte :
SELECT to_hex(EXTRACT(EPOCH FROM backend_start)::integer) || '.' ||
to_hex(procpid)
FROM pg_stat_activity;

Astuce
Si log_line_prefix est diffrent d'une chane vide, il est intressant d'ajouter une espace en fin de chane
pour crer une sparation visuelle avec le reste de la ligne. Un caractre de ponctuation peut aussi tre utilis.

Astuce
syslog produit ses propres informations d'horodatage et d'identifiant du processus. Ces chappements n'ont
donc que peu d'intrt avec syslog.
log_lock_waits (boolean)
Contrle si une trace applicative est crite quand une session attend plus longtemps que deadlock_timeout pour acqurir un
verrou. Ceci est utile pour dterminer si les attentes de verrous sont la cause des pertes de performance. Dsactiv (off) par
348

Configuration du serveur

dfaut.
log_statement (enum)
Contrle les instructions SQL tracer. Les valeurs valides sont none (off), ddl, mod et all (toutes les instructions). ddl
trace toutes les commandes de dfinition comme CREATE, ALTER et DROP. mod trace toutes les instructions ddl ainsi
que les instructions de modification de donnes INSERT, UPDATE, DELETE, TRUNCATE et COPY FROM. Les instructions PREPARE, EXECUTE et EXPLAIN ANALYZE sont aussi traces si la commande qui les contient est d'un type
appropri. Pour les clients utilisant le protocole de requtage tendu, la trace survient quand un message Execute est reu et
les valeurs des paramtres de Bind sont incluses (avec doublement de tout guillemet simple embarqu).
La valeur par dfaut est none. Seuls les superutilisateurs peuvent changer ce paramtrage.

Note
Les instructions qui contiennent de simples erreurs de syntaxe ne sont pas traces mme si log_statement
est positionn all car la trace n'est mise qu'aprs qu'une analyse basique soit ralise pour dterminer le
type d'instruction. Dans le cas du protocole de requtage tendu, ce paramtre ne trace pas les instructions qui
chouent avant la phase Execute (c'est--dire pendant l'analyse et la planification).
log_min_error_statement doit tre positionn ERROR pour tracer ce type d'instructions.
log_temp_files (integer)
Contrle l'criture de traces sur l'utilisation des fichiers temporaires (noms et tailles). Les fichiers temporaires peuvent tre
crs pour des tris, des hachages et des rsultats temporaires de requte. Une entre de journal est gnre pour chaque fichier
temporaire au moment ou il est effac. Zro implique une trace des informations sur tous les fichiers temporaires alors qu'une
valeur positive ne trace que les fichiers dont la taille est suprieure ou gale au nombre indiqu (en kilo-octets). La valeur par
dfaut est -1, ce qui a pour effet de dsactiver les traces. Seuls les superutilisateurs peuvent modifier ce paramtre.
log_timezone (string)
Configure le fuseau horaire utilis par l'horodatage des traces. Contrairement timezone, cette valeur est valable pour le cluster complet, de faon ce que toutes les sessions utilisent le mme. Si ce paramtre n'est pas explicitement configur, le serveur initialise cette variable avec le fuseau horaire indiqu par l'environnement systme. Voir Section 8.5.3, Fuseaux horaires pour plus d'informations. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu
sur la ligne de commande.

18.8.4. Utiliser les journaux au format CSV


L'ajout de csvlog dans la liste log_destination est une manire simple d'importer des journaux dans une table de base de
donnes. Cette option permet de crer des journaux au format CSV avec les colonnes : l'horodatage en millisecondes, le nom de
l'utilisateur, le nom de la base de donnes, le PID du processus serveur, l'hte et le numro de port du client, l'identifiant de la session, le numro de ligne dans la session, le tag de la commande, l'horodatage de dbut de la session, l'identifiant de transaction virtuelle, l'identifiant de transaction standard, la svrit de l'erreur, le code SQLSTATE, le message d'erreur, les dtails du message
d'erreur, une astuce, la requte interne qui a amen l'erreur (si elle existe), le nombre de caractres pour arriver la position de
l'erreur, le contexte de l'erreur, la requte utilisateur qui a amen l'erreur (si elle existe et si log_min_error_statement est
activ), le nombre de caractres pour arriver la position de l'erreur, l'emplacement de l'erreur dans le code source de PostgreSQL
(si log_error_verbosity est configur verbose) et le nom de l'application.
Exemple de dfinition d'une table de stockage de journaux au format CSV :
CREATE TABLE postgres_log
(
log_time timestamp(3) with time zone,
user_name text,
database_name text,
process_id integer,
connection_from text,
session_id text,
session_line_num bigint,
command_tag text,
session_start_time timestamp with time zone,
virtual_transaction_id text,
transaction_id bigint,
error_severity text,
sql_state_code text,
349

Configuration du serveur

message text,
detail text,
hint text,
internal_query text,
internal_query_pos integer,
context text,
query text,
query_pos integer,
location text,
application_name text,
PRIMARY KEY (session_id, session_line_num)
);
Pour importer un journal dans cette table, on utilise la commande COPY FROM :
COPY postgres_log FROM '/chemin/complet/vers/le/logfile.csv' WITH csv;
Quelques conseils pour simplifier et automatiser l'import des journaux CVS :
1. configurer log_filename et log_rotation_age pour fournir un schma de nommage cohrent et prvisible des journaux. Cela permet de prdire le nom du fichier et le moment o il sera complet (et donc prt tre import) ;
2. initialiser log_rotation_size 0 pour dsactiver la rotation par taille compte, car elle rend plus difficile la prvision du
nom du journal ;
3. positionner log_truncate_on_rotation on pour que les donnes anciennes ne soient pas mlanges aux nouvelles
dans le mme fichier ;
4. la dfinition de la table ci-dessus inclut une cl primaire. C'est utile pour se protger de l'import accidentel de la mme information plusieurs reprises. La commande COPY valide toutes les donnes qu'elle importe en une fois. Toute erreur annule donc
l'import complet. Si un journal incomplet est import et qu'il est de nouveau import lorsque le fichier est complet, la violation
de la cl primaire cause un chec de l'import. Il faut attendre que le journal soit complet et ferm avant de l'importer. Cette procdure protge aussi de l'import accidentel d'une ligne partiellement crite, qui causerait aussi un chec de COPY.

18.9. Statistiques d'excution


18.9.1. Collecteur de statistiques sur les requtes et les index
Ces paramtres contrlent la collecte de statistiques de niveau serveur. Lorsque celle-ci est active, les donnes produites peuvent
tre visualises travers la famille de vues systmes pg_stat et pg_statio. On peut se reporter Chapitre 27, Surveiller l'activit de
la base de donnes pour plus d'informations.
track_activities (boolean)
Active la collecte d'informations sur la commande en cours d'excution dans chaque session, avec l'heure de dmarrage de la
commande. Ce paramtre est activ par dfaut. Mme si le paramtre est activ, cette information n'est pas visible par tous les
utilisateurs, mais uniquement par les superutilisateurs et l'utilisateur possdant la session traite ; de ce fait, cela ne reprsente
pas une faille de scurit. Seuls les superutilisateurs peuvent modifier ce paramtre.
track_activity_query_size (integer)
Spcifie le nombre d'octets rservs pour suivre la commande en cours d'excution pour chaque session active, pour le champ
pg_stat_activity.current_query. La valeur par dfaut est 1024. Ce paramtre ne peut tre positionn qu'au dmarrage du
serveur.
track_counts (boolean)
Active la rcupration de statistiques sur l'activit de la base de donnes. Ce paramtre est activ par dfaut car le processus
autovacuum utilise les informations ainsi rcupres. Seuls les super-utilisateurs peuvent modifier ce paramtre.
track_functions (enum)
Active le suivi du nombre et de la dure des appels aux fonctions. Prcisez pl pour ne tracer que les fonctions de langages
procduraux, ou all pour suivre aussi les fonctions SQL et C. La valeur par dfaut est none, qui dsactive le suivi des statistiques de fonctions. Seuls les superutilisateurs peuvent modifier ce paramtre.

350

Configuration du serveur

Note
Les fonctions en langage SQL qui sont assez simples pour tre inlined , c'est dire substitues dans le code
de la requte appelante, ne seront pas suivies, quelle que soit la valeur de ce paramtre.
update_process_title (boolean)
Active la mise jour du titre du processus chaque fois qu'une nouvelle commande SQL est reue par le serveur. Le titre du
processus est visible typiquement avec la commande ps sur Unix ou en utilisant l'explorateur de processus sur Windows.
Seuls les superutilisateurs peuvent modifier ce paramtre.
stats_temp_directory (string)
Prcise le rpertoire dans lequel stocker les donnes temporaires de statistiques. Cela peut tre un chemin relatif au rpertoire
de donnes ou un chemin absolu. La valeur par dfaut est pg_stat_tmp. Faire pointer ceci vers un systme de fichiers mmoire diminuera les entres/sorties physiques et peut amliorer les performances. Ce paramtre ne peut tre positionn que
dans le fichier postgresql.conf ou sur la ligne de commande.

18.9.2. Surveillance et statistiques


log_statement_stats
(boolean),
log_executor_stats (boolean)

log_parser_stats

(boolean),

log_planner_stats

(boolean),

crivent, pour chaque requte, les statistiques de performance du module respectif dans les traces du serveur. C'est un outil de
profilage trs simpliste, similaire aux possibilits de l'appel getrusage() du systme d'exploitation Unix.
log_statement_stats rapporte les statistiques d'instructions globales, tandis que les autres fournissent un rapport par
module. log_statement_stats ne peut pas tre activ conjointement une option de module. Par dfaut, toutes ces options sont dsactives. Seuls les superutilisateurs peuvent modifier ces paramtres.

18.10. Nettoyage (vacuum) automatique


Ces paramtres contrlent le comportement de la fonctionnalit appele autovacuum. Se rfrer la Section 23.1.5, Le dmon
auto-vacuum pour plus de dtails.
autovacuum (boolean)
Contrle si le serveur doit dmarrer le dmon d'autovacuum. Celui-ci est activ par dfaut. track_counts doit aussi tre activ
pour que ce dmon soit dmarr. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur
la ligne de commande.
Mme si ce paramtre est dsactiv, le systme lance les processus autovacuum ncessaires pour empcher le bouclage des
identifiants de transaction. Voir Section 23.1.4, viter les cycles des identifiants de transactions pour plus d'informations.
log_autovacuum_min_duration (integer)
Trace chaque action ralise par l'autovacuum si elle dure chacune plus de ce nombre de millisecondes. Le configurer zro
trace toutes les actions de l'autovacuum. La valeur par dfaut, -1, dsactive les traces des actions de l'autovacuum.
Par exemple, s'il est configur 250ms, toutes les oprations VACUUM et ANALYZE qui durent plus de 250 ms sont traces. De plus, quand ce paramtre est configure une valeur autre que -1, un message sera trac si l'action de l'autovacuum
est abandonne cause de l'existence d'un verrou en conflit. Activer ce paramtre peut tre utile pour tracer l'activit de
l'autovacuum. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
autovacuum_max_workers (integer)
Indique le nombre maximum de processus autovacuum (autre que le lanceur d'autovacuum) qui peuvent tre excuts simultanment. La valeur par dfaut est 3. Ce paramtre ne peut tre configur qu'au lancement du serveur.
autovacuum_naptime (integer)
Indique le dlai minimum entre les tours d'activit du dmon autovacuum sur une base. chaque tour, le dmon examine une
base de donnes et lance les commandes VACUUM et ANALYZE ncessaires aux tables de cette base. Le dlai, mesur en
secondes, vaut, par dfaut, une minute (1min). Ce paramtre ne peut tre configur que dans le fichier postgresql.conf
ou indiqu sur la ligne de commande.
autovacuum_vacuum_threshold (integer)
351

Configuration du serveur

Indique le nombre minimum de lignes mises jour ou supprimes ncessaire pour dclencher un VACUUM sur une table. La
valeur par dfaut est de 50 lignes. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu
sur la ligne de commande. Il est possible de surcharger ce paramtre pour toute table en modifiant les paramtres de stockage.
autovacuum_analyze_threshold (integer)
Indique le nombre minimum de lignes insres, mises jour ou supprimes ncessaire pour dclencher un ANALYZE sur
une table. La valeur par dfaut est de 50 lignes. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf
ou indiqu sur la ligne de commande. Il est possible de surcharger ce paramtre pour toute table en modifiant les paramtres
de stockage.
autovacuum_vacuum_scale_factor (floating point)
Indique la fraction de taille de la table ajouter autovacuum_vacuum_threshold pour dcider du moment auquel dclencher un VACUUM. La valeur par dfaut est 0.2 (20 % de la taille de la table). Ce paramtre ne peut tre configur que
dans le fichier postgresql.conf ou indiqu sur la ligne de commande. Il est possible de surcharger ce paramtre pour
toute table en modifiant les paramtres de stockage.
autovacuum_analyze_scale_factor (floating point)
Indique la fraction de taille de la table ajouter autovacuum_analyze_threshold pour dcider du moment auquel
dclencher une commande ANALYZE. La valeur par dfaut est 0.1 (10 % de la taille de la table). Ce paramtre ne peut tre
configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande. Il est possible de surcharger ce paramtre pour toute table en modifiant les paramtres de stockage.
autovacuum_freeze_max_age (integer)
Indique l'ge maximum (en transactions) que le champ pg_class.relfrozenxid d'une table peut atteindre avant qu'une
opration VACUUM ne soit force pour empcher la rinitialisation de l'ID de transaction sur cette table. Le systme lance
les processus autovacuum pour viter ce bouclage mme si l'autovacuum est dsactiv.
L'opration VACUUM supprime aussi les anciens fichiers du sous-rpertoire pg_clog, ce qui explique pourquoi la valeur
par dfaut est relativement basse (200 millions de transactions). Ce paramtre n'est lu qu'au dmarrage du serveur, mais il
peut tre diminu pour toute table en modifiant les paramtres de stockage. Pour plus d'informations, voir Section 23.1.4,
viter les cycles des identifiants de transactions .
autovacuum_vacuum_cost_delay (integer)
Indique la valeur du cot de dlai utilise dans les oprations de VACUUM. Si -1 est indiqu, la valeur habituelle de vacuum_cost_delay est utilise. La valeur par dfaut est 20 millisecondes. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande. Il est possible de le surcharger pour toute table en modifiant les paramtres de stockage.
autovacuum_vacuum_cost_limit (integer)
Indique la valeur de cot limite utilise dans les oprations de VACUUM automatiques. Si -1 est indiqu (valeur par dfaut),
la valeur courante de vacuum_cost_limit est utilise. La valeur est distribue proportionnellement entre les processus autovacuum en cours d'excution, s'il y en a plus d'un, de sorte que la somme des limites de chaque processus ne dpasse jamis la limite de cette variable. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne
de commande. Il est possible de le surcharger pour toute tableen modifiant les paramtres de stockage.

18.11. Valeurs par dfaut des connexions client


18.11.1. Comportement des instructions
search_path (string)
Cette variable prcise l'ordre dans lequel les schmas sont parcourus lorsqu'un objet (table, type de donnes, fonction, etc.) est
rfrenc par un simple nom sans prcision du schma. Lorsque des objets de noms identiques existent dans plusieurs schmas, c'est le premier trouv dans le chemin de recherche qui est utilis. Il ne peut tre fait rfrence un objet qui ne fait partie d'aucun des schmas indiqus dans le chemin de recherche qu'en prcisant son schma conteneur avec un nom qualifi
(avec un point).
search_path doit contenir une liste de noms de schmas spars par des virgules. Si un des lments de la liste est la valeur spciale $user, alors le schma dont le nom correspond la valeur retourne par SESSION_USER est substitu, s'il
existe (sinon $user est ignor).
Le schma du catalogue systme, pg_catalog, est toujours parcouru, qu'il soit ou non mentionn dans le chemin. Mention352

Configuration du serveur

n, il est alors parcouru dans l'ordre indiqu. Dans le cas contraire, il est parcouru avant tout autre lment du chemin.
De mme, le schma des tables temporaires, pg_temp_nnn, s'il existe, est toujours parcouru. Il peut tre explicitement ajout au chemin l'aide de l'alias pg_temp. S'il n'en fait pas partie, la recherche commence par lui (avant mme
pg_catalog). Nanmoins, seuls les noms de relation (table, vue, squence, etc.) et de type de donnes sont recherchs dans
le schma temporaire. Aucune fonction et aucun oprateur n'y est jamais recherch.
Lorsque des objets sont crs sans prcision de schma cible particulier, ils sont placs dans le premier schma list dans le
chemin de recherche. Une erreur est rapporte si le chemin de recherche est vide.
La valeur par dfaut de ce paramtre est '"$user", public' (la deuxime partie est ignore s'il n'existe pas de schma
nomm public). Elle permet l'utilisation partage d'une base de donnes (dans laquelle aucun utilisateur n'a de schma priv et tous partagent l'utilisation de public), les schmas privs d'utilisateur ainsi qu'une combinaison de ces deux modes.
D'autres effets peuvent tre obtenus en modifiant le chemin de recherche par dfaut, globalement ou par utilisateur.
La valeur courante relle du chemin de recherche peut tre examine via la fonction SQL current_schemas() (voir Section 9.23, Fonctions d'informations systme ). Elle n'est pas identique la valeur de search_path car current_schemas affiche la faon dont les requtes apparaissant dans search_path sont rsolues.
Pour plus d'informations sur la gestion des schmas, voir la Section 5.7, Schmas .
default_tablespace (string)
Cette variable indique le tablespace par dfaut dans lequel sont crs les objets (tables et index) quand une commande
CREATE ne l'explicite pas.
La valeur est soit le nom d'un tablespace soit une chane vide pour indiquer l'utilisation du tablespace par dfaut de la base de
donnes courante. Si la valeur ne correspond pas au nom d'un tablespace existant, PostgreSQL utilise automatiquement le
tablespace par dfaut de la base de donnes courante. Si un tablespace diffrent de celui par dfaut est indiqu, l'utilisateur
doit avoir le droit CREATE. Dans le cas contraire, la tentative de cration chouera.
Cette variable n'est pas utilise pour les tables temporaires ; pour elles, temp_tablespaces est consult la place.
Cette variable n'est pas utilise non plus lors de la cration de bases de donnes. Par dfaut, une nouvelle base de donnes hrite sa configuration de tablespace de la base de donnes modle qui sert de copie.
Pour plus d'informations sur les tablespaces, voir Section 21.6, Tablespaces .
temp_tablespaces (string)
Cette variable indique le (ou les) tablespace(s) dans le(s)quel(s) crer les objets temporaires (tables temporaires et index sur
des tables temporaires) quand une commande CREATE n'en explicite pas. Les fichiers temporaires crs par les tris de gros
ensembles de donnes sont aussi crs dans ce tablespace.
Cette valeur est une liste de noms de tablespaces. Quand cette liste contient plus d'un nom, PostgreSQL choisit un membre
de la liste au hasard chaque fois qu'un objet temporaire doit tre cr. En revanche, dans une transaction, les objets temporaires crs successivement sont placs dans les tablespaces successifs de la liste. Si l'lment slectionn de la liste est une
chane vide, PostgreSQL utilise automatiquement le tablespace par dfaut de la base en cours.
Si temp_tablespaces est configur interactivement, l'indication d'un tablespace inexistant est une erreur. Il en est de
mme si l'utilisateur n'a pas le droit CREATE sur le tablespace indiqu. Nanmoins, lors de l'utilisation d'une valeur prcdemment configure, les tablespaces qui n'existent pas sont ignors comme le sont les tablespaces pour lesquels l'utilisateur
n'a pas le droit CREATE. Cette rgle s'applique, en particulier, lors de l'utilisation d'une valeur configure dans le fichier
postgresql.conf.
La valeur par dfaut est une chane vide. De ce fait, tous les objets temporaires sont crs dans le tablespace par dfaut de la
base de donnes courante.
Voir aussi default_tablespace.
check_function_bodies (boolean)
Ce paramtre est habituellement positionn on. Positionn off, il dsactive la validation du corps de la fonction lors de
CREATE FUNCTION(7). Dsactiver la validation vite les effets de bord du processus de validation et vite les faux positifs
ds aux problmes, par exemple les rfrences. Configurer ce paramtre off avant de charger les fonctions la place des
autres utilisateurs ; pg_dump le fait automatiquement.
default_transaction_isolation (enum)
Chaque transaction SQL a un niveau d'isolation. Celui-ci peut tre read uncommitted , read committed , repeatable
read ou serializable . Ce paramtre contrle le niveau d'isolation par dfaut de chaque nouvelle transaction. La valeur par
dfaut est read committed .
353

Configuration du serveur

Consulter le Chapitre 13, Contrle d'accs simultan et SET TRANSACTION(7) pour plus d'informations.
default_transaction_read_only (boolean)
Une transaction SQL en lecture seule ne peut pas modifier les tables permanentes. Ce paramtre contrle le statut de lecture
seule par dfaut de chaque nouvelle transaction. La valeur par dfaut est off (lecture/criture).
Consulter SET TRANSACTION(7) pour plus d'informations.
default_transaction_deferrable (boolean)
Lors du fonctionnement avec le niveau d'isolation serializable, une transaction SQL en lecture seule et diffrable peut
subir un certain dlai avant d'tre autorise continuer. Nanmoins, une fois qu'elle a commenc son excution, elle n'encourt
aucun des frais habituels ncessaires pour assurer sa sriabilit. Donc le code de srialisation n'a aucune raison de forcer son
annulation cause de mises jour concurrentes, ce qui rend cette option trs intressante pour les longues transactions en lecture seule.
Ce paramtre contrle le statut diffrable par dfaut de chaque nouvelle transaction. Il n'a actuellement aucun effet sur les
transactions en lecture/criture ou celles oprant des niveaux d'isolation infrieurs serializable. La valeur par dfaut
est off.
Consultez SET TRANSACTION(7) pour plus d'informations.
session_replication_role (enum)
Contrle l'excution des triggers et rgles relatifs la rplication pour la session en cours. Seul un superutilisateur peut configurer cette variable. Sa modification rsulte en l'annulation de tout plan de requte prcdemment mis en cache. Les valeurs
possibles sont origin (la valeur par dfaut), replica et local. Voir ALTER TABLE(7) pour plus d'informations.
statement_timeout (integer)
Interrompt toute instruction qui dure plus longtemps que ce nombre (indiqu en millisecondes). Le temps est dcompt partir du moment o la commande en provenance du client arrive sur le serveur. Si log_min_error_statement est configur ERROR, ou plus bas, l'instruction en cause est trace. La valeur zro (par dfaut) dsactive le dcompte.
Il n'est pas recommand de configurer statement_timeout dans postgresql.conf car cela affecte toutes les sessions.
vacuum_freeze_table_age (integer)
VACUUM effectuera un parcours complet de la table si le champ pg_class.relfrozenxid de la table a atteint l'ge spcifi par ce paramtre. La valeur par dfaut est 150 millions de transactions. Mme si les utilisateurs peuvent positionner cette
valeur n'importe quelle valeur comprise entre zro et 1 milliard, VACUUM limitera silencieusement la valeur effective
95% de autovacuum_freeze_max_age, afin qu'un vacuum priodique manuel ait une chance de s'excuter avant un autovacuum anti-bouclage ne soit lanc pour la table. Pour plus d'informations voyez Section 23.1.4, viter les cycles des identifiants de transactions .
vacuum_freeze_min_age (integer)
Indique l'ge limite (en transactions) que VACUUM doit utiliser pour dcider de remplacer les ID de transaction par FrozenXID lors du parcours d'une table. La valeur par dfaut est 50 millions. Bien que les utilisateurs puissent configurer une
valeur quelconque comprise entre zro et 1 milliard, VACUUM limite silencieusement la valeur relle la moiti de la valeur
de autovacuum_freeze_max_age afin que la valeur entre deux autovacuums forcs ne soit pas draisonnablement courte. Pour
plus d'informations, voir Section 23.1.4, viter les cycles des identifiants de transactions .
bytea_output (enum)
Configure le format de sortie pour les valeurs de type bytea. Les valeurs valides sont hex (la valeur par dfaut) et escape
(le format traditionnel de PostgreSQL). Voir Section 8.4, Types de donnes binaires pour plus d'informations. Le type bytea accepte toujours les deux formats en entre, quelque soit la valeur de cette configuration.
xmlbinary (enum)
Dfinit la manire de coder les valeurs binaires en XML. Ceci s'applique, par exemple, quand les valeurs bytea sont converties en XML par les fonctions xmlelement et xmlforest. Les valeurs possibles sont base64 et hex, qui sont toutes les
deux dfinies dans le standard XML Schema. La valeur par dfaut est base64. Pour plus d'informations sur les fonctions relatives XML, voir Section 9.14, Fonctions XML .
Le choix effectif de cette valeur est une affaire de sensibilit, la seule restriction provenant des applications clientes. Les deux
mthodes supportent toutes les valeurs possibles, et ce bien que le codage hexadcimal soit un peu plus grand que le codage
en base64.
xmloption (enum)

354

Configuration du serveur

Dfinit si DOCUMENT ou CONTENT est implicite lors de la conversion entre XML et valeurs chanes de caractres. Voir Section 8.13, Type XML pour la description. Les valeurs valides sont DOCUMENT et CONTENT. La valeur par dfaut est
CONTENT.
D'aprs le standard SQL, la commande pour configurer cette option est :
SET XML OPTION { DOCUMENT | CONTENT };
Cette syntaxe est aussi disponible dans PostgreSQL.

18.11.2. Locale et formatage


datestyle (string)
Configure le format d'affichage des valeurs de type date et heure, ainsi que les rgles d'interprtation des valeurs ambigus de
dates saisies. Pour des raisons historiques, cette variable contient deux composantes indpendantes : la spcification du format
en sortie (ISO, Postgres, SQL ou German) et la spcification en entre/sortie de l'ordre anne/mois/jour (DMY, MDY ou
YMD). Elles peuvent tre configures sparment ou ensemble. Les mots cls Euro et European sont des synonymes de
DMY ; les mots cls US, NonEuro et NonEuropean sont des synonymes de MDY. Voir la Section 8.5, Types date/heure
pour plus d'informations. La valeur par dfaut est ISO, MDY, mais initdb initialise le fichier de configuration avec une valeur qui correspond au comportement de la locale lc_time choisie.
IntervalStyle (enum)
Positionne le format d'affichage pour les valeurs de type intervalle. La valeur sql_standard produira une sortie correspondant aux litraux d'intervalles du standard SQL. La valeur postgres (qui est la valeur par dfaut) produira une sortie
correspondant celle des versions de PostgreSQL antrieures la 8.4 quand le paramtre datestyle tait positionn ISO.
La valeur postgres_verbose produira une sortie correspondant celle des versions de PostgreSQL antrieures la 8.4
quand le paramtre DateStyle tait positionn une valeur autre que ISO La valeur iso_8601 produira une sortie correspondant au format avec designateurs d'intervalle de temps dfini dans le paragraphe 4.4.3.2 de l'ISO 8601.
Le paramtre IntervalStyle affecte aussi l'interprtation des entres ambiges d'intervalles. Voir Section 8.5.4, Saisie
d'intervalle pour plus d'informations.
timezone (string)
Configure le fuseau horaire pour l'affichage et l'interprtation de la date et de l'heure. Si ce paramtre n'est pas configur explicitement, le serveur l'initialise avec le fuseau horaire indiqu par l'environnement systme. Voir la Section 8.5.3, Fuseaux
horaires pour plus d'informations.
timezone_abbreviations (string)
Configure la liste des abrviations de fuseaux horaires accepts par le serveur pour la saisie de donnes de type datetime. La
valeur par dfaut est 'Default', qui est une liste qui fonctionne presque dans le monde entier ; il y a aussi 'Australia'
et 'India'. D'autres listes peuvent tre dfinies pour une installation particulire. Voir Annexe B, Support de date/heure
pour plus d'informations.
extra_float_digits (integer)
Ce paramtre ajuste le nombre de chiffres affichs par les valeurs virgule flottante, ce qui inclut float4, float8 et les types de
donnes gomtriques. La valeur du paramtre est ajoute au nombre standard de chiffres (FLT_DIG ou DBL_DIG). La valeur peut tre initialise une valeur maximale de 3 pour inclure les chiffres partiellement significatifs ; c'est tout spcialement utile pour sauvegarder les donnes virgule flottante qui ont besoin d'tre restaures exactement. Cette variable peut
aussi tre ngative pour supprimer les chiffres non souhaits. Voir aussi Section 8.1.3, Types virgule flottante .
client_encoding (string)
Initialise l'encodage client (jeu de caractres). Par dfaut, il s'agit de celui de la base de donnes. Les ensembles de caractres
supports par PostgreSQL sont dcrits dans Section 22.3.1, Jeux de caractres supports .
lc_messages (string)
Initialise la langue d'affichage des messages. Les valeurs acceptables dpendent du systme ; voir Section 22.1, Support des
locales pour plus d'informations. Si cette variable est initialise une chane vide (valeur par dfaut), alors la valeur est hrite de l'environnement d'excution du serveur.
Avec certains systmes, cette catgorie de locale n'existe pas. Initialiser cette variable fonctionne toujours mais n'a aucun effet. De mme, il est possible qu'il n'existe pas de traduction des messages dans la langue slectionne. Dans ce cas, les messages sont affichs en anglais.
355

Configuration du serveur

Seuls les superutilisateurs peuvent modifier ce paramtre car il affecte aussi bien les messages envoys dans les traces du serveur que ceux envoys au client.
lc_monetary (string)
Initialise la locale utiliser pour le formatage des montants montaires (pour la famille de fonctions to_char, par exemple).
Les valeurs acceptables dpendent du systme ; voir la Section 22.1, Support des locales pour plus d'informations. Si cette
variable est initialise une chane vide (valeur par dfaut), alors la valeur est hrite de l'environnement d'excution du serveur, et une valeur incorrecte pourrait dgrader la lisibilit des traces du serveur.
lc_numeric (string)
Initialise la locale utiliser pour le formatage des nombres (pour la famille de fonctions to_char, par exemple). Les valeurs
acceptables dpendent du systme ; voir la Section 22.1, Support des locales pour plus d'informations. Si cette variable est
initialise une chane vide (valeur par dfaut), alors la valeur est hrite de l'environnement d'excution du serveur.
lc_time (string)
Initialise la locale utiliser pour le formatage des valeurs de date et d'heure, par exemple avec la famille de fonctions
to_char. Les valeurs acceptables dpendent du systme ; voir la Section 22.1, Support des locales pour plus
d'informations. Si cette variable est initialise une chane vide (valeur par dfaut), alors la valeur est hrite de
l'environnement d'excution du serveur.
default_text_search_config (string)
Slectionne la configuration de recherche plein texte utilise par les variantes des fonctions de recherche plein texte qui n'ont
pas d'argument explicite pour prciser la configuration. Voir Chapitre 12, Recherche plein texte pour plus d'informations. La
valeur par dfaut est pg_catalog.simple mais initdb initialise le fichier de configuration avec une valeur qui correspond
la locale choisie pour lc_ctype s'il est possible d'identifier une configuration correspondant la locale.

18.11.3. Autres valeurs par dfaut


dynamic_library_path (string)
Chemin de recherche utilis lorsqu'un module chargeable dynamiquement doit tre ouvert et que le nom de fichier indiqu
dans la commande CREATE FUNCTION ou LOAD ne contient pas d'indication de rpertoire (c'est--dire que le nom ne
contient pas de slash).
La valeur de dynamic_library_path doit tre une liste de chemins absolus spars par des virgules (ou des points virgules sous Windows). Si un lment de la liste dbute par la chane spciale $libdir, le rpertoire des bibliothques internes du paquetage PostgreSQL est substitu $libdir. C'est l'emplacement o sont installs les modules fournis par la
distribution PostgreSQL standard. (La commande pg_config --pkglibdir permet de connatre le nom de ce rpertoire.) Par exemple :
dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
ou dans un environnement Windows :
dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
La valeur par dfaut de ce paramtre est '$libdir'. Si la valeur est une chane vide, la recherche automatique du chemin
est dsactive.
Ce paramtre peut tre modifi l'excution par les superutilisateurs, mais un tel paramtrage ne persiste que pour la dure de
la connexion du client. Il est donc prfrable de ne rserver cette mthode qu' des fins de dveloppement. Il est recommand
d'initialiser ce paramtre dans le fichier de configuration postgresql.conf.
gin_fuzzy_search_limit (integer)
Limite souple haute de la taille de l'ensemble renvoy par un index GIN. Pour plus d'informations, voir Section 54.4,
Conseils et astuces GIN .
local_preload_libraries (string)
Indique les bibliothques partages charger l'initialisation d'une connexion. Si plusieurs bibliothques doivent tre charges, leurs noms sont spars par des virgules. Tous les noms de bibliothques sont convertis en minuscule sauf s'ils sont
compris entre des guillemets doubles. Ce paramtre ne peut pas tre modifi aprs le dmarrage de la session.
Comme il ne s'agit pas d'une option rserve aux superutilisateurs, les bibliothques pouvant tre charges sont restreintes
celles du sous-rpertoire plugins du rpertoire standard des bibliothques. (Il est de la responsabilit de l'administrateur de
356

Configuration du serveur

bases de donnes de s'assurer que seules des bibliothques saines s'y trouvent.) Les entres dans local_preload_libraries peuvent indiquer ce rpertoire explicitement, par exemple $libdir/plugins/ma_lib,
ou n'indiquer que le nom de la bibliothque -- ma_lib a le mme effet que $libdir/plugins/ma_lib.
Contrairement shared_preload_libraries, il n'y a pas de gain de performance charger une bibliothque au dmarrage d'une
session ou sa premire utilisation. Le but de cette fonctionnalit est d'autoriser le chargement de bibliothques de dbogage
ou de mesure de performance dans certaines sessions spcifiques sans commande LOAD explicite. Par exemple, le dbogage
peut tre activ pour toutes les sessions d'un nom d'utilisateur donn en configurant ce paramtre avec ALTER ROLE SET.
Si une bibliothque indique n'est pas trouve, la tentative de connexion choue.
Toute bibliothque supporte par PostgreSQL contient un bloc magique qui permet d'en garantir la compatibilit. Pour
cette raison, les bibliothques non PostgreSQL ne peuvent pas tre charges de cette faon.

18.12. Gestion des verrous


deadlock_timeout (integer)
Temps total, en millisecondes, d'attente d'un verrou avant de tester une condition de verrou mort (deadlock). Le test de verrou
mort est trs coteux, le serveur ne l'effectue donc pas chaque fois qu'il attend un verrou. Les dveloppeurs supposent (de
faon optimiste ?) que les verrous morts sont rares dans les applications en production et attendent simplement un verrou pendant un certain temps avant de lancer une recherche de blocage. Augmenter cette valeur rduit le temps perdu en recherches
inutiles de verrous morts mais retarde la dtection de vraies erreurs de verrous morts. La valeur par dfaut est une seconde
(1s), ce qui est probablement la plus petite valeur pratique. Sur un serveur en pleine charge, elle peut tre augmente. Idalement, ce paramtrage peut dpasser le temps typique d'une transaction de faon augmenter la probabilit qu'un verrou soit
relch avant que le processus en attente ne dcide de lancer une recherche de verrous morts.
Quand log_lock_waits est configur, ce paramtre dtermine aussi le temps d'attente avant qu'un message ne soit enregistr
dans les journaux concernant cette attente. Pour comprendre ces dlais de verrouillage, il peut tre utile de configurer deadlock_timeout une valeur extraordinairement basse.
max_locks_per_transaction (integer)
La table des verrous partags trace les verrous sur max_locks_per_transaction * (max_connections +
max_prepared_transactions) objets (c'est--dire des tables) ; de ce fait, au maximum ce nombre d'objets distincts peuvent tre
verrouills simultanment. Ce paramtre contrle le nombre moyen de verrous d'objets allous pour chaque transaction ; des
transactions individuelles peuvent verrouiller plus d'objets tant que l'ensemble des verrous de toutes les transactions tient dans
la table des verrous. Il ne s'agit pas du nombre de lignes qui peuvent tre verrouilles ; cette valeur n'a pas de limite. La valeur
par dfaut, 64, s'est toujours avre suffisante par le pass, mais il est possible de l'augmenter si des clients accdent de
nombreuses tables diffrentes au sein d'une unique transaction. Ce paramtre ne peut tre initialis qu'au lancement du serveur.
Augmenter ce paramtre peut obliger PostgreSQL rclamer plus de mmoire partage System V ou de smaphores que
ne le permet la configuration par dfaut du systme d'exploitation. Voir la Section 17.4.1, Mmoire partage et smaphore
pour plus d'informations sur la faon d'ajuster ces paramtres, si ncessaire.
Lors de l'excution d'un serveur en attente, vous devez configurer ce paramtre la mme valeur ou une valeur plus importante que sur le serveur matre. Sinon, des requtes pourraient ne pas tre autorises sur le serveur en attente.
max_pred_locks_per_transaction (integer)
La table de verrous de prdicat partage garde une trace des verrous sur max_pred_locks_per_transaction *
(max_connections + max_prepared_transactions) objets (autrement dit tables). Du coup, pas plus que ce nombre d'objets distincts peut tre verrouill un instant. Ce paramtre contrle le nombre moyen de verrous d'objet allous pour chaque transaction ; les transactions individuelles peuvent verrouilles plus d'objets condition que les verrous de toutes les transactions
tiennent dans la table des verrous. Ce n'est pas le nombre de lignes qui peuvent tre verrouilles, cette valeur tant illimite.
La valeur par dfaut, 64, a t gnralement suffisante dans les tests mais vous pouvez avoir besoin d'augmenter cette valeur
si vous avez des clients qui touchent beaucoup de tables diffrentes dans une seule transaction srialisable. Ce paramtre n'est
configurable qu'au lancement du serveur.
Augmenter ce paramtre pourrait faire que PostgreSQL demande plus de mmoire partage System V que ce qu'autorise
la configuration par dfaut du systme d'exploitation. Voir Section 17.4.1, Mmoire partage et smaphore pour des informations sur l'ajustement de ces paramtres, si ncessaire.

18.13. Compatibilit de version et de plateforme


357

Configuration du serveur

18.13.1. Versions prcdentes de PostgreSQL


array_nulls (boolean)
Contrle si l'analyseur de saisie de tableau reconnat NULL non-encadr par des guillemets comme lment de tableaux
NULL. Activ par dfaut (on), il autorise la saisie de valeurs NULL dans un tableau. Nanmoins, les versions de
PostgreSQL antrieures la 8.2 ne supportent pas les valeurs NULL dans les tableaux. De ce fait, ces versions traitent
NULL comme une chane dont le contenu est NULL . Pour une compatibilit ascendante avec les applications ncessitant
l'ancien comportement, ce paramtre peut tre dsactiv (off).
Il est possible de crer des valeurs de tableau contenant des valeurs NULL mme quand cette variable est off.
backslash_quote (enum)
Contrle si un guillemet simple peut tre reprsent par un \' dans une chane. Il est prfrable, et conforme au standard
SQL, de reprsenter un guillemet simple en le doublant ('') mais, historiquement, PostgreSQL a aussi accept \'. Nanmoins, l'utilisation de \' prsente des problmes de scurit car certains encodages client contiennent des caractres multioctets dans lesquels le dernier octet est l'quivalent ASCII numrique d'un \. Si le code ct client ne fait pas un chappement
correct, alors une attaque par injection SQL est possible. Ce risque peut tre vit en s'assurant que le serveur rejette les requtes dans lesquelles apparat un guillemet chapp avec un antislash. Les valeurs autorises de backslash_quote sont
on (autorise \' en permanence), off (le rejette en permanence) et safe_encoding (ne l'autorise que si l'encodage client
n'autorise pas l'ASCII \ dans un caractre multioctet). safe_encoding est le paramtrage par dfaut.
Dans une chane littrale conforme au standard, \ ne signifie que \. Ce paramtre affecte seulement la gestion des chanes
non conformes, incluant la syntaxe de chanes d'chappement (E'...').
default_with_oids (boolean)
Contrle si les commandes CREATE TABLE et CREATE TABLE AS incluent une colonne OID dans les tables nouvellement cres, lorsque ni WITH OIDS ni WITHOUT OIDS ne sont prcises. Ce paramtre dtermine galement si les OID
sont inclus dans les tables cres par SELECT INTO. Ce paramtre est dsactiv (off) par dfaut ; avec PostgreSQL 8.0
et les versions prcdentes, il tait activ par dfaut.
L'utilisation d'OID dans les tables utilisateur est considre comme obsolte. Il est donc prfrable pour la plupart des installations de laisser ce paramtre dsactiv. Les applications qui requirent des OID pour une table particulire doivent prciser
WITH OIDS lors de la cration de la table. Cette variable peut tre active pour des raisons de compatibilit avec les anciennes applications qui ne suivent pas ce comportement.
escape_string_warning (boolean)
S'il est activ (on), un message d'avertissement est affich lorsqu'un antislash (\) apparat dans une chane littrale ordinaire
(syntaxe '...') et que standard_conforming_strings est dsactiv. Il est activ par dfaut (on).
Les applications qui souhaitent utiliser l'antislash comme chappement doivent tre modifies pour utiliser la syntaxe de
chane d'chappement (E'...') car le comportement par dfaut des chanes ordinaires est maintenant de traiter les antislashs
comme un caractre ordinaire, d'aprs le standard SQL. Cette variable peut tre active pour aider localiser le code qui doit
tre chang
regex_flavor (enum)
La flaveur des expressions rationnelles peut tre configure advanced (avance), extended (tendue) ou basic
(basique). La valeur par dfaut est advanced. La configuration extended peut tre utile pour une compatibilit ascendante avec les versions antrieures PostgreSQL 7.4. Voir Section 9.7.3.1, Dtails des expressions rationnelles pour
plus de dtails.
lo_compat_privileges (boolean)
Dans les versions antrieures la 9.0, les Large Objects n'avaient pas de droits d'accs et taient, en ralit, lisibles et modifiables par tous les utilisateurs. L'activation de cette variable dsactive les nouvelles vrifications sur les droits, pour amliorer la compatibilit avec les versions prcdentes. Dsactiv par dfaut.
Configurer cette variable ne dsactive pas toutes les vrifications de scurit pour les Large Objects -- seulement ceux
dont le comportement par dfaut a chang avec PostgreSQL 9.0. Par exemple, lo_import() et lo_export() ont besoin de droits superutilisateur indpendants de cette configuration.
quote_all_identifiers (boolean)
Quand la base de donnes gnre du SQL, ce paramtre force tous les identifiants tre entre guillemets, mme s'ils ne sont
pas (actuellement) des mots-cls. Ceci affectera la sortie de la commande EXPLAIN ainsi que le rsultat des fonctions
comme pg_get_viewdef. Voir aussi l'option --quote-all-identifiers de pg_dump(1) et pg_dumpall(1).
sql_inheritance (boolean)
358

Configuration du serveur

Ce paramtre contrle si les rfrences de table doivent inclure les tables filles. La valeur par dfaut est on, signifiant que les
tables filles sont incluses (et de ce fait, un suffixe * est suppos par dfaut. Si ce paramtre est dsactiv ( off), les tables
filles ne sont pas inclus (et de ce fait, le prfixe ONLY est ajout). Le standard SQL requiert que les tables filles soient inclues,
donc le paramtrages off n'est pas conforme au standard. Cependant, il est fourni par compatibilit avec les versions PostgreSQL antrieures la 7.1. Voir Section 5.8, L'hritage pour plus d'informations.
Dsactiver sql_allance n'est pas conseill car le comportement induis par cette configuration porte faire beaucoup
d'erreurs. Ceci n'est pas constat lorsque ce paramtre est activ comme le demande le standard SQL. Les discussions sur
l'hritage dans ce manuel supposent gnralement que ce paramtre est configur on.
standard_conforming_strings (boolean)
Contrle si les chanes ordinaires ('...') traitent les antislashs littralement, comme cela est indiqu dans le standard SQL.
partir de PostgreSQL 9.1, ce paramtre est activ par dfaut, donc on (les versions prcdentes avaient off par dfaut). Les applications peuvent vrifier ce paramtre pour dterminer la faon dont elles doivent traiter les chanes littrales.
La prsence de ce paramtre indique aussi que la syntaxe de chane d'chappement (E'...') est supporte. La syntaxe de
chane d'chappement (Section 4.1.2.2, Constantes chane avec des chappements de style C ) doit tre utilise pour les applications traitant les antislashs comme des caractres d'chappement.
synchronize_seqscans (boolean)
Cette variable permet la synchronisation des parcours squentiels de grosses tables pour que les parcours concurrents lisent le
mme bloc peu prs au mme moment, et donc partagent la charge d'entres/sorties. Quand ce paramtre est activ, un parcours peut commencer au milieu de la table, aller jusqu' la fin, puis revenir au dbut pour rcuprer toutes les lignes, ce
qui permet de le synchroniser avec l'activit de parcours dj entams. Il peut en rsulter des modifications non prvisibles
dans l'ordre des lignes renvoyes par les requtes qui n'ont pas de clause ORDER BY. Dsactiver ce paramtre assure un comportement identique aux versions prcdant la 8.3 pour lesquelles un parcours squentiel commence toujours au dbut de la
table. Activ par dfaut (on).

18.13.2. Compatibilit entre la plateforme et le client


transform_null_equals (boolean)
Lorsque ce paramtre est activ (on), les expressions de la forme expr = NULL (ou NULL = expr) sont traites comme
expr IS NULL, c'est--dire qu'elles renvoient vrai si expr s'value la valeur NULL, et faux sinon. Le bon comportement, compatible avec le standard SQL, de expr = NULL est de toujours renvoyer NULL (inconnu). De ce fait, ce paramtre est dsactiv par dfaut.
Toutefois, les formulaires filtrs dans Microsoft Access engendrent des requtes qui utilisent expr = NULL pour tester
les valeurs NULL. Il peut donc tre souhaitable, lorsque cette intarface est utilise pour accder une base de donnes,
d'activer ce paramtre. Comme les expressions de la forme expr = NULL renvoient toujours la valeur NULL (en utilisant
l'interprtation du standard SQL), elles ne sont pas trs utiles et n'apparaissent pas souvent dans les applications normales. De
ce fait, ce paramtre a peu d'utilit en pratique. Mais la smantique des expressions impliquant des valeurs NULL est souvent
source de confusion pour les nouveaux utilisateurs. C'est pourquoi ce paramtre n'est pas activ par dfaut.
Ce paramtre n'affecte que la forme exacte = NULL, pas les autres oprateurs de comparaison ou expressions quivalentes en
terme de calcul des expressions qui impliquent l'oprateur gal (tels que IN). De ce fait, ce paramtre ne doit pas tre considr comme un correctif gnral une mauvaise programmation.
De plus amples informations sont disponibles dans la Section 9.2, Oprateurs de comparaison .

18.14. Gestion des erreurs


exit_on_error (boolean)
Si positionn true, toute erreur terminera la session courante. Par dfaut, ce paramtre est false, pour que seules des erreurs
de niveau FATAL puissent terminer la session.
restart_after_crash (boolean)
Quand ce paramtre est configur true, ce qui est sa valeur par dfaut, PostgreSQL redmarrera automatiquement aprs
un arrt brutal d'un processus serveur. Il est gnralement prfrable de laisser cette valeur true car cela maximise la disponibilit de la base de donnes. Nanmoins, dans certaines circonstances, comme le fait que PostgreSQL soit lanc par un
outil de clustering, il pourrait tre utile de dsactiver le redmarrage pour que l'outil puisse avoir le contrle et prendre toute
action qui lui semble appropri.

359

Configuration du serveur

18.15. Options prconfigures


Les paramtres qui suivent sont en lecture seule. Ils sont dtermins la compilation ou l'installation de PostgreSQL. De
ce fait, ils sont exclus du fichier postgresql.conf d'exemple. Ces paramtres dcrivent diffrents aspects du comportement
de PostgreSQL qui peuvent s'avrer intressants pour pour certaines applications, en particulier pour les interfaces
d'administration.
block_size (integer)
Informe sur la taille d'un bloc disque. Celle-ci est dtermine par la valeur de BLCKSZ la construction du serveur. La valeur
par dfaut est de 8192 octets. La signification de diverses variables de configuration (shared_buffers, par exemple) est influence par block_size. Voir la Section 18.4, Consommation des ressources pour plus d'informations.
integer_datetimes (boolean)
Informe sur la construction de PostgreSQL avec le support des dates et heures sur des entiers de 64 bits. Ceci peut tre
dsactiv avec l'option --disable-integer-datetimes au moment de la construction de PostgreSQL. La valeur
par dfaut est on.
lc_collate (string)
Affiche la locale utilise pour le tri des donnes de type texte. Voir la Section 22.1, Support des locales pour plus
d'informations. La valeur est dtermine lors de la cration d'une base de donnes.
lc_ctype (string)
Affiche la locale qui dtermine les classifications de caractres. Voir la Section 22.1, Support des locales pour plus
d'informations. La valeur est dtermine lors de la cration d'une base de donnes. Elle est habituellement identique
lc_collate. Elle peut, toutefois, pour des applications particulires, tre configure diffremment.
max_function_args (integer)
Affiche le nombre maximum d'arguments des fonctions. Ce nombre est dtermin par la valeur de FUNC_MAX_ARGS lors de
la construction du serveur. La valeur par dfaut est de 100 arguments.
max_identifier_length (integer)
Affiche la longueur maximale d'un identifiant. Elle est dtermine NAMEDATALEN - 1 lors de la construction du serveur. La
valeur par dfaut de NAMEDATALEN est 64 ; la valeur par dfaut de max_identifier_length est, de ce fait, de 63 octets mais peut tre moins de 63 caractres lorsque des encodages multi-octets sont utiliss.
max_index_keys (integer)
Affiche le nombre maximum de cls d'index. Ce nombre est dtermin par la valeur de INDEX_MAX_KEYS lors de la
construction du serveur. La valeur par dfaut est de 32 cls.
segment_size (integer)
Retourne le nombre de blocs (pages) qui peuvent tre stocks dans un segment de fichier. C'est dtermin par la valeur de
RELSEG_SIZE la compilation du serveur. La valeur maximum d'un fichier de segment en octet est gal segment_size multipli par block_size ; par dfaut, c'est 1 Go.
server_encoding (string)
Affiche l'encodage de la base de donnes (jeu de caractres). Celui-ci est dtermin lors de la cration de la base de donnes.
Les clients ne sont gnralement concerns que par la valeur de client_encoding.
server_version (string)
Affiche le numro de version du serveur. Celui-ci est dtermin par la valeur de PG_VERSION lors de la construction du serveur.
server_version_num (integer)
Affiche le numro de version du serveur sous la forme d'un entier. Celui-ci est dtermin par la valeur de
PG_VERSION_NUM lors de la construction du serveur.
wal_block_size (integer)
Retourne la taille d'un bloc disque de WAL. C'est dtermin par la valeur XLOG_BLCKSZ la compilation du serveur. La valeur par dfaut est 8192 octets.
wal_segment_size (integer)
Retourne le nombre de blocs (pages) dans un fichier de segment WAL. La taille totale d'un fichier de segment WAL en octets
est gale wal_segment_size multipli par wal_block_size ; Par dfaut, c'est 16 Mo. Voir Section 29.4,
360

Configuration du serveur

Configuration des journaux de transaction pour plus d'informations.

18.16. Options personnalises


Cette fonctionnalit a t conue pour permettre l'ajout de paramtres habituellement inconnus de PostgreSQL par des modules
complmentaires (comme les langages procduraux). Cela permet de configurer ces modules de faon standard.
custom_variable_classes (string)
Cette variable indique les noms de classe utiliser pour les variables personnalises, sous la forme d'une liste spare par des
virgules. Une variable personnalise est une variable habituellement inconnue de PostgreSQL mais utilise par certains modules complmentaires. Les noms de ces variables doivent tre constitus d'un nom de classe, d'un point et d'un nom de variable. custom_variable_classes indique tous les noms de classe utiliss dans une installation particulire. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
La difficult de configurer des variables personnalises dans postgresql.conf se situe dans le fait que le fichier doit tre lu
avant que les modules complmentaires ne soient chargs. De ce fait, les variables sont habituellement rejetes parce
qu'inconnues. Lorsque custom_variable_classes est initialis, le serveur accepte les dfinitions de variables arbitraires
l'intrieur de chaque classe indique. Ces variables sont traites comme des emplacements et n'ont aucune fonction tant que le module qui les dfinit n'est pas charg. Quand un module d'une classe spcifique est charg, il ajoute les bonnes dfinitions de variables pour son nom de classe, convertit les valeurs des emplacements en fonction de leurs dfinitions et met des messages
d'avertissement pour tout emplacement non reconnu de la classe restant.
Exemple de ce que peut contenir postgresql.conf lorsque les variables personnalises sont utilises :
custom_variable_classes = 'plpgsql,plperl'
plpgsql.variable_conflict = use_variable
plperl.use_strict = true
plruby.use_strict = true
# generates error, unknown class name

18.17. Options pour les dveloppeurs


Les paramtres qui suivent permettent de travailler sur les sources de PostgreSQL et, dans certains cas, fournissent une aide la
rcupration de bases de donnes svrement endommages. Il n'y a aucune raison de les utiliser en configuration de production.
En tant que tel, ils sont exclus du fichier d'exemple de postgresql.conf. Un certain nombre d'entre eux requirent des options de compilation spciales pour fonctionner.
allow_system_table_mods (boolean)
Autorise la modification de la structure des tables systmes. Ce paramtre, utilis par initdb, n'est modifiable qu'au dmarrage
du serveur.
debug_assertions (boolean)
Active diffrentes vrifications d'affectations. C'est une aide au dbogage. En cas de problmes tranges ou d'arrts brutaux,
ce paramtre peut tre activ car il permet de remonter des erreurs de programmation. Pour utiliser ce paramtre, la macro
USE_ASSERT_CHECKING doit tre dfinie lors de la construction de PostgreSQL ( l'aide de l'option -enable-cassert de configure). Ce paramtre est activ par dfaut si PostgreSQL a t construit avec l'activation des
assertions.
ignore_system_indexes (boolean)
Ignore les index systme lors de la lecture des tables systme (mais continue de les mettre jour lors de modifications des
tables). Cela s'avre utile lors de la rcupration d'index systme endommags. Ce paramtre ne peut pas tre modifi aprs le
dmarrage de la session.
post_auth_delay (integer)
Si ce paramtre est diffrent de zro, un dlai de ce nombre de secondes intervient, aprs l'tape d'authentification, lorsqu'un
nouveau processus serveur est lanc. Ceci a pour but de donner l'opportunit aux dveloppeurs d'attacher un dbogueur au
processus serveur. Ce paramtre ne peut pas tre modifi aprs le dmarrage de la session.
pre_auth_delay (integer)
Si ce paramtre est diffrent de zro, un dlai de ce nombre de secondes intervient juste aprs la cration d'un nouveau processus, avant le processus d'authentification. Ceci a pour but de donner une opportunit aux dveloppeurs d'attacher un dbogueur au processus serveur pour tracer les mauvais comportements pendant l'authentification. Ce paramtre ne peut tre confi361

Configuration du serveur

gur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.


trace_notify (boolean)
Produit un grand nombre de sorties de dbogage pour les commandes LISTEN et NOTIFY. client_min_messages ou
log_min_messages doivent tre positionnes DEBUG1 ou plus bas pour envoyer cette sortie sur les traces client ou serveur,
respectivement.
trace_recovery_messages (enum)
Contrle les niveaux des traces crites dans le journal applicatif pour les modules ncessaires lors du traitement de la restauration. Cela permet l'utilisateur de surcharger la configuration normale de log_min_messages, mais seulement pour des messages spcifiques. a a t ajout principalement pour dbugger Hot Standby. Les valeurs valides sont DEBUG5, DEBUG4,
DEBUG3, DEBUG2, DEBUG1 et LOG. La valeur par dfaut, LOG, n'affecte pas les dcisions de trace. Les autres valeurs
causent l'apparition de messages de dbogage relatifs la restauration pour tous les messages de ce niveau et des niveaux suprieurs. Elles utilisent malgr tout le niveau LOG ; pour les configurations habituelles de log_min_messages, cela rsulte en un envoi sans condition dans les traces du serveur. Ce paramtre ne peut tre configur que dans le fichier postgresql.conf ou indiqu sur la ligne de commande.
trace_sort (boolean)
Si ce paramtre est actif, des informations concernant l'utilisation des ressources lors des oprations de tri sont mises. Ce paramtre n'est disponible que si la macro TRACE_SORT a t dfinie lors de la compilation de PostgreSQL (nanmoins,
TRACE_SORT est actuellement dfinie par dfaut).
trace_locks (boolean)
Si activ, met des informations propos de l'utilisation des verrous. L'information fournie inclut le type d'opration de verrouillage, le type de verrou et l'identifiant unique de l'objet verrouill ou dverrouill. Sont aussi inclus les masques de bits
pour les types de verrous dj accords pour cet objet, ainsi que pour les types de verrous attendus sur cet objet. Pour chaque
type de verrou un dcompte du nombre de verrous accords et en attente est aussi retourn, ainsi que les totaux. Un exemple
de sortie dans le journal applicatif est montr ici :
LOG:
LOG:
LOG:
LOG:

LockAcquire: new: lock(0xb7acd844) id(24688,24696,0,0,0,1)


grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0
wait(0) type(AccessShareLock)
GrantLock: lock(0xb7acd844) id(24688,24696,0,0,0,1)
grantMask(2) req(1,0,0,0,0,0,0)=1 grant(1,0,0,0,0,0,0)=1
wait(0) type(AccessShareLock)
UnGrantLock: updated: lock(0xb7acd844) id(24688,24696,0,0,0,1)
grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0
wait(0) type(AccessShareLock)
CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1)
grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0
wait(0) type(INVALID)

Les dtails de la structure retourne peuvent tre trouvs dans src/include/storage/lock.h.


Ce paramtre n'est disponible que si la macro LOCK_DEBUG a t dfinie quand PostgreSQL a t compil.
trace_lwlocks (boolean)
Si on, gnre des informations propos de l'utilisation de verrous lgers (lightweight lock). Les verrous lgers servent principalement fournir une exclusion mutuelle d'accs aux structures de donnes en mmoire partage.
Ce paramtre n'est disponible que si la macro LOCK_DEBUG a t dfinie quand PostgreSQL a t compil.
trace_userlocks (boolean)
Si activ, gnre des informations propos de l'utilisation de verrous utilisateurs. La sortie est la mme que pour trace_locks,
mais restreinte aux verrous informatifs.
trace_lock_oidmin (integer)
Si positionn, ne trace pas les verrouillages pour des tables en dessous de cet OID. ( utiliser pour ne pas avoir de sortie pour
les tables systmes)
Ce paramtre n'est disponible que si la macro LOCK_DEBUG a t dfinie quand PostgreSQL a t compil.
trace_lock_table (integer)
Tracer les verrouillages sur cette table de faon inconditionnelle.
Ce paramtre n'est disponible que si la macro LOCK_DEBUG a t dfinie quand PostgreSQL a t compil.
debug_deadlocks (boolean)
362

Configuration du serveur

Si positionn, gnre des informations propos de tous les verrous en cours quand l'expiration de temps d'attente d'un verrou
mortel se produit.
Ce paramtre n'est disponible que si la macro LOCK_DEBUG a t dfinie quand PostgreSQL a t compil.
log_btree_build_stats (boolean)
Si positionn, trace des statistiques d'utilisation de ressource systme (mmoire et processeur) sur diffrentes oprations Btree.
Ce paramtre n'est disponible que si la macro BTREE_BUILD_STATS a t dfinie quand PostgreSQL a t compil.
wal_debug (boolean)
Si ce paramtre est positionn on, une sortie de dbogage relative aux WAL est mise. Ce paramtre n'est disponible que si
la macro WAL_DEBUG a t dfinie au moment de la compilation de PostgreSQL.
zero_damaged_pages (boolean)
La dtection d'un en_tte de page endommag cause normalement le renvoi d'une erreur par PostgreSQL, annulant du
mme coup la transaction en cours. Activer zero_damaged_pages fait que le systme renvoie un message
d'avertissement, efface la page endommage en mmoire et continue son traitement. Ce comportement dtruit des donnes,
trs exactement toutes les lignes comprises dans la page endommage. Nanmoins, il vous permet de passer l'erreur et de rcuprer les lignes des pages non endommages qui pourraient tre prsentes dans la table. C'est intressant pour rcuprer des
donnes si une corruption est survenue cause d'une erreur logicielle ou matrielle. Vous ne devriez pas activer cette option
sauf si vous avez perdu tout espoir de rcuprer les donnes des pages endommages d'une table. L'effacement des pages n'est
pas vide sur disque donc il est recommand de recrer la table ou l'index avant de dsactiver de nouveau ce paramtre. La
configuration par dfaut est off, et peut seulement tre modifie par un superutilisateur.

18.18. Options courtes


Pour des raisons pratiques, il existe galement des commutateurs en ligne de commandes sur une seule lettre pour certains paramtres. Ceux-ci sont dcrits dans le Tableau 18.2, Cl d'option courte . Certaines des options existent pour des raisons historiques et leur prsence en tant qu'option courte ne doit pas tre vue comme une incitation son utilisation massive.
Tableau 18.2. Cl d'option courte

Option courte

quivalent

-A x

debug_assertions = x

-B x

shared_buffers = x

-d x

log_min_messages = DEBUGx

-e

datestyle = euro

-fb, -fh, -fi, -fm, -fn, -fs, -ft

enable_bitmapscan = off, enable_hashjoin =


off, enable_indexscan = off, enable_mergejoin
= off, enable_nestloop = off, enable_seqscan
= off, enable_tidscan = off

-F

fsync = off

-h x

listen_addresses = x

-i

listen_addresses = '*'

-k x

unix_socket_directory = x

-l

ssl = on

-N x

max_connections = x

-O

allow_system_table_mods = on

-p x

port = x

-P

ignore_system_indexes = on

-s

log_statement_stats = on

-S x

work_mem = x

-tpa, -tpl, -te

log_parser_stats = on, log_planner_stats =


on, log_executor_stats = on

-W x

post_auth_delay = x
363

Chapitre 19. Authentification du client


Quand une application client se connecte au serveur de bases de donnes, elle indique le nom de l'utilisateur de base de donnes
utiliser pour la connexion, de la mme faon qu'on se connecte un ordinateur Unix sous un nom d'utilisateur particulier. Au
sein de l'environnement SQL, le nom d'utilisateur de la base de donnes active dtermine les droits rgissant l'accs aux objets
de la base de donnes -- voir le Chapitre 20, Rles de la base de donnes pour plus d'informations. Ainsi, il est essentiel de limiter le nombre de bases de donnes auxquelles les utilisateurs peuvent se connecter.

Note
Comme expliqu dans le Chapitre 20, Rles de la base de donnes, PostgreSQL gre les droits par
l'intermdiaire des rles . Dans ce chapitre, le terme utilisateur de bases de donnes est utilis pour signifier
rle disposant du droit LOGIN .
L'authentification est le processus par lequel le serveur de bases de donnes tablit l'identit du client et, par extension, dtermine si l'application client (ou l'utilisateur qui l'utilise) est autorise se connecter avec le nom d'utilisateur de bases de donnes
indiqu.
PostgreSQL offre quantit de mthodes d'authentification diffrentes. La mthode utilise pour authentifier une connexion
client particulire peut tre slectionne d'aprs l'adresse (du client), la base de donnes et l'utilisateur.
Les noms d'utilisateur de bases de donnes sont spars de faon logique des noms d'utilisateur du systme d'exploitation sur lequel tourne le serveur. Si tous les utilisateurs d'un serveur donn ont aussi des comptes sur la machine serveur, il peut tre pertinent d'attribuer aux utilisateurs de bases de donnes des noms qui correspondent ceux des utilisateurs du systme
d'exploitation. Cependant, un serveur qui accepte des connexions distantes peut avoir des utilisateurs de bases de donnes dpourvus de compte correspondant sur le systme d'exploitation. Dans ce cas, aucune correspondance entre les noms n'est ncessaire.

19.1. Le fichier pg_hba.conf


L'authentification du client est contrle par un fichier, traditionnellement nomm pg_hba.conf et situ dans le rpertoire data du groupe de bases de donnes, par exemple /usr/local/pgsql/data/pg_hba.conf (HBA signifie host-based authentication : authentification fonde sur l'hte.) Un fichier pg_hba.conf par dfaut est install lorsque le rpertoire data est
initialis par initdb. Nanmoins, il est possible de placer le fichier de configuration de l'authentification ailleurs ; voir le paramtre de configuration hba_file.
Le format gnral du fichier pg_hba.conf est un ensemble d'enregistrements, un par ligne. Les lignes vides sont ignores
tout comme n'importe quel texte plac aprs le caractre de commentaire #. Un enregistrement est constitu d'un certain nombre
de champs spars par des espace et/ou des tabulations. Les enregistrements ne peuvent pas tre continus sur plusieurs lignes.
Les champs peuvent contenir des espaces si la valeur du champ est mise entre guillemets. Mettre entre guillemets un des motscls dans un champ base de donnes, utilisateur ou adresse (par exemple, all ou replication) fait que le mot perd son interprtation spciale, ou correspond la base de donnes, l'utilisateur ou l'hte ayant ce nom.
Chaque enregistrement prcise un type de connexion, une plage d'adresses IP (si appropri au type de connexion), un nom de
base de donnes, un nom d'utilisateur et la mthode d'authentification utiliser pour les connexions correspondant ces paramtres. Le premier enregistrement qui correspond au type de connexion, l'adresse client, la base de donnes demande et au
nom d'utilisateur est utilis pour effectuer l'authentification. Il n'y a pas de suite aprs une erreur ( fall-through ou
backup ) : si un enregistrement est choisi et que l'authentification choue, les enregistrements suivants ne sont pas considrs.
Si aucun enregistrement ne correspond, l'accs est refus.
Un enregistrement peut avoir l'un des sept formats suivants.
local
host
hostssl
hostnossl
host
hostssl
hostnossl

database
database
database
database
database
database
database

user
user
user
user
user
user
user

auth-method [auth-options]
address auth-method [auth-options]
address auth-method [auth-options]
address auth-method [auth-options]
IP-address IP-mask auth-method [auth-options]
IP-address IP-mask auth-method [auth-options]
IP-address IP-mask auth-method [auth-options]

La signification des champs est la suivante :


local
Cet enregistrement intercepte les tentatives de connexion qui utilise les sockets du domaine Unix. Sans enregistrement de ce
364

Authentification du client

type, les connexions de sockets du domaine Unix ne sont pas autorises.


host
Cet enregistrement intercepte les tentatives de connexion par TCP/IP. Les lignes host s'appliquent toute tentative de
connexion, SSL ou non.

Note
Les connexions TCP/IP ne sont pas autorises si le serveur n'est pas dmarr avec la valeur approprie du paramtre de configuration listen_addresses. En effet, par dfaut, le serveur n'coute que les connexions TCP/IP en
provenance de l'adresse loopback locale, localhost.
hostssl
Cet enregistrement intercepte les seules tentatives de connexions par TCP/IP qui utilisent le chiffrement SSL.
Pour utiliser cette fonction, le serveur doit tre compil avec le support de SSL. De plus, SSL doit tre activ au dmarrage du
serveur en positionnant le paramtre de configuration ssl (voir la Section 17.9, Connexions tcp/ip scurises avec ssl pour
plus d'informations).
hostnossl
Cet enregistrement a un comportement oppos hostssl : il n'intercepte que les tentatives de connexion qui n'utilisent pas
SSL.
database
Indique les noms des bases de donnes concernes par l'enregistrement. La valeur all indique qu'il concerne toutes les bases
de donnes. Le terme sameuser indique que l'enregistrement concide si la base de donnes demande a le mme nom que
l'utilisateur demand. Le terme samerole indique que l'utilisateur demand doit tre membre du rle portant le mme nom
que la base de donnes demande (samegroup est obsolte bien qu'il soit toujours accept comme criture alternative de
samerole.). La valeur replication indique que l'enregistrement tablit une correspondance si une connexion de rplication est demande (notez que les connexions de rplication ne ciblent pas une base de donnes particulire). Dans tous les
autres cas, c'est le nom d'une base de donnes particulire. Plusieurs noms de base de donnes peuvent tre fournis en les sparant par des virgules. Un fichier contenant des noms de base de donnes peut tre indiqu en faisant prcder le nom du fichier de @.
user
Indique les utilisateurs de bases de donnes auxquels cet enregistrement correspond. La valeur all indique qu'il concerne
tous les utilisateurs. Dans le cas contraire, il s'agit soit du nom d'un utilisateur spcifique de bases de donnes ou d'un nom de
groupe prcd par un + (il n'existe pas de vritable distinction entre les utilisateurs et les groupes dans PostgreSQL ; un +
signifie exactement tablit une correspondance pour tous les rles faisant parti directement ou indirectement de ce rle
alors qu'un nom sans + tablit une correspondance avec ce rle spcifique). Plusieurs noms d'utilisateurs peuvent tre fournis
en les sparant par des virgules. Un fichier contenant des noms d'utilisateurs peut tre indiqu en faisant prcder le nom du
fichier de @.
address
Indique l'adresse IP ou la plage d'adresses IP laquelle correspond cet enregistrement. Ce champ peut contenir soit un nom de
machine (FQDN), soit le suffixe d'un domaine (sous la forme .exemple.com), soit une adresse ou une plage d'adresses IP, soit
enfin l'un des mots-cls mentionns ci-aprs.
Les adresses IP doivent tre crites sous la notation dcimale standard avec une longueur de masque CIDR. La longueur du
masque indique le nombre de bits forts pour lesquels une correspondance doit tre trouve avec l'adresse IP du client. Les bits
de droite doivent valoir zro dans l'adresse IP indique. Il ne doit y avoir aucune espace entre l'adresse IP, le / et la longueur
du masque CIDR.
la place du CIDR-address, vous pouvez crire samehost pour correspondre aux adresses IP du serveur ou samenet
pour correspondre toute adresse du sous-rseau auquel le serveur est directement connect.
Une adresse CIDR (CIDR-address) est typiquement 172.20.143.89/32 pour un hte seul, 172.20.143.0/24
pour un petit rseau ou 10.6.0.0/16 pour un rseau plus grand. 0.0.0.0/0 reprsente toutes les adresses IPv4, et ::/0
reprsente l'ensemble des adresses IPv6. Pour n'indiquer qu'un seul hte, on utilise un masque de 32 pour IPv4 ou 128 pour
IPv6. Dans une adresse rseau, ne pas oublier les zros terminaux.
Une adresse IP indique au format IPv4 concide avec les connexions IPv6 d'adresse correspondante. Par exemple,
127.0.0.1 correspond l'adresse IPv6 ::ffff:127.0.0.1. Une entre donne au format IPv6 correspond uniquement
aux connexions IPv6 mme si l'adresse reprsente est dans le domaine IPv4-vers-IPv6. Les adresses au format IPv6 sont rejetes si la bibliothque systme C ne supporte pas les adresses IPv6.
La valeur all permet de cibler n'importe quelle adresse IP cliente, samehost n'importe quelle adresse IP du serveur ou
samenet pour toute adresse IP faisant partie du mme sous-rseau que le serveur.
365

Authentification du client

Si un nom d'hte est renseign (dans les faits tout ce qui ne correspond pas une adresse ou une plage d'adresses IP, ni un
mot cl, sera trait comme un nom d'hte potentiel), ce nom est compar au rsultat d'une rsolution de nom inverse de
l'adresse IP du client (ou une recherche DNS inverse si un DNS est utilis). Les comparaisons de noms d'htes ne sont pas
sensibles la casse. En cas de correspondance, une nouvelle recherche rcursive de nom sera lance afin de dterminer que le
nom d'hte concorde bel et bien avec l'adresse IP du client. L'enregistrement n'est valid qu'en cas de concordance entre la rsolution inverse et la rsolution rcursive pour l'adresse IP cliente. (Le nom d'hte fourni dans le fichier pg_hba.conf doit
donc correspondre au moins l'une des adresses IP fournies par le mcanisme de rsolution de noms, sinon l'enregistrement
ne sera pas pris en considration. Certains serveurs de noms rseau permettent d'associer une adresse IP de multiples noms
d'htes (alias DNS), mais bien souvent le systme d'exploitation ne retourne qu'un seul nom d'hte lors de la rsolution d'une
adresse IP.)
Un nom d'hte dbutant par un point (.) ciblera le suffixe du nom d'hte du poste client. Du coup, indiquer .exemple.com
correspondra la machine foo.exemple.com (mais pas au client exemple.com).
Lorsque vous spcifiez des noms d'htes dans le fichier pg_hba.conf, vous devez vous assurer que la rsolution de noms
soit raisonnablement rapide. dfaut, il peut tre avantageux de configurer un serveur-cache local pour effectuer la rsolution
de noms, tel que nscd. Vous pouvez galement valider le paramtre de configuration log_hostname afin de retrouver dans
les journaux le nom d'hte du client au lieu de sa simple adresse IP.
diffrentes occasions, des utilisateurs ont demand pourquoi les demandes d'authentification par noms d'htes sont gres
de manire aussi complexe : deux requtes de rsolution du nom d'hte dont une rsolution inverse qui n'est parfois pas
configure ou peut pointer vers un nom d'hte indsirable. Son but premier rside dans l'efficacit de l'authentification : une
tentative de connexion ncessite deux rsolutions de l'adresse du client, et s'il survient un problme de rsolution de nom,
cela devient le problme de ce client particulier. Une hypothtique implmentation alternative ne se basant que sur la seule
rsolution de nom rcursive devrait rsoudre tous les noms d'hte mentionns dans le fichier pg_hba.conf pour chacune
des tentatives de connexion au serveur. Ce qui s'avrerait lent par nature, et dans le cas d'un problme la rsolution d'un
nom d'hte, deviendrait un problme pour tout le monde.
De plus, une rsolution inverse est ncessaire pour implmenter la fonctionnalit de correspondance par suffixe dans la mesure o le nom d'hte du candidat la connexion doit tre connu afin de pouvoir effectuer cette comparaison.
Enfin, cette mthode est couramment adopte par d'autres implmentations du contrle d'accs bas sur les noms d'htes,
tels que le serveur web Apache ou TCP-wrapper.
Ce champ ne concerne que les enregistrements host, hostssl et hostnossl.
IP-address, IP-mask
Ces champs peuvent tre utiliss comme alternative la notation CIDR-address. Au lieu de spcifier la longueur du
masque, le masque rel est indique dans une colonne distincte. Par exemple, 255.0.0.0 reprsente une longueur de
masque CIDR IPv4 de 8, et 255.255.255.255 reprsente une longueur de masque de 32.
Ces champs ne concernent que les enregistrements host, hostssl et hostnossl.
auth-method
Indique la mthode d'authentification utiliser lors d'une connexion via cet enregistrement. Les choix possibles sont rsums
ici ; les dtails se trouvent dans la Section 19.3, Mthodes d'authentification .
trust
Autorise la connexion sans condition. Cette mthode permet quiconque peut se connecter au serveur de bases de donnes de
s'enregistrer sous n'importe quel utilisateur PostgreSQL de son choix sans mot de passe ou autre authentification. Voir la
Section 19.3.1, Authentification trust pour les dtails.
reject
Rejette la connexion sans condition. Ce cas est utile pour filtrer certains htes d'un groupe, par exemple une ligne reject peut bloquer la connexion d'un hte spcifique alors qu'une ligne plus bas permettra aux autres htes de se connecter
partir d'un rseau spcifique.
md5
Demande au client de fournir un mot de passe chiffr MD5 pour l'authentification. Voir la Section 19.3.2, Authentification
par mot de passe pour les dtails.
password
Requiert que le client fournisse un mot de passe non chiffr pour l'authentification. Comme le mot de passe est envoy en
clair sur le rseau, ceci ne doit pas tre utilis sur des rseaux non dignes de confiance. Voir la Section 19.3.2,
Authentification par mot de passe pour les dtails.
366

Authentification du client

gss
Utilise GSSAPI pour authentifier l'utilisateur. Disponible uniquement pour les connexions TCP/IP. Voir Section 19.3.3,
Authentification GSSAPI pour les dtails.
sspi
Utilise SSPI pour authentifier l'utilisateur. Disponible uniquement sur Windows. Voir Section 19.3.4, Authentification SSPI pour plus de dtails.
krb5
Utilise Kerberos V5 pour authentifier l'utilisateur. Ceci n'est disponible que pour les connexions TCP/IP. Voir la Section 19.3.5, Authentification Kerberos pour les dtails.
ident
Rcupre le nom de l'utilisateur en contactant le serveur d'identification sur le poste client, et vrifie que cela correspond au
nom d'utilisateur de base de donnes demand. L'authentification Ident ne peut tre utilise que pour les connexions TCP/IP.
Pour les connexions locales, elle sera remplace par l'authentification peer.
peer
Rcupre le nom d'utilisateur identifi par le systme d'exploitation du client et vrifie que cela correspond au nom
d'utilisateur de base de donnes demand. Peer ne peut tre utilise que pour les connexions locales. Voir la Section 19.3.7,
Peer Authentication ci-dessous pour les details.
ldap
Authentification par un serveur LDAP. Voir la Section 19.3.8, Authentification LDAP pour les dtails.
radius
Authentification par un serveur RADIUS. Voir Section 19.3.9, Authentification RADIUS pour les dtails.
cert
Authentification par certificat client SSL. Voir Section 19.3.10, Authentification de certificat pour les dtails.
pam
Authentification par les Pluggable Authentification Modules (PAM) fournis par le systme d'exploitation. Voir la Section 19.3.11, Authentification PAM pour les dtails.
auth-options
Aprs le champ auth-method, on peut trouver des champs de la forme nom=valeur qui spcifient des options pour la
mthode d'authentification. Les dtails sur les options disponibles apparaissent ci-dessous pour chaque mthode
d'authentification.
Les fichiers inclus par les constructions @ sont lus comme des listes de noms, spars soit par des espaces soit par des virgules.
Les commentaires sont introduits par le caractre # comme dans pg_hba.conf, et les constructions @ imbriques sont autorises. moins que le nom du fichier qui suit @ ne soit un chemin absolu, il est suppos relatif au rpertoire contenant le fichier le
rfrenant.
Les enregistrements du fichier pg_hba.conf sont examins squentiellement chaque tentative de connexion, l'ordre des enregistrements est donc significatif. Gnralement, les premiers enregistrements ont des paramtres d'interception de connexions
stricts et des mthodes d'authentification peu restrictives tandis que les enregistrements suivants ont des paramtres plus larges et
des mthodes d'authentification plus fortes. Par exemple, on peut souhaiter utiliser l'authentification trust pour les connexions
TCP/IP locales mais demander un mot de passe pour les connexion TCP/IP distantes. Dans ce cas, l'enregistrement prcisant une
authentification trust pour les connexions issues de 127.0.0.1 apparat avant un enregistrement indiquant une authentification
par mot de passe pour une plage plus tendue d'adresses IP client autorises.
Le fichier pg_hba.conf est lu au dmarrage et lorsque le processus serveur principal reoit un signal SIGHUP. Si le fichier est
dit sur un systme actif, on peut signaler au postmaster (en utilisant pg_ctl reload ou kill -HUP) de relire le fichier.

Astuce
Pour se connecter une base particulire, un utilisateur doit non seulement passer les vrifications de
pg_hba.conf mais doit galement avoir le droit CONNECT sur cette base. Pour contrler qui peut se connecter
quelles bases, il est en gnral plus facile de le faire en donnant ou retirant le privilge CONNECT plutt qu'en
plaant des rgles dans le fichier pg_hba.conf.
Quelques exemples d'entres de pg_hba.conf sont donns ci-dessous dans l'Exemple 19.1, Exemple d'entres de
pg_hba.conf . Voir la section suivante pour les dtails des mthodes d'authentification.
Exemple 19.1. Exemple d'entres de pg_hba.conf

367

Authentification du client

# Permettre n'importe quel utilisateur du systme local de se connecter


# la base de donnes sous n'importe quel nom d'utilisateur au travers
# des sockets de domaine Unix (par dfaut pour les connexions locales).
#
# TYPE DATABASE
USER
ADDRESS
METHOD
local
all
all
trust
# La mme chose en utilisant les connexions TCP/IP locales loopback.
#
# TYPE DATABASE
USER
ADDRESS
METHOD
host
all
all
127.0.0.1/32
trust
# Pareil mais en utilisant une colonne netmask distincte.
#
# TYPE DATABASE
USER
IP-ADDRESS
IP-mask
host
all
all
127.0.0.1
255.255.255.255
# Pareil mais en IPv6.
#
# TYPE DATABASE
host
all

USER
all

ADDRESS
::1/128

METHOD
trust

METHOD
trust

# l'identique en utilisant le nom d'hte (qui doit typiquement fonctionner en IPv4 et


IPv6).
#
# TYPE DATABASE
USER
ADDRESS
METHOD
host
all
all
localhost
trust
# Permettre n'importe quel utilisateur de n'importe quel hte d'adresse IP
# 192.168.93.x de se connecter la base de donnes "postgres" sous le nom
# d'utilisateur qu'ident signale la connexion (gnralement le
# nom utilisateur du systme d'exploitation).
#
# TYPE DATABASE
USER
ADDRESS
METHOD
host
postgres
all
192.168.93.0/24
ident
# Permet un utilisateur de l'hte 192.168.12.10 de se connecter la base de
# donnes "postgres" si le mot de passe de l'utilisateur est correctement fourni.
#
# TYPE DATABASE
USER
ADDRESS
METHOD
host
postgres
all
192.168.12.10/32
md5
# Permet la connexion n'importe quel utilisateur depuis toutes les machines du
# domaine exemple.com n'importe quelle base de donnes si le mot de passe
# correct est fourni.
#
# TYPE DATABASE
USER
ADDRESS
METHOD
host
all
all
.exemple.com
md5
# Si aucune ligne "host" ne prcde, ces deux lignes rejettent toutes
# les connexions en provenance de 192.168.54.1 (puisque cette entre dclenche
# en premier), mais autorisent les connexions Kerberos 5 de n'importe o
# ailleurs sur l'Internet. Le masque zro signifie qu'aucun bit de l'ip de
# l'hte n'est considr, de sorte correspondre tous les htes.
#
# TYPE DATABASE
USER
ADDRESS
METHOD
host
all
all
192.168.54.1/32
reject
host
all
all
0.0.0.0/0
krb5
# Permettre tous les utilisateurs de se connecter depuis 192.168.x.x n'importe
# quelle base de donnes s'ils passent la verification d'identification. Si,
# par exemple, ident indique que l'utilisateur est "bryanh" et qu'il
# demande se connecter en tant qu'utilisateur PostgreSQL "guest1", la
# connexion n'est permise que s'il existe une entre dans pg_ident.conf pour la
# correspondance "omicron" disant que "bryanh" est autoris se connecter en
# tant que "guest1".
#
# TYPE DATABASE
USER
ADDRESS
METHOD
host
all
all
192.168.0.0/16
ident map=omicron
368

Authentification du client

# Si ces trois lignes traitent seules les connexions locales, elles


# n'autorisent les utilisateurs locaux qu' se connecter leur propre
# base de donnes (base ayant le mme nom que leur nom
# d'utilisateur) exception faite des administrateurs
# et des membres du rle "support" qui peuvent se connecter toutes les bases
# de donnes. Le fichier $PGDATA/admins contient une liste de noms
# d'administrateurs. Un mot de passe est requis dans tous les cas.
#
# TYPE DATABASE
USER
ADDRESS
METHOD
local
sameuser
all
md5
local
all
@admins
md5
local
all
+support
md5
# Les deux dernires lignes ci-dessus peuvent tre combines en une seule ligne :
local
all
@admins,+support
md5
# La colonne database peut aussi utiliser des listes et des noms de fichiers :
local
db1,db2,@demodbs all
md5

19.2. Correspondances d'utilisateurs


Lorsqu'on utilise une authentification externe telle que Ident ou GSSAPI, le nom de l'utilisateur du systme d'exploitation qui a
initi la connexion peut ne pas tre le mme que celui de l'utilisateur de la base laquelle il tente de se connecter. Dans ce cas, une
table de correspondance d'identits peut tre mise en place pour faire correspondre le nom d'utilisateur systme au nom
d'utilisateur base de donne. Pour utiliser une table de correspondance d'identits, spcifiez map=nom-table dans le champ options de pg_hba.conf. Cette option est supporte pour toutes les mthodes d'authentification qui reoivent des noms
d'utilisateurs externes. Comme diffrentes correspondances peuvent tre ncessaires pour diffrentes connexions, le nom de la
table utiliser doit tre spcifi dans le paramtre nom-table de pg_hba.conf afin d'indiquer quelle table utiliser pour
chaque connexion.
Les tables de correspondance de noms d'utilisateurs sont dfinies dans le fichier de correspondance, qui par dfaut s'appelle
pg_ident.conf et est stock dans le rpertoire de donnes du cluster. (Toutefois, il est possible de placer la table de correspondance ailleurs ; voir le paramtre de configuration ident_file.) Le fichier de table de correspondance contient des lignes de la
forme suivante :
nom-table nom-d-utilisateur-systeme nom-d-utilisateur-base
Les commentaires et les blancs sont traits de la mme faon que dans pg_hba.conf. Le nom-table est un nom arbitraire qui
sera utilis pour faire rfrence cette table de correspondance dans pg_hba.conf. Les deux autres champs spcifient un nom
d'utilisateur du systme d'exploitation et un nom d'utilisateur de la base de donnes correspondant. Le mme nomcorrespondance peut tre utilis de faon rpte pour indiquer plusieurs correspondances d'utilisateur dans la mme carte.
Il n'y a aucune restriction sur le nombre d'utilisateurs de base de donnes auxquels un utilisateur du systme d'exploitation peut
correspondre et vice-versa. Du coup, les entres dans une carte signifient que cet utilisateur du systme d'exploitation est autoris se connecter en tant que cet utilisateur de la base de donnes , plutt que supposer qu'ils sont quivalents. La connexion sera
autorise s'il existe une entre dans la carte qui correspond au nom d'utilisateur obtenu partir du systme d'authentification externe pour le nom de l'utilisateur de la base de donnes que l'utilisateur a indiqu.
Si le champ system-username commence avec un slash (/), le reste du champ est trait comme une expression rationnelle.
(Voir Section 9.7.3.1, Dtails des expressions rationnelles pour les dtails de la syntaxe des expressions rationnelles avec PostgreSQL.). L'expression rationnelle peut inclure une copie (sous-expression entre parenthses), qui peut ensuite tre rfrence
dans le champ database-username avec le joker \1 (antislash-un). Ceci permet la correspondance de plusieurs noms
d'utilisateurs sur une seule ligne, ce qui est particulirement utile pour les substitutions simples. Par exemple, ces entres
mymap
mymap

/^(.*)@mydomain\.com$
/^(.*)@otherdomain\.com$

\1
guest

supprimeront la partie domaine pour les utilisateurs de systme d'exploitation dont le nom finissent avec @mydomain.com, et
permettront aux utilisateurs dont le nom se termine avec @otherdomain.com de se connecter en tant que guest.

Astuce
Gardez en tte que, par dfaut, une expression rationnelle peut correspondre une petite partie d'une chane. Il est
369

Authentification du client

gnralement conseill d'utiliser les jokers ^ et $, comme indiqu dans l'exemple ci-dessus, pour forcer une correspondance sur le nom entier de l'utilisateur du systme d'exploitation.
Le fichier pg_ident.conf est lu au dmarrage et quand le processus principal du serveur reoit un signal SIGHUP. Si vous
ditez le fichier sur un systme en cours d'utilisation, vous devez notifier le postmaster (en utilisantpg_ctl reload ou kill
-HUP) pour lui faire relire le fichier.
Un fichier pg_ident.conf qui pourrait tre utilis avec le fichier pg_hba.conf de Exemple 19.1, Exemple d'entres de
pg_hba.conf est montr en Exemple 19.2, Un exemple de fichier pg_ident.conf . Dans cet exemple, toute personne
connecte sur une machine du rseau 192.168 qui n'a pas le nom d'utilisateur du systme d'exploitation bryanh, ann, ou robert verrait son accs refus. L'utilisateur Unix robert ne verrait son accs autoris que lorsqu'il essaye de se connecter en tant
qu'utilisateur PostgreSQL bob, pas en tant que robert ou qui que ce soit d'autre. ann ne serait autorise se connecter qu'en
tant que ann. L'utilisateur bryanh aurait le droit de se connecter soit en tant que bryanh, soit en tant que guest1.
Exemple 19.2. Un exemple de fichier pg_ident.conf

# MAPNAME

SYSTEM-USERNAME

PG-USERNAME

omicron
bryanh
bryanh
omicron
ann
ann
# bob has user name robert on these machines
omicron
robert
bob
# bryanh can also connect as guest1
omicron
bryanh
guest1

19.3. Mthodes d'authentification


Les sous-sections suivantes dcrivent les mthodes d'authentification en dtail.

19.3.1. Authentification trust


Quand l'authentification trust est utilise, PostgreSQL considre que quiconque peut se connecter au serveur est autoris
accder la base de donnes quel que soit le nom d'utilisateur de bases de donnes qu'il fournit (mme les noms des superutilisateurs). Les restrictions apportes dans les colonnes database et user continuent videmment de s'appliquer. Cette mthode ne doit tre utilise que si le systme assure un contrle adquat des connexions au serveur.
L'authentification trust est approprie et trs pratique pour les connexions locales sur une station de travail mono-utilisateur.
Elle n'est gnralement pas approprie en soi sur une machine multi-utilisateur. Cependant, trust peut tout de mme tre utilis
sur une machine multi-utilisateur, si l'accs au fichier socket de domaine Unix est restreint par les permissions du systme de fichiers. Pour ce faire, on peut positionner les paramtres de configuration unix_socket_permissions (et au besoin
unix_socket_group) comme cela est dcrit dans la Section 18.3, Connexions et authentification . On peut galement positionner le paramtre de configuration unix_socket_directory pour placer le fichier de socket dans un rpertoire l'accs
convenablement restreint.
Le rglage des droits du systme de fichiers n'a d'intrt que le cas de connexions par les sockets Unix. Les droits du systme de
fichiers ne restreignent pas les connexions TCP/IP locales. Ainsi, pour utiliser les droits du systme de fichiers pour assurer la scurit locale, il faut supprimer la ligne host ...127.0.0.1 ... de pg_hba.conf ou la modifier pour utiliser une mthode d'authentification diffrente de trust.
L'authentification trust n'est envisageable, pour les connexions TCP/IP, que si chaque utilisateur de chaque machine autorise
se connecter au serveur par les lignes trust du fichier pg_hba.conf est digne de confiance. Il est rarement raisonnable
d'utiliser trust pour les connexions autres que celles issues de localhost (127.0.0.1).

19.3.2. Authentification par mot de passe


Les mthodes fondes sur une authentification par mot de passe sont md5 et password. Ces mthodes fonctionnent de faon
analogue l'exception du mode d'envoi du mot de passe travers la connexion : respectivement, hachage MD5 et texte en clair.
S'il existe un risque d'attaque par interception (sniffing) des mots de passe, il est prfrable d'utiliser md5. L'utilisation de
password, en clair, est toujours viter quand c'est possible. Nanmoins, md5 ne peut pas tre utilis avec la fonctionnalit
db_user_namespace. Si la connexion est protge par un chiffrement SSL, alors password peut tre utilis avec sret (bien que
l'authentification par certificat SSL pourrait tre un meilleur choix s'il y a dpendance au sujet de l'utilisation de SSL).
370

Authentification du client

Les mots de passe PostgreSQL sont distincts des mots de passe du systme d'exploitation. Le mot de passe de chaque utilisateur
est enregistr dans le catalogue systme pg_authid. Ils peuvent tre grs avec les commandes SQL CREATE USER(7) et ALTER ROLE(7). Ainsi, par exemple, CREATE USER foo WITH PASSWORD 'secret';. Si aucun mot de passe n'est enregistr pour un utilisateur, le mot de passe enregistr est nul et l'authentification par mot de passe choue systmatiquement pour
cet utilisateur.

19.3.3. Authentification GSSAPI


GSSAPI est un protocole du standard de l'industrie pour l'authentification scurise dfinie dans RFC 2743. PostgreSQL supporte GSSAPI avec l'authentification Kerberos suivant la RFC 1964. GSSAPI fournit une authentification automatique
(single sign-on) pour les systmes qui le supportent. L'authentification elle-mme est scurise mais les donnes envoyes sur la
connexion seront en clair sauf si SSL est utilis.
Quand GSSAPI passe par Kerberos, il utilise un principal standard dans le format nomservice/nomhte@domaine.
Pour des informations sur les parties du principal et sur la faon de configurer les cls requises, voir Section 19.3.5,
Authentification Kerberos .
Le support de GSSAPI doit tre activ lors de la construction de PostgreSQL ; voir Chapitre 15, Procdure d'installation de
PostgreSQL du code source pour plus d'informations.
Les options de configuration suivantes sont supportes pour GSSAPI :
include_realm
Si configur 1, le nom du royaume provenant du principal de l'utilisateur authentifi est inclus dans le nom de l'utilisateur
systme qui est pass au systme de correspondance d'utilisateur (Section 19.2, Correspondances d'utilisateurs ). Ceci est
utile pour grer des utilisateurs provenant de plusieurs royaumes.
map
Permet la mise en correspondance entre les noms systme et base de donnes. Voir Section 19.2, Correspondances
d'utilisateurs pour plus de dtails. Pour un principal Kerberos username/hostbased@EXAMPLE.COM, le nom
d'utilisateur utilis pour la correspondance est nomutilisateur/hote si include_realm est dsactiv, et username/hostbased@EXAMPLE.COM si include_realm est activ.
krb_realm
Configure le royaume pour la correspondance du principal de l'utilisateur. Si ce paramtre est configur, seuls les utilisateurs
de ce royaume seront accepts. S'il n'est pas configur, les utilisateurs de tout royaume peuvent se connecter, condition que
la correspondance du nom de l'utilisateur est faite.

19.3.4. Authentification SSPI


SSPI est une technologie Windows pour l'authentification scurise avec single sign-on. PostgreSQL utilise SSPI dans un
mode de ngociation (negotiate) qui utilise Kerberos si possible et NTLM sinon. L'authentification SSPI ne fonctionne
que lorsque serveur et client utilisent Windows ou, sur les autres plateformes, quand GSSAPI est disponible.
Lorsque Kerberos est utilis, SSPI fonctionne de la mme faon que GSSAPI. Voir Section 19.3.3, Authentification
GSSAPI pour les dtails.
Les options de configuration suivantes sont supportes pour SSPI :
include_realm
Si configur 1, le nom du royaume provenant du principal de l'utilisateur authentifi est inclus dans le nom de l'utilisateur
systme qui est pass au systme de correspondance d'utilisateur (Section 19.2, Correspondances d'utilisateurs ). Ceci est
utile pour grer des utilisateurs provenant de plusieurs royaumes.
map
Permet la mise en correspondance entre les noms systme et base de donnes. Voir Section 19.2, Correspondances
d'utilisateurs pour plus de dtails.
krb_realm
Configure le royaume pour la correspondance du principal de l'utilisateur. Si ce paramtre est configur, seuls les utilisateurs
de ce royaume seront accepts. S'il n'est pas configur, les utilisateurs de tout royaume peuvent se connecter, condition que
la correspondance du nom de l'utilisateur est faite.

19.3.5. Authentification Kerberos


371

Authentification du client

Note
L'authentification Kerberos native est obsolte et ne doit tre utilise que pour assurer la compatibilit ascendante.
Les nouvelles installations et les mises jour utiliseront prfrentiellement le standard d'authentification de
l'industrie, GSSAPI (voir Section 19.3.3, Authentification GSSAPI ).
Kerberos est un systme d'authentification scurise de standard industriel destin l'informatique distribue sur un rseau public. La description de Kerberos dpasse les objectifs de ce document mme dans les gnralits, c'est assez complexe (bien
que puissant). La FAQ Kerberos ou la page Kerberos du MIT sont un bon point de dpart l'exploration. Il existe plusieurs
sources de distribution Kerberos. Kerberos fournit une authentification scurise mais ne chiffre pas les requtes ou les donnes passes sur le rseau ; pour cela, SSL doit tre utilis.
PostgreSQL supporte Kerberos version 5. Le support de Kerberos doit tre activ lors de la construction de PostgreSQL ; voir
le Chapitre 15, Procdure d'installation de PostgreSQL du code source pour plus d'informations.
PostgreSQL opre comme un service Kerberos normal. Le nom du service principal est nomservice/nomhte@domaine.
nomservice peut tre configur du ct serveur en utilisant le paramtre de configuration krb_srvname (voir aussi Section 31.1,
Fonctions de contrle de connexion la base de donnes ). La valeur par dfaut l'installation, postgres, peut tre modifie
lors de la construction avec ./configure --with-krb-srvnam=quelquechose. Dans la plupart des environnements, il
est inutile de modifier cette valeur. Nanmoins, cela devient ncessaire pour supporter plusieurs installations de PostgreSQL sur
le mme hte. Quelques implantations de Kerberos peuvent imposer un nom de service diffrent, comme Microsoft Active Directory qui rclame un nom du service en majuscules (POSTGRES).
nom_hote est le nom de l'hte pleinement qualifi (fully qualified host name) de la machine serveur. Le domaine du service
principal (client) est le domaine prfr du serveur.
Les principaux (clients) doivent contenir le nom de leur utilisateur PostgreSQL comme premier composant, nomutilisateurpg@domaine, par exemple. Sinon, vous pouvez utiliser une correspondance du nom d'utilisateur qui tablit la correspondance partir du premier composant du nom du principal vers le nom d'utilisateur de la base de donnes Par dfaut, le domaine du
client n'est pas vrifi par PostgreSQL. Si l'authentification inter-domaine (cross-realm) est active, on utilise le paramtre
krb_realm ou activer include_realm et utiliser la correspondance du nom d'utilisateur pour vrifier le royaume.
Le fichier de cls du serveur doit tre lisible (et de prfrence uniquement lisible) par le compte serveur PostgreSQL (voir aussi
la Section 17.1, Compte utilisateur PostgreSQL ). L'emplacement du fichier de cls est indiqu grce au paramtre de configuration krb_server_keyfile fourni l'excution. La valeur par dfaut est /etc/srvtab, si Kerberos 4 est utilis, et /
usr/local/pgsql/etc/krb5.keytab sinon (ou tout autre rpertoire indiqu comme sysconfdir la compilation).
Le fichier de cls est engendr par le logiciel Kerberos ; voir la documentation de Kerberos pour les dtails. L'exemple suivant
correspond des implantations de Kerberos 5 compatibles avec MIT :
kadmin% ank -randkey postgres/server.my.domain.org
kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org
Lors de la connexion la base de donnes, il faut s'assurer de possder un ticket pour le principal correspondant au nom
d'utilisateur de base de donnes souhait. Par exemple, pour le nom d'utilisateur PostgreSQL fred, le principal
fred@EXAMPLE.COM pourrait se connecter. Pour autoriser aussi le principal fred/users.example.com@EXAMPLE.COM,
utiliser une correspondance de nom d'utilisateur, comme dcrit dans Section 19.2, Correspondances d'utilisateurs .
Si mod_auth_kerb et mod_perl sont utiliss sur le serveur web Apache, AuthType KerberosV5SaveCredentials peut
tre utilis avec un script mod_perl. Cela fournit un accs sr aux bases de donnes, sans demander de mot de passe supplmentaire.
Les options de configuration suivantes sont supportes pour Kerberos :
map
Permet la mise en correspondance entre les noms systme et base de donnes. Voir Section 19.2, Correspondances
d'utilisateurs pour plus de dtails.
include_realm
Si configur 1, le nom du royaume provenant du principal de l'utilisateur authentifi est inclus dans le nom de l'utilisateur
systme qui est pass au systme de correspondance d'utilisateur (Section 19.2, Correspondances d'utilisateurs ). Ceci est
utile pour grer des utilisateurs provenant de plusieurs royaumes.
krb_realm
Configure le royaume pour la correspondance du principal de l'utilisateur. Si ce paramtre est configur, seuls les utilisateurs
de ce royaume seront accepts. S'il n'est pas configur, les utilisateurs de tout royaume peuvent se connecter, condition que
la correspondance du nom de l'utilisateur est faite.
372

Authentification du client

krb_server_hostname
Prcise le nom d'hte du service principal. Cela, combin avec krb_srvname, est utilis pour gnr le nom complet du
service principal, qui est krb_srvname/krb_server_hostname@REALM. S'il n'est pas renseign, la valeur par dfaut
est le nom d'hte du serveur.

19.3.6. Authentification fonde sur ident


La mthode d'authentification ident fonctionne en obtenant le nom de l'oprateur du systme depuis le serveur ident distant et en
l'appliquant comme nom de l'utilisateur de la base de donnes (et aprs une ventuelle mise en correspondance). Cette mthode
n'est supporte que pour les connexions TCP/IP.

Note
Lorsqu'ident est spcifi pour une connexion locale (c'est--dire non TCP/IP), l'authentification peer (voir Section 19.3.7, Peer Authentication ) lui est automatiquement substitue.
Les options de configuration suivantes sont supportes pour ident :
map
Permet la mise en correspondance entre les noms systme et base de donnes. Voir Section 19.2, Correspondances
d'utilisateurs pour plus de dtails.
Le protocole d'identification est dcrit dans la RFC 1413. Thoriquement, chaque systme d'exploitation de type Unix contient
un serveur ident qui coute par dfaut sur le port TCP 113. La fonctionnalit basique d'un serveur ident est de rpondre aux questions telles que : Quel utilisateur a initi la connexion qui sort du port X et se connecte mon port Y? . Puisque PostgreSQL
connat X et Y ds lors qu'une connexion physique est tablie, il peut interroger le serveur ident de l'hte du client qui se connecte
et peut ainsi thoriquement dterminer l'utilisateur du systme d'exploitation pour n'importe quelle connexion.
Le revers de cette procdure est qu'elle dpend de l'intgrit du client : si la machine cliente est douteuse ou compromise, un attaquant peut lancer n'importe quel programme sur le port 113 et retourner un nom d'utilisateur de son choix. Cette mthode
d'authentification n'est, par consquent, approprie que dans le cas de rseaux ferms dans lesquels chaque machine cliente est
soumise un contrle strict et dans lesquels les administrateurs systme et de bases de donnes oprent en troite collaboration.
En d'autres mots, il faut pouvoir faire confiance la machine hbergeant le serveur d'identification. Cet avertissement doit tre
gard l'esprit :
Le protocole d'identification n'a pas vocation tre un protocole d'autorisation ou de contrle d'accs.
RFC 1413
Certains serveurs ident ont une option non standard qui chiffre le nom de l'utilisateur retourn l'aide d'une cl connue du seul administrateur de la machine dont mane la connexion. Cette option ne doit pas tre employe lorsque le serveur ident est utilis
avec PostgreSQL car PostgreSQL n'a aucun moyen de dchiffrer la chane renvoye pour dterminer le nom rel de
l'utilisateur.

19.3.7. Peer Authentication


La mthode d'authentification peer utilise les services du systme d'exploitation afin d'obtenir le nom de l'oprateur ayant lanc la
commande client de connexion et l'utilise (aprs une ventuelle mise en correspondance) comme nom d'utilisateur de la base de
donnes. Cette mthode n'est supporte que pour les connexions locales.
Les options de configuration suivantes sont supportes pour l'authentification peer :
map
Autorise la mise en correspondance entre le nom d'utilisateur fourni par le systme d'exploitation et le nom d'utilisateur pour
la base de donnes. Voir Section 19.2, Correspondances d'utilisateurs pour plus de dtails.
L'authentification peer n'est disponible que sur les systmes d'exploitation fournissant la fonction getpeereid(), le paramtre
SO_PEERCRED pour les sockets ou un mcanisme similaire. Actuellement, cela inclut Linux, la plupart des variantes BSD (et
donc Mac OS X), ainsi que Solaris.

19.3.8. Authentification LDAP


Ce mcanisme d'authentification opre de faon similaire password ceci prs qu'il utilise LDAP comme mthode de vrifi373

Authentification du client

cation des mots de passe. LDAP n'est utilis que pour valider les paires nom d'utilisateur/mot de passe. De ce fait, pour pouvoir
utiliser LDAP comme mthode d'authentification, l'utilisateur doit pralablement exister dans la base.
L'authentification LDAP peut oprer en deux modes. Dans le premier mode, le serveur fera un bind sur le nom distingu
comme prfixe nom_utilisateur suffixe. Typiquement, le paramtre prefix est utilis pour spcifier cn= ou DOMAIN\ dans un environnement Active Directory. suffix est utilis pour spcifier le reste du DN dans un environnement autre
qu'Active Directory.
Dans le second mode, le serveur commence un bind sur le rpertoire LDAP avec un nom d'utilisateur et un mot de passe fixs,
qu'il indique ldapbinddn et ldapbindpasswd. Il ralise une recherche de l'utilisateur en essayant de se connecter la base
de donnes. Si aucun utilisateur et aucun mot de passe n'est configur, un bind anonyme sera tent sur le rpertoire. La recherche sera ralise sur le sous-arbre sur ldapbasedn, et essaiera une correspondance exacte de l'attribut indiqu par ldapsearchattribute. Si aucun attribut n'est indiqu, l'attribut uid sera utilis. Une fois que l'utilisateur a t trouv lors de cette
recherche, le serveur se dconnecte et effectue un nouveau bind au rpertoire en tant que cet utilisateur, en utilisant le mot de
passe indiqu par le client pour vrifier que la chane de connexion est correcte. Cette mthode permet une plus grande flexibilit
sur l'emplacement des objets utilisateurs dans le rpertoire mais demandera deux connexions au serveur LDAP.
Les options de configuration suivantes sont supportes pour LDAP :
ldapserver
Noms ou adresses IP des serveurs LDAP auxquels se connecter. Plusieurs serveurs peuvent tre indiqus, en les sparant par
des espaces.
ldapport
Numro de port du serveur LDAP auquel se connecter. Si aucun port n'est spcifi, le port par dfaut de la bibliothque
LDAP sera utilis.
ldaptls
Positionnez 1 pour que la connexion entre PostgreSQL et le serveur LDAP utilise du chiffrage TLS. Notez que ceci ne
chiffre que le trafic jusqu'au serveur LDAP -- la connexion vers le client peut toujours ne pas tre chiffre sauf si SSL est utilis.
ldapprefix
Chane prfixer au nom de l'utilisateur pour former le DN utilis comme lien lors d'une simple authentification bind.
ldapsuffix
Chane suffixer au nom de l'utilisateur pour former le DN utilis comme lien lors d'une simple authentification bind.
ldapbasedn
Racine DN pour commencer la recherche de l'utilisateur lors d'une authentification search+bind.
ldapbinddn
DN de l'utilisateur pour se lier au rpertoire avec lequel effectuer la recherche lors d'une authentification search+bind.
ldapbindpasswd
Mot de passe de l'utilisateur pour se lier au rpertoire avec lequel effectuer la recherche lors d'une authentification
search+bind.
ldapsearchattribute
Attribut faire correspondre au nom d'utilisateur dans la recherche lors d'une authentification search+bind.

Note
Comme LDAP utilise souvent des virgules et des espaces pour sparer les diffrentes parties d'un DN, il est souvent ncessaire d'utiliser des paramtres entours de guillements durant le paramtrage des options LDAP, comme
par exemple :
ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example,
dc=net"

19.3.9. Authentification RADIUS


Cette mthode d'authentification opre de faon similaire password sauf qu'il existe la mthode RADIUS pour la vrification
du mot de passe. RADIUS est seulement utilis pour valider des pairs nom utilisateur / mot de passe. Du coup, l'utilisateur doit dj exister dans la base de donnes avant que RADIUS puisse tre utilis pour l'authentification.

374

Authentification du client

Lors de l'utilisation de l'authentification RADIUS, un message de demande d'accs (Access Request) sera envoy au serveur RADIUS configur. Cette demande sera du type authentification seule (Authenticate Only) et incluera les paramtres pour
le nom de l'utilisateur, son mot de passe (chiffr) et un identifiant NAS (NAS Identifier). La demande sera chiffre en utilisant un secret partag avec le serveur. Le serveur RADIUS rpondre au serveur soit la russite (Access Accept) soit l'chec
(Access Reject) de l'accs. Il n'y a pas de support des comptes RADIUS.
Les options de configuration suivantes sont supportes par RADIUS :
radiusserver
Le nom ou l'adresse IP sur serveur RADIUS pour l'authentification. Ce paramtre est requis.
radiussecret
Le secret partag utilis lors de discussions scurises avec le serveur RADIUS. Il doit y avoir exactement la mme valeur sur
le serveur PostgreSQL et sur le serveur RADIUS. Il est recommand d'utiliser une chane d'au moins 16 caractres. Ce paramtre est requis.

Note
Le vecteur de chiffrement utilis sera un chiffrement fort seulement si PostgreSQL a t compil avec le
support d'OpenSSL. Dans les autres cas, la transmission au serveur RADIUS peut seulement tre considre
comme cach, et non pas scuris, et des mesures de scurit externes doivent tre appliques si ncessaire.
radiusport
Le numro de port sur le serveur RADIUS pour la connexion. Si aucun port n'est indiqu, le port par dfaut, 1812, sera utilis.
radiusidentifier
La chane utilise comme identifiant NAS (NAS Identifier) dans les demandes RADIUS. Ce paramtre peut tre utilis
comme second paramtre identifiant par exemple l'utilisateur de bases de donnes pour la connexion. C'est utilisable pour des
vrifications sur le serveur RADIUS. Si aucune identifiant n'est spcifi, la valeur par dfaut, postgresql, sera utilise.

19.3.10. Authentification de certificat


Cette mthode d'authentification utilise des clients SSL pour procder l'authentification. Elle n'est par consquent disponible que
pour les connexions SSL. Quand cette mthode est utilise, le serveur exigera que le client fournisse un certificat valide. Aucune
invite de saisie de mot de passe ne sera envoye au client. L'attribut cn (Common Name) du certificat sera compar au nom
d'utilisateur de base de donnes demand. S'ils correspondent, la connexion sera autorise. La correspondance des noms
d'utilisateurs peut tre utilis pour permettre au cn d'tre diffrent du nom d'utilisateur de la base de donnes.
Les options de configuration suivantes sont supportes pour l'authentification par certificat SSL :
map
Permet la correspondance entre les noms d'utilisateur systme et les noms d'utilisateurs de bases de donnes. Voir Section 19.2, Correspondances d'utilisateurs pour les dtails.

19.3.11. Authentification PAM


Ce mcanisme d'authentification fonctionne de faon similaire password ceci prs qu'il utilise PAM (Pluggable Authentication Modules) comme mthode d'authentification. Le nom du service PAM par dfaut est postgresql. PAM n'est utilis que
pour valider des paires nom utilisateur/mot de passe. De ce fait, avant de pouvoir utiliser PAM pour l'authentification, l'utilisateur
doit pralablement exister dans la base de donnes. Pour plus d'informations sur PAM, merci de lire la page Linux-PAM et la
page PAM Solaris.
Les options suivantes sont supportes pour PAM :
pamservice
Nom de service PAM.

Note
Si PAM est configur pour lire /etc/shadow, l'authentification choue car le serveur PostgreSQL est excut en
tant qu'utilisateur standard. Ce n'est toutefois pas un problme quand PAM est configur pour utiliser LDAP ou les
375

Authentification du client

autres mthodes d'authentification.

19.4. Problmes d'authentification


Les erreurs et problmes d'authentification se manifestent gnralement par des messages d'erreurs tels que ceux qui suivent.
FATAL: no pg_hba.conf entry for host "123.123.123.123", user "andym", database
"testdb"
ou, en franais,
FATAL: pas d'entre pg_hba.conf pour l'hte "123.123.123.123", utilisateur "andym",
base "testdb"
C'est le message le plus probable lorsque le contact peut tre tabli avec le serveur mais qu'il refuse de communiquer. Comme le
suggre le message, le serveur a refus la demande de connexion parce qu'il n'a trouv aucune entre correspondante dans son fichier de configuration pg_hba.conf.
FATAL:

password authentication failed for user "andym"

ou, en franais,
FATAL:

l'authentification par mot de passe a chou pour l'utilisateur "andym"

Les messages de ce type indiquent que le serveur a t contact et qu'il accepte la communication, mais pas avant que la mthode
d'authentification indique dans le fichier pg_hba.conf n'ait t franchie avec succs. Le mot de passe fourni, le logiciel
d'identification ou le logiciel Kerberos doivent tre vrifis en fonction du type d'authentification mentionn dans le message
d'erreur.
FATAL:

user "andym" does not exist

ou, en franais,
FATAL:

l'utilisateur "andym" n'existe pas

Le nom d'utilisateur indiqu n'a pas t trouv.


FATAL:

database "testdb" does not exist

ou, en franais,
FATAL:

la base "testdb" n'existe pas

La base de donnes utilise pour la tentative de connexion n'existe pas. Si aucune base n'est prcise, le nom de la base par dfaut
est le nom de l'utilisateur, ce qui peut tre appropri ou non.

Astuce
Les traces du serveur contiennent plus d'informations sur une erreur d'authentification que ce qui est rapport au
client. En cas de doute sur les raisons d'un chec, il peut s'avrer utile de les consulter.

376

Chapitre 20. Rles de la base de donnes


PostgreSQL gre les droits d'accs aux bases de donnes en utilisant le concept de rles. Un rle peut tre vu soit comme un
utilisateur de la base de donnes, soit comme un groupe d'utilisateurs de la base de donnes, suivant la faon dont le rle est
configur. Les rles peuvent possder des objets de la base de donnes (par exemple des tables) et peuvent affecter des droits sur
ces objets d'autres rles pour contrler qui a accs ces objets. De plus, il est possible de donner l'appartenance d'un rle un
autre rle, l'autorisant du coup utiliser les droits affects un autre rle.
Le concept des rles comprends les concepts des utilisateurs et des groupes . Dans les versions de PostgreSQL antrieures la 8.1, les utilisateurs et les groupes taient des types d'entit distincts mais, maintenant, ce ne sont que des rles. Tout
rle peut agir comme un utilisateur, un groupe ou les deux.
Ce chapitre dcrit comment crer et grer des rles. Section 5.6, Droits donne plus d'informations sur les effets des droits des
rles pour les diffrents objets de la base de donnes.

20.1. Rles de la base de donnes


Conceptuellement, les rles de la base sont totalement spars des utilisateurs du systme d'exploitation. En pratique, il peut tre
commode de maintenir une correspondance mais cela n'est pas requis. Les rles sont globaux toute une installation de groupe
de bases de donnes (et non individuelle pour chaque base). Pour crer un rle, utilisez la commande SQL CREATE ROLE(7) :
CREATE ROLE nom_utilisateur;
nom_utilisateur suit les rgles des identifiants SQL : soit sans guillemets et sans caractres spciaux, soit entre doubleguillemets (en pratique, vous voudrez surtout ajouter des options supplmentaires, comme LOGIN, cette commande. Vous
trouverez plus de dtails ci-dessous). Pour supprimer un rle existant, utilisez la commande analogue DROP ROLE(7) :
DROP ROLE nom_utilisateur;
Pour une certaine facilit d'utilisation, les programmes createuser(1) et dropuser(1) sont fournis comme emballage de ces commandes SQL et peuvent tre appels depuis la ligne de commande du shell :
createuser nom_utilisateur
dropuser nom_utilisateur
Pour dterminer l'ensemble des rles existants, examinez le catalogue systme pg_roles existant, par exemple
SELECT rolname FROM pg_roles;
La mta-commande \du du programme psql(1) est aussi utile pour lister les rles existants.
Afin d'amorcer le systme de base de donnes, un systme rcemment install contient toujours un rle prdfini. Ce rle est un
superutilisateur et aura par dfaut le mme nom que l'utilisateur du systme d'exploitation qui a initialis le groupe de bases de
donnes ( moins que cela ne soit modifi en lanant la commande initdb). Par habitude, ce rle sera nomm postgres. Pour
crer plus de rles, vous devez d'abord vous connecter en tant que ce rle initial.
Chaque connexion au serveur de la base de donnes est fait au nom d'un certain rle et ce rle dtermine les droits d'accs initiaux pour les commandes lances sur cette connexion. Le nom du rle employer pour une connexion une base particulire
est indiqu par le client initialisant la demande de connexion et ce, de la manire qui lui est propre. Par exemple, le programme
psql utilise l'option de ligne de commandes -U pour prciser sous quel rle il se connecte. Beaucoup d'applications (incluant
createuser et psql) utilisent par dfaut le nom courant de l'utilisateur du systme d'exploitation. Par consquence, il peut souvent tre pratique de maintenir une correspondance de nommage entre les rles et les utilisateurs du systme d'exploitation.
La configuration de l'authentification du client dtermine avec quel rle de la base, la connexion cliente donne se connectera,
comme cela est expliqu dans le Chapitre 19, Authentification du client (donc, un client n'est pas oblig de se connecter avec le
rle du mme nom que son nom d'utilisateur dans le systme d'exploitation ; de la mme faon que le nom de connexion d'un
utilisateur peut ne pas correspondre son vrai nom). Comme le rle dtermine l'ensemble des droits disponibles pour le client
connect, il est important de configurer soigneusement les droits quand un environnement multi-utilisateurs est mis en place.

20.2. Attributs des rles


Un rle de bases de donnes peut avoir un certain nombre d'attributs qui dfinissent ses droits et interagissent avec le systme
d'authentification du client.
droit de connexion
Seuls les rles disposant de l'attribut LOGIN peuvent tre utiliss comme nom de rle initial pour une connexion une base
377

Rles de la base de donnes

de donnes. Un rle avec l'attribut LOGIN peut tre considr de la mme faon qu'un utilisateur de la base de donnes .
Pour crer un rle disposant du droit de connexion, utilisez :
CREATE ROLE nom LOGIN;
CREATE USER nom;
(CREATE USER est quivalent CREATE ROLE sauf que CREATE USER utilise LOGIN par dfaut alors que
CREATE ROLE ne le fait pas)
statut de superutilisateur
Les superutilisateurs ne sont pas pris en compte dans les vrifications des droits, sauf le droit de connexion ou d'initier la rplication. Ceci est un droit dangereux et ne devrait pas tre utilis sans faire particulirement attention ; il est prfrable de
faire la grande majorit de votre travail avec un rle qui n'est pas superutilisateur. Pour crer un nouveau superutilisateur, utilisez CREATE ROLE nom SUPERUSER. Vous devez le faire en tant que superutilisateur. Crer un superutilisateur donne
par dfaut les droits pour initier une rplication en flux. Pour une scurit accrue, cela peut tre interdit en utilisant la requte
CREATE ROLE nom SUPERUSER NOREPLICATION.
cration de bases de donnes
Les droits de cration de bases doivent tre explicitement donnes un rle ( l'exception des super-utilisateurs qui passent au
travers de toute vrification de droits). Pour crer un tel rle, utilisez CREATE ROLE nom_utilisateur CREATEDB.
cration de rle
Un rle doit se voir explicitement donn le droit de crer plus de rles (sauf pour les superutilisateurs vu qu'ils ne sont pas
pris en compte lors des vrifications de droits). Pour crer un tel rle, utilisez CREATE ROLE nom CREATEROLE. Un rle
disposant du droit CREATEROLE peut aussi modifier et supprimer d'autres rles, ainsi que donner ou supprimer
l'appartenance ces rles. Nanmoins, pour crer, modifier, supprimer ou changer l'appartenance un rle superutilisateur, le
statut de superutilisateur est requis ; CREATEROLE n'est pas suffisant pour cela.
initiating replication
Un rle doit se voir explicitement donn le droit d'initier une rplication en flux. Un rle utilis pour la rplication en flux doit
toujours avoir le droit LOGIN. Pour crer un tel rle, utilisez CREATE ROLE nom REPLICATION LOGIN.
mot de passe
Un mot de passe est seulement significatif si la mthode d'authentification du client exige que le client fournisse un mot de
passe quand il se connecte la base. Les mthodes d'authentification par mot de passe et md5 utilisent des mots de
passe. Les mots de passe de la base de donnes ne sont pas les mmes que ceux du systme d'exploitation. Indiquez un mots
de passe lors de la cration d'un rle avec CREATE ROLE nom_utilisateur PASSWORD 'le_mot_de_passe'.
Les attributs d'un rle peuvent tre modifis aprs sa cration avec ALTER ROLE. Regardez les pages de rfrences de
CREATE ROLE(7) et de ALTER ROLE(7) pour plus de dtails.

Astuce
Une bonne pratique est de crer un rle qui dispose des droits CREATEDB et CREATEROLE mais qui n'est pas un
superutilisateur, et d'utiliser ce rle pour toute la gestion des bases de donnes et des rles. Cette approche vite les
dangers encourus en travaillant en tant que superutilisateur pour des tches qui n'ont pas besoin de cet tat.
Un rle peut aussi configurer ses options par dfaut pour de nombreux paramtres de configuration dcris dans le Chapitre 18,
Configuration du serveur. Par exemple, si, pour une raison ou une autre, vous voulez dsactiver les parcours d'index (conseil : ce
n'est pas une bonne ide) chaque fois que vous vous connectez, vous pouvez utiliser :
ALTER ROLE myname SET enable_indexscan TO off;
Cela sauve les paramtres (mais ne les applique pas immdiatement). Dans les connexions ultrieures de ce rle, c'est comme si
SET enable_indexscan TO off avait t appel juste avant le dmarrage de la session. Vous pouvez toujours modifier les
paramtres durant la session. Pour supprimer une configuration par dfaut spcifique un rle, utilisez ALTER ROLE
nom_utilisateur RESET nom_variable. Notez que les valeurs par dfaut spcifiques aux rles sans droit de connexion
(LOGIN) sont vraiment inutiles car ils ne seront jamais appels.

20.3. Appartenance d'un rle


Il est souvent intressant de grouper les utilisateurs pour faciliter la gestion des droits : de cette faon, les droits peuvent tre donns ou supprims pour tout un groupe. Dans PostgreSQL, ceci se fait en crant un rle reprsentant le groupe, puis en ajoutant
les rles utilisateurs individuels membres de ce groupe.
Pour configurer un rle en tant que groupe, crez tout d'abord le rle :
CREATE ROLE nom;
378

Rles de la base de donnes

Typiquement, un rle utilis en tant que groupe n'aura pas l'attribut LOGIN bien que vous puissiez le faire si vous le souhaitez.
Une fois que ce rle existe, vous pouvez lui ajouter et lui supprimer des membres en utilisant les commandes GRANT(7) et REVOKE(7) :
GRANT role_groupe TO role1, ... ;
REVOKE role_groupe FROM role1, ... ;
Vous pouvez aussi faire en sorte que d'autres rles groupes appartiennent ce groupe (car il n'y a pas rellement de distinction
entre les rles groupe et les rles non groupe). La base de donnes ne vous laissera pas configure des boucles circulaires
d'appartenance. De plus, il est interdit de faire en sorte qu'un membre appartienne PUBLIC.
Les membres d'un rle groupe peuvent utiliser les droits du rle de deux faons. Tout d'abord, chaque membre d'un groupe peut
excuter explicitement SET ROLE(7) pour devenir temporairement le rle groupe. Dans cet tat, la session de la base de donnes a accs aux droits du rle groupe plutt qu' ceux du rle de connexion original et tous les objets crs sont considrs
comme appartenant au rle groupe, et non pas au rle utilis lors de la connexion. Deuximement, les rles membres qui ont
l'attribut INHERIT peuvent utiliser automatiquement les droits des rles dont ils sont membres, ceci incluant les droits hrits par
ces rles. Comme exemple, supposons que nous avons lanc les commandes suivantes :
CREATE ROLE
CREATE ROLE
CREATE ROLE
GRANT admin
GRANT wheel

joe LOGIN INHERIT;


admin NOINHERIT;
wheel NOINHERIT;
TO joe;
TO admin;

Immdiatement aprs connexion en tant que joe, la session de la base de donnes peut utiliser les droits donns directement
joe ainsi que ceux donns admin parce que joe hrite des droits de admin. Nanmoins, les droits donns wheel ne
sont pas disponibles parce que, mme si joe est un membre indirect de wheel, l'appartenance se fait via admin qui dispose de
l'attribut NOINHERIT. Aprs :
SET ROLE admin;
la session aura la possibilit d'utiliser les droits donns admin mais n'aura plus accs ceux de joe. Aprs :
SET ROLE wheel;
la session pourra utiliser uniquement ceux de wheel, mais ni ceux de joe ni ceux de admin. L'tat du droit initial peut tre restaur avec une des instructions suivantes :
SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

Note
La commande SET ROLE autorisera toujours la slection de tout rle dont le rle de connexion est membre directement ou indirectement. Du coup, dans l'exemple prcdent, il n'est pas ncessaire de devenir admin pour devenir
wheel.

Note
Dans le standard SQL, il existe une distinction claire entre les utilisateurs et les rles. Les utilisateurs ne peuvent
pas hriter automatiquement alors que les rles le peuvent. Ce comportement est obtenu dans PostgreSQL en
donnant aux rles utiliss comme des rles SQL l'attribut INHERIT, mais en donnant aux rles utiliss en tant
qu'utilisateurs SQL l'attribut NOINHERIT. Nanmoins, par dfaut, PostgreSQL donne tous les rles l'attribut
INHERIT pour des raisons de compatibilit avec les versions prcdant la 8.1 dans lesquelles les utilisateurs
avaient toujours les droits des groupes dont ils taient membres.
Les attributs LOGIN, SUPERUSER, CREATEDB et CREATEROLE peuvent tre vus comme des droits spciaux qui ne sont jamais
hrits contrairement aux droits ordinaires sur les objets de la base. Vous devez rellement utiliser SET ROLE vers un rle spcifique pour avoir un de ces attributs et l'utiliser. Pour continuer avec l'exemple prcdent, nous pourrions trs bien choisir de donner les droits CREATEDB et CREATEROLE au rle admin. Puis, une session connecte en tant que le rle joe n'aurait pas ces
droits immdiatement, seulement aprs avoir excut SET ROLE admin.
Pour dtruire un rle groupe, utilisez DROP ROLE(7):
DROP ROLE nom;

379

Rles de la base de donnes

Toute appartenance ce rle est automatiquement supprime (mais les rles membres ne sont pas autrement affects). Notez
nanmoins que tous les objets dont le groupe tait propritaire doivent d'abord tre supprims ou raffects ; et tous les droits accords au rle groupe doivent tre supprims.

20.4. Scurit des fonctions et dclencheurs (triggers)


Les fonctions et les dclencheurs autorisent l'intrieur du serveur les utilisateurs insrer du code que d'autres utilisateurs
peuvent excuter sans en avoir l'intention. Par consquent, les deux mcanismes permettent aux utilisateurs d'utiliser un cheval
de Troie contre d'autres avec une relative facilit. La seule protection relle est d'effectuer un fort contrle sur ceux qui peuvent
dfinir des fonctions.
Les fonctions sont excutes l'intrieur du processus serveur avec les droits au niveau systme d'exploitation du dmon serveur
de la base de donnes. Si le langage de programmation utilis par la fonction autorise les accs mmoire non contrls, il est possible de modifier les structures de donnes internes du serveur. Du coup, parmi d'autres choses, de telles fonctions peuvent dpasser les contrles d'accs au systme. Les langages de fonctions qui permettent un tel accs sont considres sans confiance et
PostgreSQL autorise uniquement les superutilisateurs crire des fonctions dans ces langages.

380

Chapitre 21. Administration des bases de donnes


Chaque instance d'un serveur PostgreSQL gre une ou plusieurs bases de donnes. Les bases de donnes sont donc le niveau
hirarchique le plus lev pour organiser des objets SQL ( objets de base de donnes ). Ce chapitre dcrit les proprits des
bases de donnes et comment les crer, les administrer et les dtruire.

21.1. Aperu
Une base de donnes est un ensemble nomm d'objets SQL ( objets de base de donnes ). En gnral, chaque objet de base de
donnes (table, fonction etc.) appartient une et une seule base de donnes (nanmoins certains catalogues systme, par
exemple pg_database, appartiennent tout le groupe et sont accessibles depuis toutes les bases de donnes du groupe). Plus
prcisment, une base de donnes est une collection de schmas et les schmas contiennent les tables, fonctions, etc. Ainsi, la
hirarchie complte est : serveur, base de donnes, schma, table (ou un autre type d'objet, comme une fonction).
Lors de la connexion au serveur de bases de donnes, une application cliente doit spcifier dans sa requte de connexion la base
de donnes laquelle elle veut se connecter. Il n'est pas possible d'accder plus d'une base de donnes via la mme connexion.
Nanmoins une application n'est pas limite dans le nombre de connexions qu'elle tablit avec une ou plusieurs bases de donnes. Les bases de donnes sont spares physiquement et le contrle d'accs est gr au niveau de la connexion. Si une instance
de serveur PostgreSQL doit hberger des projets ou des utilisateurs censs rester spars et sans interaction, il est recommand de les rpartir sur plusieurs bases de donnes. Si les projets ou les utilisateurs sont relis et doivent pouvoir partager leurs ressources, alors ils devraient tre placs dans la mme base de donnes mais ventuellement dans des schmas diffrents. Les
schmas sont une structure purement logique et qui peut accder ce qui est gr par le systme des droits. Pour plus
d'informations sur la manipulation des schmas, voir la Section 5.7, Schmas .
Les bases de donnes sont cres avec la commande CREATE DATABASE (voir la Section 21.2, Cration d'une base de
donnes ) et dtruites avec la commande DROP DATABASE (voir la Section 21.5, Dtruire une base de donnes ). Pour
dterminer l'ensemble des bases de donnes existantes, examinez le catalogue systme pg_database, par exemple
SELECT datname FROM pg_database;
La mta-commande \l du programme psql(1) et l'option en ligne de commande -l sont aussi utiles pour afficher les bases de
donnes existantes.

Note
Le standard SQL appelle les bases de donnes des catalogues mais il n'y a aucune diffrence en pratique.

21.2. Cration d'une base de donnes


Pour pouvoir crer une base de donnes, il faut que le serveur PostgreSQL soit lanc (voir la Section 17.3, Lancer le serveur
de bases de donnes ).
Les bases de donnes sont cres l'aide de la commande SQL CREATE DATABASE(7) :
CREATE DATABASE nom;
ou nom suit les rgles habituelles pour les identifiants SQL. Le rle actuel devient automatiquement le propritaire de la nouvelle base de donnes. C'est au propritaire de la base de donnes qu'il revient de la supprimer par la suite (ce qui supprime aussi
tous les objets qu'elle contient, mme s'ils ont un propritaire diffrent).
La cration de bases de donnes est une opration protge. Voir la Section 20.2, Attributs des rles sur la manire
d'attribuer des droits.
Comme vous devez tre connect au serveur de base de donnes pour excuter la commande CREATE DATABASE, reste
savoir comment crer la premire base de donnes d'un site. La premire base de donnes est toujours cre par la commande
initdb quand l'aire de stockage des donnes est initialise (voir la Section 17.2, Crer un groupe de base de donnes ). Cette
base de donnes est appele postgres. Donc, pour crer la premire base de donnes ordinaire , vous pouvez vous connecter postgres.
Une deuxime base de donnes, template1, est aussi cre durant l'initialisation du cluster de bases de donnes. Quand une
nouvelle base de donnes est cre l'intrieur du groupe, template1 est gnralement clon. Cela signifie que tous les changements effectus sur template1 sont propags toutes les bases de donnes cres ultrieurement. cause de cela, vitez
de crer des objets dans template1 sauf si vous voulez les propager chaque nouvelle base de donnes cre. Pour plus de
dtails, voir la Section 21.3, Bases de donnes modles .
Pour plus de confort, il existe aussi un programme que vous pouvez excuter partir du shell pour crer de nouvelles bases de
381

Administration des bases de donnes

donnes, createdb.
createdb nom_base
createdb ne fait rien de magique. Il se connecte la base de donnes postgres et excute la commande CREATE DATABASE, exactement comme ci-dessus. La page de rfrence sur createdb(1) contient les dtails de son invocation. Notez que createdb sans aucun argument cre une base de donne portant le nom de l'utilisateur courant.

Note
Le Chapitre 19, Authentification du client contient des informations sur la manire de restreindre l'accs une base
de donnes.
Parfois, vous voulez crer une base de donnes pour quelqu'un d'autre. Ce rle doit devenir le propritaire de la nouvelle base de
donnes afin de pouvoir la configurer et l'administrer lui-mme. Pour faire ceci, utilisez l'une des commandes suivantes :
CREATE DATABASE nom_base OWNER nom_role;
dans l'environment SQL ou
createdb -O nom_role nom_base
dans le shell. Seul le super-utilisateur est autoris crer une base de donnes pour quelqu'un d'autre c'est--dire pour un rle dont
vous n'tes pas membre.

21.3. Bases de donnes modles


En fait, CREATE DATABASE fonctionne en copiant une base de donnes prexistante. Par dfaut, cette commande copie la
base de donnes systme standard template1. Ainsi, cette base de donnes est le modle partir duquel de nouvelles bases
de donnes sont cres. Si vous ajoutez des objets template1, ces objets seront copis dans les bases de donnes utilisateur
cres ultrieurement. Ce comportement permet d'apporter des modifications locales au jeu standard d'objets des bases de donnes. Par exemple, si vous installez le langage de procdures PL/Perl dans template1, celui-ci sera automatiquement disponible
dans les bases de donnes utilisateur sans qu'il soit ncessaire de faire quelque chose de spcial au moment o ces bases de donnes sont cres.
Il y a une seconde base de donnes systme standard appele template0. Cette base de donnes contient les mmes donnes
que le contenu initial de template1, c'est--dire seulement les objets standards prdfinis dans votre version de PostgreSQL.
template0 ne devrait jamais tre modifie aprs que le cluster des bases de donnes ait t cr. En indiquant CREATE DATABASE de copier template0 au lieu de template1, vous pouvez crer une base de donnes utilisateur vierge qui ne
contient aucun des ajouts locaux template1. Ceci est particulirement pratique quand on restaure une sauvegarde ralis avec
pg_dump : le script de dump devrait tre restaur dans une base de donnes vierge pour tre sr de recrer le contenu correct de
la base de donnes sauvegarde, sans survenue de conflits avec des objets qui auraient t ajouts template1.
Une autre raison habituelle de copier template0 au lieu de template1 est que les nouvelles options d'encodage et de locale
peuvent tre indiques lors de la copie de template0, alors qu'une copie de template1 doit utiliser les mme options. Ceci
est d au fait que template1 pourrait conteinur des donnes spcifiques l'encodage ou la locale alors que template0 n'est
pas modifiable.
Pour crer une base de donnes partir de template0, on crit :
CREATE DATABASE nom_base TEMPLATE template0;
dans l'environnement SQL ou
createdb -T template0 nom_base
dans le shell.
Il est possible de crer des bases de donnes modles supplmentaires et, vrai dire, on peut copier n'importe quelle base de donnes d'un cluster en la dsignant comme modle pour la commande CREATE DATABASE. Cependant, il importe de comprendre, que ceci n'est pas (encore) prendre comme une commande COPY DATABASE de porte gnrale. La principale
limitation est qu'aucune autre session ne peut tre connecte la base source tant qu'elle est copie. CREATE DATABASE
chouera si une autre connexion existe son lancement. Lors de l'opration de copie, les nouvelles connexions la base source
sont empches.
Deux drapeaux utiles existent dans pg_database pour chaque base de donnes : les colonnes datistemplate et datallowconn. datistemplate peut tre positionn vrai pour indiquer qu'une base de donnes a vocation servir de modle
CREATE DATABASE. Si ce drapeau est positionn vrai, la base de donnes peut tre clone par tout utilisateur ayant le droit
CREATEDB ; s'il est positionn faux, seuls les super-utilisateurs et le propritaire de la base de donnes peuvent la cloner. Si
382

Administration des bases de donnes

datallowconn est positionn faux, alors aucune nouvelle connexion cette base de donnes n'est autorise (mais les sessions
existantes ne sont pas termines simplement en positionnant ce drapeau faux). La base de donnes template0 est normalement marque datallowconn = false pour empcher qu'elle ne soit modifie. Aussi bien template0 que template1
devraient toujours tre marques datistemplate = true.

Note
template1 et template0 n'ont pas de statut particulier en dehors du fait que template1 est la base de donnes source par dfaut pour la commande CREATE DATABASE. Par exemple, on pourrait supprimer template1 et la recrer partir de template0 sans effet secondaire gnant. Ce procd peut tre utile lorsqu'on a
encombr template1 d'objets inutiles. (Pour supprimer template1, cette dernire doit avoir le statut
pg_database.datistemplate false.
La base de donnes postgres est aussi cr quand le groupe est initialis. Cette base de donnes a pour but de
devenir une base de donnes par dfaut pour la connexion des utilisateurs et applications. C'est une simple copie de
template1 et peut tre supprime et re-cre si ncessaire.

21.4. Configuration d'une base de donnes


Comme il est dit dans le Chapitre 18, Configuration du serveur, le serveur PostgreSQL offre un grand nombre de variables de
configuration chaud. Vous pouvez spcifier des valeurs par dfaut, valables pour une base de donnes particulire, pour nombre
de ces variables.
Par exemple, si pour une raison quelconque vous voulez dsactiver l'optimiseur GEQO pour une base de donne particulire, vous
n'avez pas besoin de le dsactiver pour toutes les bases de donnes ou de faire en sorte que tout client se connectant excute la
commande SET geqo TO off;. Pour appliquer ce rglage par dfaut la base de donnes en question, vous pouvez excuter
la commande :
ALTER DATABASE ma_base SET geqo TO off;
Cela sauvegarde le rglage (mais ne l'applique pas immdiatement). Lors des connexions ultrieures cette base de donnes, tout
se passe comme si la commande SET geqo TO off est excute juste avant de commencer la session. Notez que les utilisateurs peuvent cependant modifier ce rglage pendant la session ; il s'agit seulement d'un rglage par dfaut. Pour annuler un tel rglage par dfaut, utilisez ALTER DATABASE nom_base RESET nomvariable.

21.5. Dtruire une base de donnes


Les bases de donnes sont dtruites avec la commande DROP DATABASE(7) :
DROP DATABASE nom;
Seul le propritaire de la base de donnes ou un superutilisateur peut supprimer une base de donnes. Supprimer une base de donnes supprime tous les objets qui taient contenus dans la base. La destruction d'une base de donnes ne peut pas tre annule.
Vous ne pouvez pas excuter la commande DROP DATABASE en tant connect la base de donnes cible. Nanmoins, vous
pouvez tre connect une autre base de donnes, ceci incluant la base template1. template1 pourrait tre la seule option
pour supprimer la dernire base utilisateur d'un groupe donn.
Pour une certaine facilit, il existe un script shell qui supprime les bases de donnes, dropdb(1) :
dropdb nom_base
(Contrairement createdb, l'action par dfaut n'est pas de supprimer la base possdant le nom de l'utilisateur en cours.)

21.6. Tablespaces
Les tablespaces dans PostgreSQL permettent aux administrateurs de bases de donnes de dfinir l'emplacement dans le systme
de fichiers o seront stocks les fichiers reprsentant les objets de la base de donnes. Une fois cr, un tablespace peut tre rfrenc par son nom lors de la cration d'objets.
En utilisant les tablespaces, un administrateur peut contrler les emplacements sur le disque d'une installation PostgreSQL. Ceci
est utile dans au moins deux cas. Tout d'abord, si la partition ou le volume sur lequel le groupe a t initialis arrive court
d'espace disque mais ne peut pas tre tendu, un tablespace peut tre cr sur une partition diffrente et utilis jusqu' ce que le
systme soit reconfigur.
Deuximement, les tablespaces permettent un administrateur d'utiliser sa connaissance des objets de la base pour optimiser les
performances. Par exemple, un index qui est trs utilis peut tre plac sur un disque trs rapide et disponible, comme un priph383

Administration des bases de donnes

rique mmoire. En mme temps, une table stockant des donnes archives et peu utilise ou dont les performances ne portent pas
consquence pourra tre stocke sur un disque systme plus lent, moins cher.
Pour dfinir un tablespace, utilisez la commande CREATE TABLESPACE(7), par exemple :
CREATE TABLESPACE espace_rapide LOCATION '/mnt/sda1/postgresql/data';
L'emplacement doit tre un rpertoire existant, possd par l'utilisateur systme d'exploitation de PostgreSQL. Tous les objets
crs par la suite dans le tablespace seront stocks dans des fichiers contenus dans ce rpertoire.

Note
Il n'y a gnralement aucune raison de crer plus d'un tablespace sur un systme de fichiers logique car vous ne
pouvez pas contrler l'emplacement des fichiers individuels l'intrieur de ce systme de fichiers logique. Nanmoins, PostgreSQL ne vous impose aucune limitation et, en fait, il n'est pas directement conscient des limites du
systme de fichiers sur votre systme. Il stocke juste les fichiers dans les rpertoires que vous lui indiquez.
La cration d'un tablespace lui-mme doit tre fait en tant que superutilisateur de la base de donnes mais, aprs cela, vous pouvez
autoriser des utilisateurs standards de la base de donnes l'utiliser. Pour cela, donnez-leur le droit CREATE sur le tablespace.
Les tables, index et des bases de donnes entires peuvent tre affects des tablespaces particuliers. Pour cela, un utilisateur disposant du droit CREATE sur un tablespace donn doit passer le nom du tablespace comme paramtre de la commande. Par
exemple, ce qui suit cre une table dans le tablespace espace1 :
CREATE TABLE foo(i int) TABLESPACE espace1;
Autrement, utilisez le paramtre default_tablespace :
SET default_tablespace = espace1;
CREATE TABLE foo(i int);
Quand default_tablespace est configur avec autre chose qu'une chane vide, il fournit une clause TABLESPACE implicite
pour les commandes CREATE TABLE et CREATE INDEX qui n'en ont pas d'explicites.
Il existe aussi un paramtre temp_tablespaces, qui dtermine l'emplacement des tables et index temporaires, ainsi les fichiers temporaires qui sont utiliss pour le tri de gros ensembles de donnes. Ce paramtre peut aussi contenir une liste de tablespaces, plutt
qu'une seule, pour que la charge associe aux objets temporaires soit rpartie sur plusieurs tablespaces. Un membre de la liste est
pris au hasard chaque fois qu'un objet temporaire doit tre cr.
Le tablespace associ avec une base de donnes est utilis pour stocker les catalogues systme de la base. De plus, il est l'espace
par dfaut pour les tables, index et fichiers temporaires crs l'intrieur de cette base de donnes si aucune clause TABLESPACE
n'est fournie et qu'aucune slection n'est spcifie par default_tablespace ou temp_tablespaces (comme appropri).
Si une base de donnes est cre sans spcifier de tablespace pour elle, le serveur utilise le mme tablespace que celui de la base
modle utilise comme copie.
Deux tablespaces sont automatiquement crs lors de l'initialisation du cluster de bases de donnes. Le tablespace pg_global
est utilis pour les catalogues systme partags. Le tablespace pg_default est l'espace logique par dfaut des bases de donnes
template1 et template0 (et, du coup, sera le tablespace par dfaut pour les autres bases de donnes sauf en cas de surcharge
par une clause TABLESPACE dans CREATE DATABASE).
Une fois cr, un tablespace peut tre utilis partir de toute base de donnes si l'utilisateur le souhaitant dispose du droit ncessaire. Ceci signifie qu'un tablespace ne peut pas supprim tant que tous les objets de toutes les bases de donnes utilisant le tablespace n'ont pas t supprims.
Pour supprimer un tablespace vide, utilisez la commande DROP TABLESPACE(7).
Pour dterminer l'ensemble des tablespaces existants, examinez le catalogue systme pg_tablespace, par exemple
SELECT spcname FROM pg_tablespace;
La mtacommande \db du programme psql(1) est aussi utile pour afficher les tablespaces existants.
PostgreSQL utilise des liens symboliques pour simplifier l'implmentation des tablespaces. Ceci signifie que les tablespaces
peuvent tre utiliss seulement sur les systmes supportant les liens symboliques.
Le rpertoire $PGDATA/pg_tblspc contient des liens symboliques qui pointent vers chacun des tablespaces utilisateur dans le
groupe. Bien que non recommand, il est possible d'ajuster la configuration des tablespaces la main en redfinissant ces liens.
Deux avertissements : ne pas le faire alors que le serveur est en cours d'excution, mettez jour le catalogue pg_tablespace pour
indiquer les nouveaux emplacements (si vous ne le faites pas, pg_dump continuera afficher les anciens emplacements des tablespaces).
384

Chapitre 22. Localisation


Ce chapitre dcrit, du point de vue de l'administrateur, les fonctionnalits de rgionalisation (ou localisation) disponibles. PostgreSQL fournit deux approches diffrentes pour la gestion de la localisation :

l'utilisation des fonctionnalits de locales du systme d'exploitation pour l'ordonnancement du tri, le formatage des chiffres,
les messages traduits et autres aspects spcifiques la locale. Ces aspects sont couverts dans Section 22.1, Support des locales et Section 22.2, Support des collations . ;

la fourniture d'un certain nombre d'encodages diffrents pour permettre le stockage de texte dans toutes les langues et fournir
la traduction de l'encodage entre serveur et client. Ces aspects sont couverts dans Section 22.3, Support des jeux de caractres .

22.1. Support des locales


Le support des locales fait rfrence une application respectant les prfrences culturelles au regard des alphabets, du tri, du
format des nombres, etc. PostgreSQL utilise les possibilits offertes par C et POSIX du standard ISO fournies par le systme
d'exploitation du serveur. Pour plus d'informations, consulter la documentation du systme.

22.1.1. Aperu
Le support des locales est configur automatiquement lorsqu'un cluster de base de donnes est cr avec initdb. initdb initialise
le cluster avec la valeur des locales de son environnement d'excution par dfaut. Si le systme est dj paramtr pour utiliser
la locale souhaite pour le cluster, il n'y a donc rien d'autre faire. Si une locale diffrente est souhaite (ou que celle utilise par
le serveur n'est pas connue avec certitude), il est possible d'indiquer initdb la locale utiliser l'aide de l'option --locale.
Par exemple :
initdb --locale=sv_SE
Cet exemple pour les systmes Unix positionne la locale au sudois (sv) tel que parl en Sude (SE). Parmi les autres possibilits, on peut inclure en_US (l'anglais amricain) ou fr_CA (franais canadien). Si plus d'un ensemble de caractres peuvent tre
utiliss pour une locale, alors les spcifications peuvent prendre la forme langage_territoire.codeset. Par exemple,
fr_BE.UTF-8 reprsente la langue franaise telle qu'elle est parle en Belgique (BE), avec un encodage UTF-8.
Les locales disponibles et leurs noms dpendent de l'diteur du systme d'exploitation et de ce qui est install. Sur la plupart des
systmes Unix, la commande locale -a fournit la liste des locales disponibles. Windows utilise des noms de locale plus verbeux, comme German_Germany ou Swedish_Sweden.1252 mais le principe est le mme.
Il est parfois utile de mlanger les rgles de plusieurs locales, par exemple d'utiliser les rgles de tri anglais avec des messages
en espagnol. Pour cela, des sous-catgories de locales existent qui ne contrlent que certains aspects des rgles de localisation :
LC_COLLATE

Ordre de tri des chanes de caractres

LC_CTYPE

Classification de caractres (Qu'est-ce qu'une lettre ? La majuscule quivalente ?)

LC_MESSAGES

Langue des messages

LC_MONETARY

Formatage des valeurs montaires

LC_NUMERIC

Formatage des nombres

LC_TIME

Formatage des dates et heures

Les noms des catgories se traduisent par des options la commande initdb qui portent un nom identique pour surcharger le
choix de locale pour une catgorie donne. Par exemple, pour utiliser la locale franais canadien avec des rgles amricaines
pour le formatage montaire, on utilise initdb --locale=fr_CA --lc-monetary=en_US.
Pour bnficier d'un systme qui se comporte comme s'il ne disposait pas du support des locales, on utilise les locales spciales
C ou un quivalent, POSIX.
Certaines catgories de locales doivent avoir leur valeurs fixes lors de la cration de la base de donnes. Vous pouvez utiliser
des paramtrages diffrents pour chaque bases de donnes. En revanche, une fois que la base est cre, les paramtrages de locales ne peuvent plus tre modifis. LC_COLLATE et LC_CTYPE sont ces catgories. Elles affectent l'ordre de tri des index et
doivent donc rester inchanges, les index sur les colonnes de texte risquant d'tre corrompus dans le cas contraire. (Mais vous
pouvez lever ces restrictions sur les collations, comme cela est discut dans Section 22.2, Support des collations .) La valeur
par dfaut pour ces catgories est dtermine lors de l'excution d'initdb. Ces valeurs sont utilises quand de nouvelles bases de
385

Localisation

donnes sont cres, sauf si d'autres valeurs sont indiques avec la commande CREATE DATABASE.
Les autres catgories de locale peuvent tre modifies n'importe quel moment en configurant les variables d'environnement de
mme nom (voir la Section 18.11.2, Locale et formatage pour de plus amples dtails). Les valeurs par dfaut choisies par initdb sont en fait crites dans le fichier de configuration postgresql.conf pour servir de valeurs par dfaut au dmarrage du
serveur. Si ces dclarations sont supprimes du fichier postgresql.conf, le serveur hrite des paramtres de son environnement d'excution.
Le comportement des locales du serveur est dtermin par les variables d'environnement vues par le serveur, pas par celles de
l'environnement d'un quelconque client. Il est donc important de configurer les bons paramtres de locales avant le dmarrage du
serveur. Cela a pour consquence que, si les locales du client et du serveur diffrent, les messages peuvent apparatre dans des
langues diffrentes en fonction de leur provenance.

Note
Hriter la locale de l'environnement d'excution signifie, sur la plupart des systmes d'exploitation, la chose suivante : pour une catgorie de locales donne (l'ordonnancement par exemple) les variables d'environnement
LC_ALL, LC_COLLATE (ou la variable qui correspond la catgorie) et LANG sont consultes dans cet ordre jusqu' en trouver une qui est fixe. Si aucune de ces variables n'est fixe, c'est la locale par dfaut, C, qui est utilise.
Certaines bibliothques de localisation regardent aussi la variable d'environnement LANGUAGE qui surcharge tout
autre paramtre pour fixer la langue des messages. En cas de doute, lire la documentation du systme
d'exploitation, en particulier la partie concernant gettext.
Pour permettre la traduction des messages dans la langue prfre de l'utilisateur, NLS doit avoir t activ pendant la compilation
(configure --enable-nls). Tout autre support de la locale est construit automatiquement.

22.1.2. Comportement
Le paramtrage de la locale influence les fonctionnalits SQL suivantes :

l'ordre de tri dans les requtes utilisant ORDER BY ou les oprateurs de comparaison standards sur des donnes de type texte ;

Les fonctions upper, lower et initcap

Les oprateurs de correspondance de motifs (LIKE, SIMILAR TO et les expressions rationnelles de type POSIX); les locales
affectent aussi bien les oprateurs insensibles la classe et le classement des caractres par les expressions rationnelles portant
sur des caractres.

La famille de fonctions to_char.

La possibilit d'utiliser des index avec des clauses LIKE

Le support des locales autres que C ou POSIX dans PostgreSQL a pour inconvnient son impact sur les performances. Il ralentit
la gestion des caractres et empche l'utilisation des index ordinaires par LIKE. Pour cette raison, il est prfrable de n'utiliser les
locales qu'en cas de rel besoin.
Toutefois, pour permettre PostgreSQL d'utiliser des index avec les clauses LIKE et une locale diffrente de C, il existe plusieurs classes d'oprateurs personnalises. Elles permettent la cration d'un index qui ralise une stricte comparaison caractre par
caractre, ignorant les rgles de comparaison des locales. Se rfrer la Section 11.9, Classes et familles d'oprateurs pour
plus d'informations. Une autre possibilit est de crer des index en utilisant la collation C collation, comme cela est indiqu dans
Section 22.2, Support des collations .

22.1.3. Problmes
Si le support des locales ne fonctionne pas au regard des explications ci-dessus, il faut vrifier que le support des locales du systme d'exploitation est correctement configur. Pour vrifier les locales installes sur le systme, on peut utiliser la commande
locale -a, si elle est fournie avec le systme d'exploitation.
Il faut vrifier que PostgreSQL utilise effectivement la locale suppose. Les paramtres LC_COLLATE et LC_CTYPE sont dtermins lors de la cration de la base de donnes et ne peuvent pas tre modifis sauf en crant une nouvelle base de donnes.
D'autres paramtres de locale, y compris LC_MESSAGES et LC_MONETARY, sont dtermins initialement par l'environnement
dans lequel le serveur est lanc mais peuvent tre modifis pendant l'excution. Pour vrifier le paramtrage de la locale active on
utilise la commande SHOW.
Le rpertoire src/test/locale de la distribution source contient une srie de tests pour le support des locales dans PostgreSQL.
386

Localisation

Les applications clientes qui grent les erreurs en provenance du serveur par l'analyse du texte du message d'erreur vont certainement prouver des difficults lorsque les messages du serveur sont dans une langue diffrente. Les auteurs de telles applications
sont invits utiliser le schma de code d'erreur la place.
Le maintien de catalogues de traductions de messages ncessitent les efforts permanents de beaucoup de volontaires qui souhaitent
voir PostgreSQL parler correctement leur langue prfre. Si certains messages dans une langue ne sont pas disponibles ou pas
compltement traduits, toute aide est la bienvenue. Pour apporter son aide ce projet, consulter le Chapitre 48, Support natif des
langues ou crire la liste de diffusion des dveloppeurs.

22.2. Support des collations


Cette fonctionnalit permet de dfinir pour colonne, ou pour chaque requte, la collation utilise pour dterminer l'ordre de tri et le
classement des caractres. Cette fonctionnalit permet de lever la restriction sur les paramtres LC_COLLATE et LC_CTYPE
d'une base de donnes et qui ne pouvaient pas tre modifis aprs sa cration.

22.2.1. Concepts
Conceptuellement, toute expression d'un type de donne qui est collatable a une collation. (Les types de donnes intgrs qui supportent une collation sont text, varchar, et char. Les types de donnes dfinies par l'utilisateur peuvent aussi tre marques comme
supportant la collation, et bien entendu un domaine qui est dfini sur un type de donnes supportant la collation est, lui aussi, collationnable.) Si l'expression est une colonne, la collation de l'expression est dtermine par la collation de la colonne. Si
l'expression est une constante, la collation utilise sera la collation par dfaut du type de donnes de la constante. La collation
d'une expression plus complexe est dtermine partir des diffrentes collations de ses entres, comme cela est dcrit ci-dessous.
Une expression peut prendre la collation par dfaut, default , c'est dire la collation dfinie au niveau de la base de donnes. Il
est possible que la collation d'une expression soit indtermine. Dans un tel cas, les oprations de tri et les autres oprations qui
ont besoin de connatre la collation vont chouer.
Lorsque la base de donnes doit raliser un tri ou classement de caractres, alors elle utilisera la collation de l'expression en entre.
Ce cas se prsentera, par exemple, si vous employez la clause ORDER BY et des appels des fonctions ou des oprateurs tels que
<. La collation qui s'applique une clause ORDER BY est simplement la collation de la cl de tri. La collation qui s'applique pour
l'appel une fonction ou un oprateur est driv des arguments, comme dcrit plus bas. En plus de s'appliquer aux oprateurs de
comparaison, les collations sont galement prises en compte par les fonctions qui ralisent les conversions entre minuscules et majuscules, comme lower, upper et initcap; par les oprateurs de correspondance de motifs et par to_char et les fonctions
affilies.
Pour un appel une fonction ou un oprateur, la collation est dtermine partir de la collation des arguments qui sont passs
l'excution de l'opration. Si une expression voisine ncessite de connatre la collation de la fonction ou de l'oprateur, et si le type
de donnes du rsultat de l'appel possde une collation alors cette collation est interprte comme la collation de l'expression au
moment de l'analyse.
Le calcul de la collation d'une expression est ralis implicitement ou explicitement. Cette distinction affecte la faon dont les collations sont combines entre elles lorsque plusieurs collations diffrentes sont utilises dans une expression. La collation d'une expression peut tre dtermine explicitement par l'emploi de la clause COLLATE; dans les autres cas, la collation est dtermine de
manire implicite. Les rgles suivantes s'appliquent lorsque plusieurs collations doivent tre utilise en mme temps, par exemple
dans un appel une fonction, les rgles suivantes s'appliquent:
1. Si la collation d'une expression d'entre est dclare explicitement alors les collations dclare explicitement pour les autres expressions d'entres doivent tre les mmes, sinon une erreur est leve. Si une expression en entre contient une collation explicite, toutes les collations explicitement drives parmi les expressions en entre doivent tre identiques. Dans le cas contraire,
une erreur est renvoye. Si une collation drive explicitement est prsente, elle est le rsultat de la combinaison des collations.
2. Dans les autres cas, toutes les expressions en entre doivent avoir la mme collation, qu'elle soit implicite ou dtermine partir de la collation par dfaut. Si une collation est prsente, autre que celle par dfaut, elle est le rsultat de la combinaison des
collations. Sinon, le rsultat correspond la collation par dfaut.
3. S'il existe des collations implicites mais non par dfaut qui entrent en conflit avec les expressions en entre, alors la combinaison ne peut aboutir qu' une collation indtermine. Ce n'est pas une erreur sauf si la fonction appele requiert une application
de la collation. Dans ce cas, une erreur est renvoye lors de l'excution.
Par exemple, considrez la table dfinie de la faon suivante:
CREATE TABLE test1 (
a text COLLATE "de_DE",
b text COLLATE "es_ES",
...
387

Localisation

);
Ensuite, dans la requte
SELECT a < 'foo' FROM test1;
la comparaison < est ralise en tenant compte des rgles de la locale de_DE, parce que l'expression combine la collation calcule
implicitement avec la collation par dfaut. Mais, dans la requte
SELECT a < ('foo' COLLATE "fr_FR") FROM test1;
la comparaison est effectue en utilisant les rgles de la locale fr_FR, parce que l'utilisation explicite de cette locale prvaut sur
la locale dtermine de manire implicite. De plus, avec la requte
SELECT a < b FROM test1;
l'analyseur ne dispose pas des lments pour dterminer quelle collation employer, car les collations des colonnes a et b sont diffrentes. Comme l'oprateur < a besoin de connatre quelle locale utiliser, une erreur sera gnre. Cette erreur peut tre rsolue en
attachant une dclaration de collation explicite l'une ou l'autre des expressions d'entres, soit:
SELECT a < b COLLATE "de_DE" FROM test1;
ou de manire quivalente
SELECT a COLLATE "de_DE" < b FROM test1;
Toutefois, pour cas structurellement similaire comme
SELECT a || b FROM test1;
ne retournera pas d'erreur car l'oprateur || ne tient pas compte des collations: son rsultat sera le mme quel que soit la collation.
La collation qui est assigne une fonction ou une combinaisons d'un oprateur avec ses expressions d'entres s'appliquent galement au rsultat de la fonction ou de l'oprateur. Bien videmment, cela s'applique que si la fonction de l'oprateur dlivre un rsultat dans un type de donnes auquel la collation peut s'appliquer. Ainsi, dans la requte
SELECT * FROM test1 ORDER BY a || 'foo';
le tri sera ralis en fonction de rgles de la locale de_DE. Mais cette requte:
SELECT * FROM test1 ORDER BY a || b;
retournera une erreur car bien que l'oprateur || ne tienne pas compte des collations de ses expressions, la clause ORDER BY en
tient compte. Comme prcdemment, ce conflit peut tre rsolue par l'emploi d'une dclaration explicite de collation:
SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";

22.2.2. Gestion des collations


Une collation est un objet du catalogue dont le nom au niveau SQL correspond une locale du systme d'exploitation. Et plus particulirement, elle l'associe une combinaison de LC_COLLATE et LC_CTYPE. (Comme le nom le suggre, le principal objectif
d'une collation est de positionner LC_COLLATE qui contrle l'ordre de tri. Dans la pratique, il est trs rarement ncessaire de dfinir un paramtre LC_CTYPE diffrent de LC_COLLATE. De cette faon, il est plus facile de regrouper ces deux paramtres
dans un mme concept plutt que de crer une infrastructure diffrente simplement pour pouvoir positionner LC_CTYPE pour
chaque requte.) De la mme faon, une collation est lie un jeu de caractre (voir Section 22.3, Support des jeux de caractres ). Ainsi, plusieurs jeux de caractres peuvent utiliser une collation portant le mme nom.
Les collations nommes default, C, et POSIX sont disponibles sur toutes les plateformes. Les collations complmentaires seront ou non disponibles en fonction de leur support au niveau du systme d'exploitation. La collation default permet d'utiliser
les valeurs de LC_COLLATE et LC_CTYPE telles qu'elles ont t dfinies la cration de la base de donnes. Les collations C et
POSIX spcifie toute deux le comportement traditionnel C , dans lequel seules les caractres ASCII de A Z sont
388

Localisation

considres comme des lettres, et les tris sont ordonns strictement par valeur de l'octet du code caractre.
Si le systme d'exploitation permet un programme de supporter plusieurs locales (fonction newlocale et fonctions conjointes),
alors initdb peuplera le catalogue systme pg_collation en se basant sur toutes les locales qu'il trouve sur le systme
d'exploitation au moment de l'initialisation du cluster de bases de donnes. Par exemple, le systme d'exploitation peut offrir une
locale appele de_DE.utf8. initdb crera alors une collation nomme de_DE.utf8 pour le jeu de caractre UTF8 pour lequel
LC_COLLATE et LC_CTYPE sont positionns de_DE.utf8. Il crera aussi une collation dont le nom sera amput du tag
.utf8. Ainsi, vous pouvez utiliser cette collation sous le nom de_DE, dont l'criture est beaucoup plus facile et qui le rend
moins dpendant du jeu de caractres.Nanmoins, notez que le nommage de chaque collation collecte par initdb est dpendant de
la plateforme utilise.
Si vous souhaitez utiliser une collation dont les valeurs LC_COLLATE et LC_CTYPE diffrent, il vous faudra crer une nouvelle
collation par le biais de la commande CREATE COLLATION(7). Cette commande peut galement tre utilise pour crer une
nouvelle collation partir d'une collation existante, ce qui tre utile pour utiliser dans vos applications des collations dont le nom
est indpendant du systme d'exploitation.
Dans une mme base de donnes, seules les collations qui utilisent le jeu de caractres de la base de donnes sont pris en compte.
Les autres entres de pg_collation sont ignores. De cette faon, une collation dont le nom est tronqu, comme de_DE, sera
considr de manire unique au sein d'une mme base de donnes, mme si elle ne peut tre considre comme unique un niveau
plus global. L'utilisation de collations dont le nom est tronqu est d'ailleurs recommand car vous n'aurez pas besoin de le modifier si vous dcidez de changer le jeu de caractres de la base de donnes. Notez toutefois que les collations default, C, et POSIX peuvent tre utilis sans se soucier du jeu de caractres de la base de donnes.
PostgreSQL considre les collations comme des objets distincts et incompatibles entre eux, mme si elles possdent des proprits identiques. Ainsi, par exemle,
SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1;
va afficher une erreur alors que les collations C et POSIX possdent des proprits strictement identiques. Il n'est donc pas recommand de mlanger des collations dont le nom est complet avec des collations dont le nom l'est.

22.3. Support des jeux de caractres


Le support des jeux de caractres dans PostgreSQL permet d'insrer du texte dans diffrents jeux de caractres (aussi appels
encodages), dont ceux mono-octet tels que la srie ISO 8859 et ceux multi-octets tels que EUC (Extended Unix Code), UTF-8 ou
le codage interne Mule. Tous les jeux de caractres supports peuvent tre utiliss de faon transparente par les clients mais certains ne sont pas supports par le serveur (c'est--dire comme encodage du serveur). Le jeu de caractres par dfaut est slectionn
pendant l'initialisation du cluster de base de donnes avec initdb. Ce choix peut tre surcharg la cration de la base. Il est donc
possible de disposer de bases utilisant chacune un jeu de caractres diffrent.
Il existe, cependant une importante restriction : le jeu de caractre de la base de donnes doit tre compatible avec les variables
d'environnement LC_CTYPE (classification des caractres) et LC_COLLATE (ordre de tri des chanes) de la base de donnes.
Pour les locales C ou POSIX, tous les jeux de caractres sont autoriss, mais pour les locales, il n'y a qu'un seul jeux de caractres
qui fonctionne correctement. (Nanmoins, sur Windows, l'encodage UTF-8 peut tre utilis avec toute locale.)

22.3.1. Jeux de caractres supports


Le Tableau 22.1, Jeux de caractres de PostgreSQL prsente les jeux de caractres utilisables avec PostgreSQL.
Tableau 22.1. Jeux de caractres de PostgreSQL

Nom

Description

Langue

Ser- Octets/Caractre
veur
?

BIG5

Big Five

Chinois traditionnel

Non 1-2

EUC_CN

Code-CN Unix tendu

Chinois simplifi

Oui

1-3

EUC_JP

Code-JP Unix tendu

Japonais

Oui

1-3

EUC_JIS_2004

Code-JP Unix tendu, JIS X 0213

Japonais

Oui

1-3

EUC_KR

Code-KR Unix tendu

Coren

Oui

1-3

EUC_TW

Code-TW Unix tendu

Chinois traditionnel, tawanais Oui

1-3

GB18030

Standard national

Chinois

Non 1-2

GBK

Standard national tendu

Chinois simplifi

Non 1-2

389

Localisation

Nom

Description

Langue

Ser- Octets/Caractre
veur
?

ISO_8859_5

ISO 8859-5, ECMA 113

Latin/Cyrillique

Oui

ISO_8859_6

ISO 8859-6, ECMA 114

Latin/Arabe

Oui

ISO_8859_7

ISO 8859-7, ECMA 118

Latin/Grec

Oui

ISO_8859_8

ISO 8859-8, ECMA 121

Latin/Hbreu

Oui

JOHAB

JOHAB

Koren (Hangul)

Non 1-3

KOI8

KOI8-R(U)

Cyrillique

Oui

KOI8R

KOI8-R

Cyrillique (Russie)

Oui

KOI8U

KOI8-U

Cyrillique (Ukraine)

Oui

LATIN1

ISO 8859-1, ECMA 94

Europe de l'ouest

Oui

LATIN2

ISO 8859-2, ECMA 94

Europe centrale

Oui

LATIN3

ISO 8859-3, ECMA 94

Europe du sud

Oui

LATIN4

ISO 8859-4, ECMA 94

Europe du nord

Oui

LATIN5

ISO 8859-9, ECMA 128

Turque

Oui

LATIN6

ISO 8859-10, ECMA 144

Nordique

Oui

LATIN7

ISO 8859-13

Baltique

Oui

LATIN8

ISO 8859-14

Celtique

Oui

LATIN9

ISO 8859-15

ISO885915 avec l'Euro et Oui


les accents

LATIN10

ISO 8859-16, ASRO SR 14111

Roumain

Oui

MULE_INTERNAL

Code interne Mule

Emacs multi-langues

Oui

1-4

SJIS

Shift JIS

Japonais

Non 1-2

SHIFT_JIS_2004

Shift JIS, JIS X 0213

Japonais

Non 1-2

SQL_ASCII

non spcifi (voir le texte)

tout

Oui

UHC

Code unifi Hangul

Koren

Non 1-2

UTF8

Unicode, 8-bit

tous

Oui

1-4

WIN866

Windows CP866

Cyrillique

Oui

WIN874

Windows CP874

Thai

Oui

WIN1250

Windows CP1250

Europe centrale

Oui

WIN1251

Windows CP1251

Cyrillique

Oui

WIN1252

Windows CP1252

Europe de l'ouest

Oui

WIN1253

Windows CP1253

Grec

Oui

WIN1254

Windows CP1254

Turque

Oui

WIN1255

Windows CP1255

Hbreux

Oui

WIN1256

Windows CP1256

Arabe

Oui

WIN1257

Windows CP1257

Baltique

Oui

WIN1258

Windows CP1258

Vietnamien

Oui

Toutes les API clients ne supportent pas tous les jeux de caractres de la liste. Le pilote JDBC de PostgreSQL, par exemple, ne
supporte pas MULE_INTERNAL, LATIN6, LATIN8 et LATIN10.
SQL_ASCII se comporte de faon considrablement diffrente des autres valeurs. Quand le jeu de caractres du serveur est
SQL_ASCII, le serveur interprte les valeurs des octets 0-127 suivant le standard ASCII alors que les valeurs d'octets 128-255
sont considres comme des caractres non interprts. Aucune conversion de codage n'est effectue avec SQL_ASCII. De ce
fait, cette valeur ne dclare pas tant un encodage spcifique que l'ignorance de l'encodage. Dans la plupart des cas, si des donnes
non ASCII doivent tre traites, il est dconseill d'utiliser la valeur SQL_ASCII car PostgreSQL est alors incapable de
convertir ou de valider les caractres non ASCII.
390

Localisation

22.3.2. Choisir le jeu de caractres


initdb dfinit le jeu de caractres par dfaut (encodage) pour un cluster. Par exemple,
initdb -E EUC_JP
paramtre le jeu de caractres EUC_JP (Extended Unix Code for Japanese). L'option --encoding peut aussi tre utilise la
place de -E (options longues). Si aucune option -E ou --encoding n'est donne, initdb tente de dterminer l'encodage appropri en fonction de la locale indique ou de celle par dfaut.
Vous pouvez indiquer un encodage autre que celui par dfaut lors de la cration de la base de donnes, condition que l'encodage
soit compatible avec la locale slectionne :
createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean
Cela cre une base de donnes appele korean qui utilise le jeu de caractres EUC_KR, et la locale ko_KR. Un autre moyen de
raliser cela est d'utiliser la commande SQL suivante :
CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr'
LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;
Notez que les commandes ci-dessus prcisent de copier la base de donnes template0. Lors de la copie d'une autre base, les paramtres d'encodage et de locale ne peuvent pas tre modifis de ceux de la base de donnes source car cela pourrait corrompre les
donnes. Pour plus d'informations, voir Section 21.3, Bases de donnes modles .
L'encodage de la base de donnes est conserv dans le catalogue systme pg_database. Cela est visible l'aide de l'option -l
ou de la commande \l de psql.
$ psql -l

List of databases
Name | Owner | Encoding | Collation | Ctype | Access Privileges
-----------+----------+-----------+-------------+-------------+----------------------------clocaledb | hlinnaka | SQL_ASCII | C | C |
englishdb | hlinnaka | UTF8 | en_GB.UTF8 | en_GB.UTF8 |
japanese | hlinnaka | UTF8 | ja_JP.UTF8 | ja_JP.UTF8 |
korean | hlinnaka | EUC_KR | ko_KR.euckr | ko_KR.euckr |
postgres | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 |
template0 | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 |
{=c/hlinnaka,hlinnaka=CTc/hlinnaka}
template1 | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 |
{=c/hlinnaka,hlinnaka=CTc/hlinnaka}
(7 rows)

Important
Sur la plupart des systmes d'exploitation modernes, PostgreSQL peut dterminer le jeu de caractres impliqu
par la variable LC_CTYPE, et s'assure que l'encodage correspondant de la base de donnes est utilis. Sur les systmes plus anciens, il est de la responsabilit de l'utilisateur de s'assurer que l'encodage attendu par la locale est
bien utilis. Une erreur ce niveau risque fort de conduire un comportement trange des oprations lies la locale, tel le tri.
PostgreSQL autorise les superutilisateurs crer des bases de donnes avec le jeu de caractre SQL_ASCII
mme lorsque la variable LC_CTYPE n'est pas C ou POSIX. Comme indiqu plus haut, SQL_ASCII n'impose
aucun encodage particulier aux donnes stockes en base, ce qui rend ce paramtrage vulnrable aux comportements erratiques lors d'oprations lies la locale. Cette combinaison de paramtres est dprcie et pourrait un
jour tre interdite.

22.3.3. Conversion automatique d'encodage entre serveur et client


PostgreSQL automatise la conversion de jeux de caractres entre client et serveur pour certaines combinaisons de jeux de caractres. Les informations de conversion sont conserves dans le catalogue systme pg_conversion. PostgreSQL est livr avec
certaines conversions prdfinies, conversions listes dans le Tableau 22.2, Conversion de jeux de caractres client/serveur .
Une nouvelle conversion peut tre cre en utilisant la commande SQL CREATE CONVERSION.
Tableau 22.2. Conversion de jeux de caractres client/serveur

Jeu de caractres serveur

Jeux de caractres client disponibles

BIG5

non support comme encodage serveur


391

Localisation

Jeu de caractres serveur

Jeux de caractres client disponibles

EUC_CN

EUC_CN, MULE_INTERNAL, UTF8

EUC_JP

EUC_JP, MULE_INTERNAL, SJIS, UTF8

EUC_KR

EUC_KR, MULE_INTERNAL, UTF8

EUC_TW

EUC_TW, BIG5, MULE_INTERNAL, UTF8

GB18030

non support comme encodage serveur

GBK

non support comme encodage serveur

ISO_8859_5

ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866, WIN1251

ISO_8859_6

ISO_8859_6, UTF8

ISO_8859_7

ISO_8859_7, UTF8

ISO_8859_8

ISO_8859_8, UTF8

JOHAB

JOHAB, UTF8

KOI8R

KOI8R, ISO_8859_5, MULE_INTERNAL, UTF8, WIN866, WIN1251

KOI8U

KOI8U, UTF8

LATIN1

LATIN1, MULE_INTERNAL, UTF8

LATIN2

LATIN2, MULE_INTERNAL, UTF8, WIN1250

LATIN3

LATIN3, MULE_INTERNAL, UTF8

LATIN4

LATIN4, MULE_INTERNAL, UTF8

LATIN5

LATIN5, UTF8

LATIN6

LATIN6, UTF8

LATIN7

LATIN7, UTF8

LATIN8

LATIN8, UTF8

LATIN9

LATIN9, UTF8

LATIN10

LATIN10, UTF8

MULE_INTERNAL

MULE_INTERNAL, BIG5, EUC_CN, EUC_JP, EUC_KR, EUC_TW, ISO_8859_5, KOI8R,


LATIN1 vers LATIN4, SJIS, WIN866, WIN1250, WIN1251

SJIS

non support comme encodage serveur

SQL_ASCII

tous (aucune conversion n'est ralise)

UHC

non support comme encodage serveur

UTF8

tout encodage support

WIN866

WIN866, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN1251

WIN874

WIN874, UTF8

WIN1250

WIN1250, LATIN2, MULE_INTERNAL, UTF8

WIN1251

WIN1251, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866

WIN1252

WIN1252, UTF8

WIN1253

WIN1253, UTF8

WIN1254

WIN1254, UTF8

WIN1255

WIN1255, UTF8

WIN1256

WIN1256, UTF8

WIN1257

WIN1257, UTF8

WIN1258

WIN1258, UTF8

Pour activer la conversion automatique des jeux de caractres, il est ncessaire d'indiquer PostgreSQL le jeu de caractres
(encodage) souhait ct client. Il y a plusieurs faons de le faire :

en utilisant la commande \encoding dans psql. \encoding permet de changer l'encodage client la vole. Par exemple, pour
changer le codage en SJIS, taper :
392

Localisation

\encoding SJIS

la libpq (Section 31.9, Fonctions de contrle ) a des fonctions de contrle de l'encodage client ;

en utilisant SET client_encoding TO. L'encodage client peut tre fix avec la commande SQL suivante :
SET CLIENT_ENCODING TO 'valeur';
La syntaxe SQL plus standard SET NAMES peut galement tre utilise pour cela :
SET NAMES 'valeur';
Pour connatre l'encodage client courant :
SHOW client_encoding;
Pour revenir l'encodage par dfaut :
RESET client_encoding;

en utilisant PGCLIENTENCODING. Si la variable d'environnement PGCLIENTENCODING est dfinie dans l'environnement


client, l'encodage client est automatiquement slectionn lors de l'tablissement d'une connexion au serveur (cette variable
peut tre surcharge l'aide de toute autre mthode dcrite ci-dessus) ;

en utilisant la variable de configuration client_encoding. Si la variable client_encoding est dfinie, l'encodage client est
automatiquement slectionn lors de l'tablissement d'une connexion au serveur (cette variable peut tre surcharge l'aide de
toute autre mthode dcrite ci-dessus).

Si la conversion d'un caractre particulier n'est pas possible -- dans le cas d'encodages EUC_JP pour le serveur et LATIN1 pour le
client, et que certains caractres japonais renvoys n'ont pas de reprsentation en LATIN1 -- une erreur est remonte.
Si l'encodage client est dfini en tant que SQL_ASCII, la conversion de l'encodage est dsactive quelque soit celui du serveur.
Comme pour le serveur, SQL_ASCII est dconseill sauf ne travailler qu'avec des donnes ASCII.

22.3.4. Pour aller plus loin


Il existe quelques sources intressantes pour commencer matriser les diffrents jeux de caractres.
CJKV Information Processing: Chinese, Japanese, Korean & Vietnamese Computing
Contient des explications dtailles de EUC_JP, EUC_CN, EUC_KR, EUC_TW.
http://www.unicode.org/
Le site web du Unicode Consortium.
RFC 3629
UTF-8 (8-bit UCS/Unicode Transformation Format) est dfini ici.

393

Chapitre 23. Planifier les tches de maintenance


PostgreSQL, comme tout SGBD, requiert que certains tches soient ralises de faon rgulire pour atteindre les performances optimales. Ces tches sont requises, mais elles sont rptitives par nature et peuvent tre facilement automatises en utilisant des outils standard comme les scripts cron ou le Task Scheduler de Windows. La responsabilit de la mise en place de ces
scripts et du contrle de leur bon fonctionnement relve de l'administrateur de la base.
Une opration de maintenance vidente est la sauvegarde rgulire des donnes. Sans une sauvegarde rcente, il est impossible
de restaurer aprs un dommage grave (perte d'un disque, incendie, table supprime par erreur, etc.). Les mcanismes de sauvegarde et restauration disponibles dans PostgreSQL sont dtaills dans le Chapitre 24, Sauvegardes et restaurations.
L'autre tche primordiale est la ralisation priodique d'un vacuum , c'est dire faire le vide dans la base de donnes.
Cette opration est dtaille dans la Section 23.1, Nettoyages rguliers . La mise jour des statistiques utilises par le planificateur de requtes sera discute dans Section 23.1.3, Maintenir les statistiques du planificateur .
La gestion du fichier de traces mrite aussi une attention rgulire. Cela est dtaill dans la Section 23.3, Maintenance du fichier de traces .
check_postgres est disponible pour surveiller la sant des bases de donnes et pour rapporter des conditions inhabituelles.
check_postgres s'intgre bien avec Nagios et MRTG, mais il peut aussi fonctionner de faon autonome.
PostgreSQL demande peu de maintenance par rapport d'autres SGBD. Nanmoins, un suivi vigilant de ces tches participera beaucoup rendre le systme productif et agrable utiliser.

23.1. Nettoyages rguliers


Le SGBD PostgreSQL ncessite des oprations de maintenance priodiques, connues sous le nom de VACUUM. Pour de
nombreuses installations, il est suffisant de laisser travailler le dmon autovacuum, qui est dcrit dans Section 23.1.5, Le dmon auto-vacuum . En fonction des cas, les paramtres de cet outil peuvent tre optimiss pour obtenir de meilleurs rsultats.
Certains administrateurs de bases de donnes voudront suppler ou remplacer les activits du dmon avec une gestion manuelle
des commandes VACUUM, qui seront typiquement excutes suivant un planning par des scripts cron ou par le Task Scheduler. Pour configurer une gestion manuelle et correcte du VACUUM, il est essentiel de bien comprendre les quelques soussections suivantes. Les administrateurs qui se basent sur l'autovacuum peuvent toujours lire ces sections pour les aider comprendre et ajuster l'autovacuum.

23.1.1. Bases du VACUUM


La commande VACUUM(7) de PostgreSQL doit traiter chaque table rgulirement pour plusieurs raisons :
1. pour rcuprer ou r-utiliser l'espace disque occup par les lignes supprimes ou mises jour ;
2. pour mettre jour les statistiques utilises par l'optimiseur de PostgreSQL ;
3. pour prvenir la perte des donnes les plus anciennes cause d'un cycle de l'identifiant de transaction (XID).
Chacune de ces raisons impose de raliser des oprations VACUUM de diffrentes frquences et portes, comme expliqu dans
les sous-sections suivantes.
Il y a deux variantes de la commande VACUUM : VACUUM standard et VACUUM FULL. VACUUM FULL peut rcuprer
davantage d'espace disque mais s'excute beaucoup plus lentement. Par ailleurs, la forme standard de VACUUM peut s'excuter
en parallle avec les oprations de production des bases. Des commandes comme SELECT, INSERT, UPDATE et DELETE
continuent de fonctionner de faon normale, mais la dfinition d'une table ne peut tre modifie avec des commandes telles que
ALTER TABLE pendant le VACUUM. VACUUM FULL ncessite un verrou exclusif sur la table sur laquelle il travaille, et
ne peut donc pas tre excut en parallle avec une autre activit sur la table. En rgle gnrale, par consquent, les administrateurs doivent s'efforcer d'utiliser la commande standard VACUUM et viter VACUUM FULL.
VACUUM produit un nombre important d'entres/sorties, ce qui peut entraner de mauvaises performances pour les autres sessions actives. Des paramtres de configuration peuvent tre ajusts pour rduire l'impact d'une opration VACUUM en arrire
plan sur les performances -- voir Section 18.4.3, Report du VACUUM en fonction de son cot .

23.1.2. Rcuprer l'espace disque


Avec PostgreSQL, les versions primes des lignes ne sont pas immdiatement supprimes aprs une commande UPDATE
ou DELETE. Cette approche est ncessaire pour la consistance des accs concurrents (MVCC, voir le Chapitre 13, Contrle
d'accs simultan) : la version de la ligne ne doit pas tre supprime tant qu'elle est susceptible d'tre lue par une autre transaction. Mais finalement, une ligne qui est plus vieille que toutes les transactions en cours n'est plus utile du tout. La place qu'elle
394

Planifier les tches de maintenance

utilise doit tre rendue pour tre rutilise par d'autres lignes afin d'viter un accroissement constant, sans limite, du volume occup sur le disque. Cela est ralis en excutant VACUUM.
La forme standard de VACUUM limine les versions d'enregistrements morts dans les tables et les index, et marque l'espace
comme rutilisable. Nanmoins, il ne rend pas cet espace au systme d'exploitation, sauf dans le cas spcial o des pages la fin
d'une table deviennent totalement vides et qu'un verrou exclusif sur la table peut tre obtenu aisment. Par opposition, VACUUM
FULL compacte activement les tables en crivant une nouvelle version complte du fichier de la table, sans espace vide. Ceci rduit la taille de la table mais peut prendre beaucoup de temps. Cela requiert aussi un espace disque supplmentaire pour la nouvelle copie de la table jusqu' la fin de l'opration.
Le but habituel d'un vacuum rgulier est de lancer des VACUUM standard suffisamment souvent pour viter d'avoir recours
VACUUM FULL. Le dmon autovacuum essaie de fonctionner de cette faon, et n'excute jamais de VACUUM FULL. Avec
cette approche, l'ide directrice n'est pas de maintenir les tables leur taille minimale, mais de maintenir l'utilisation de l'espace
disque un niveau constant : chaque table occupe l'espace quivalent sa taille minimum plus la quantit d'espace consomme
entre deux vacuums. Bien que VACUUM FULL puisse tre utilis pour retourner une table sa taille minimale et rendre l'espace
disque au systme d'exploitation, cela ne sert pas grand chose, si cette table recommence grossir dans un futur proche. Par
consquent, cette approche s'appuyant sur des commandes VACUUM excutes intervalles modrment rapprochs est une
meilleure approche que d'excuter des VACUUM FULL espacs pour des tables mises jour de faon intensive.
Certains administrateurs prfrent planifier le passage de VACUUM eux-mmes, par exemple faire le travail de nuit, quand la
charge est faible. La difficult avec cette stratgie est que si une table a un pic d'activit de mise jour inattendu, elle peut grossir
au point qu'un VACUUM FULL soit vraiment ncessaire pour rcuprer l'espace. L'utilisation du dmon d'autovacuum minore ce
problme, puisque le dmon planifie les vacuum de faon dynamique, en rponse l'activit de mise jour. Il est peu raisonnable
de dsactiver totalement le dmon, sauf si l'activit de la base est extrmement prvisible. Un compromis possible est de rgler les
paramtres du dmon afin qu'il ne ragisse qu' une activit exceptionnellement lourde de mise jour, de sorte viter seulement
de perdre totalement le contrle de la volumtrie, tout en laissant les VACUUM planifis faire le gros du travail quand la charge
est normale.
Pour ceux qui n'utilisent pas autovacuum, une approche typique alternative est de planifier un VACUUM sur la base complte une
fois par jour lorsque l'utilisation n'est pas grande, avec en plus des oprations de VACUUM plus frquentes pour les tables trs
impactes par des mises jour, de la faon adquate. (Certaines installations avec normment de mises jour peuvent excuter
des VACUUM toutes les quelques minutes.) Lorsqu'il y a plusieurs bases dans un cluster, il faut penser excuter un VACUUM
sur chacune d'elles ; le programme vacuumdb(1) peut tre utile.

Astuce
Le VACUUM simple peut ne pas suffire quand une table contient un grand nombre d'enregistrements morts
comme consquence d'une mise jour ou suppression massive. Dans ce cas, s'il est ncessaire de rcuprer l'espace
disque gaspill, VACUUM FULL peut tre utilis, CLUSTER(7) ou une des variantes de ALTER TABLE(7). Ces
commandes crivent une nouvelle copie de la table et lui adjoignent de nouveaux index. Toutes ces options ncessitent un verrou exclusif. Elles utilisent aussi temporairement un espace disque supplmentaire, approximativement
gal la taille de la table, car les anciennes copies de la table et des index ne peuvent pas tre supprimes avant la
fin de l'opration.

Astuce
Si le contenu d'une table est supprim priodiquement, il est prfrable d'envisager l'utilisation de TRUNCATE(7),
plutt que DELETE suivi de VACUUM. TRUNCATE supprime le contenu entier de la table immdiatement sans
ncessiter de VACUUM ou VACUUM FULL pour rclamer l'espace disque maintenant inutilis. L'inconvnient
est la violation des smantiques MCC strictes.

23.1.3. Maintenir les statistiques du planificateur


L'optimiseur de requtes de PostgreSQL s'appuie sur des informations statistiques sur le contenu des tables dans l'optique de
produire des plans d'excutions efficaces pour les requtes. Ces statistiques sont collectes par la commande ANALYZE(7), qui
peut tre invoque seule ou comme option de VACUUM. Il est important d'avoir des statistiques relativement jour, ce qui permet d'viter les choix de mauvais plans d'excution, pnalisant les performances de la base.
Le dmon d'autovacuum, si activ, va automatiquement excuter des commandes ANALYZE chaque fois que le contenu d'une
table aura chang suffisamment. Toutefois, un administrateur peut prfrer se fier des oprations ANALYZE planifies manuellement, en particulier s'il est connu que l'activit de mise jour de la table n'a pas d'impact sur les statistiques des colonnes
intressantes . Le dmon planifie des ANALYZE uniquement en fonction du nombre d'enregistrements insrs, mis jour ou
supprims
395

Planifier les tches de maintenance

l'instar du nettoyage pour rcuprer l'espace, les statistiques doivent tre plus souvent collectes pour les tables intensment modifies que pour celles qui le sont moins. Mais mme si la table est trs modifie, il se peut que ces collectes soient inutiles si la
distribution probabiliste des donnes volue peu. Une rgle simple pour dcider est de voir comment voluent les valeurs minimum et maximum des donnes. Par exemple, une colonne de type timestamp qui contient la date de mise jour de la ligne aura
une valeur maximum en continuelle croissance au fur et mesure des modifications ; une telle colonne ncessitera plus de collectes statistiques qu'une colonne qui contient par exemple les URL des pages accdes sur un site web. La colonne qui contient
les URL peut trs bien tre aussi souvent modifie mais la distribution probabiliste des donnes changera certainement moins rapidement.
Il est possible d'excuter ANALYZE sur des tables spcifiques, voire des colonnes spcifiques ; il a donc toute flexibilit pour
mettre jour certaines statistiques plus souvent que les autres en fonction des besoins de l'application. Quoi qu'il en soit, dans la
pratique, il est gnralement mieux de simplement analyser la base entire car il s'agit d'une opration rapide. ANALYZE utilise
un systme d'chantillonage des lignes d'une table, ce qui lui vite de lire chaque ligne.

Astuce
Mme si il n'est pas trs productif de rgler prcisment la frquence de ANALYZE pour chaque colonne, il peut
tre intressant d'ajuster le niveau de dtail des statistiques collectes pour chaque colonne. Les colonnes trs utilises dans les clauses WHERE et dont la distribution n'est pas uniforme requirent des histogrammes plus prcis que
les autres colonnes. Voir ALTER TABLE SET STATISTICS, ou modifier les paramtres par dfaut de la base de
donnes en utilisant le paramtre de configuration default_statistics_target.
De plus, par dfaut, il existe peu d'informations sur la slectivit des fonctions. Nanmoins, si vous crez un index
qui utilise une fonction, des statistiques utiles seront rcupres de la fonction, ce qui peut grandement amliorer
les plans de requtes qui utilisent l'index.

23.1.4. viter les cycles des identifiants de transactions


Le mcanisme de contrle de concurrence multiversion (MVCC) de PostgreSQL s'appuie sur la possibilit de comparer des
identifiants de transactions (XID) ; c'est un nombre croissant : la version d'une ligne dont le XID d'insertion est suprieur au XID
de la transaction en cours est dans le futur et ne doit pas tre visible de la transaction courante. Comme les identifiants ont une
taille limite (32 bits), un groupe qui est en activit depuis longtemps (plus de 4 milliards de transactions) pourrait connatre un
cycle des identifiants de transaction : le XID reviendra 0 et soudainement les transactions du pass sembleront appartenir au futur - ce qui signifie qu'elles deviennent invisibles. En bref, perte de donnes totale. (En ralit, les donnes sont toujours l mais
c'est un pitre rconfort puisqu'elles resteront inaccessibles.) Pour viter ceci, il est ncessaire d'excuter un VACUUM sur chaque
table de chaque base au moins au moins une fois chaque milliard de transactions.
La raison pour laquelle un VACUUM priodique rsout le problme est que PostgreSQL rserve un ID de transaction spcial,
FrozenXID. Ce XID ne suit pas les rgles standards de comparaison des identifiants de transactions et est toujours considr
comme plus g que les XID normaux. Les XID normaux sont compars sur une base modulo-232. Cela signifie que pour chaque
XID normal, il y en a deux milliards qui sont plus vieux et deux milliards qui sont plus rcents. Une autre manire de le dire est
que l'ensemble de dfinition des XID est circulaire et sans limite. De plus, une ligne cre avec un XID normal donn, la version
de la ligne apparatra comme appartenant au pass pour les deux milliards de transactions qui suivront quelque soit le XID. Si la
ligne existe encore aprs deux milliards de transactions, elle apparatra soudainement comme appartenant au futur. Pour viter ceci, les versions trop anciennes doivent se voir affecter le XID FrozenXID avant d'atteindre le seuil fatidique des deux milliards
de transactions. Une fois qu'elles ont ce XID spcifique, elles appartiendront au pass pour toutes les transactions mme en cas de
cycle. Cette affectation des anciens XID est ralise par VACUUM.
vacuum_freeze_min_age contrle l'ge que doit avoir une valeur XID avant qu'elle soit remplace par FrozenXID. Les valeurs
plus importantes de ces deux paramtres prservent l'information transactionnelle plus longtemps alors que les valeurs plus petites
augmentent le nombre de transactions qui peuvent survenir avant un nouveau VACUUM de la table.
VACUUM ignore habituellement les pages qui n'ont pas de lignes mortes, mais ces pages pourraient toujours avoir des versions
de lignes avec d'anciennes valeurs XID. Pour s'assurer que tous les anciens XID ont t remplacs par FrozenXID, un parcours
complet de la table est ncessaire. vacuum_freeze_table_age contrle quand VACUUM fait cela : un parcours complet est forc si
la table n'a pas t parcourue compltement pendant vacuum_freeze_table_age - vacuum_freeze_min_age transactions. En le configurant zro, cela force VACUUM toujours parcourir toutes les pages, ignorant de ce fait la carte de visibilit.
Le temps maximum o une table peut rester sans VACUUM est de deux millions de transactions moins vacuum_freeze_min_age quand VACUUM a parcouru la table compltement pour la dernire fois. Si elle devait rester sans
VACUUM aprs cela, des pertes de donnes pourraient survenir. Pour s'assurer que cela n'arrive pas, autovacuum est appel sur
chaque table qui pourrait contenir des XID plus gs que ne l'indique le paramtre de configuration autovacuum_freeze_max_age.
(Ceci arrivera mme si autovacuum est dsactiv.)
Ceci implique que, si aucune opration de VACUUM n'est demande sur une table, l'autovacuum sera automatiquement dclench
396

Planifier les tches de maintenance

une fois toutes les autovacuum_freeze_max_age moins vacuum_freeze_min_age transactions. Pour les tables qui
ont rgulirement l'opration de VACUUM pour rclamer l'espace perdu, ceci a peu d'importance. Nanmoins, pour les tables statiques (ceci incluant les tables qui ont des INSERT mais pas d'UPDATE ou de DELETE), il n'est pas ncessaire d'excuter un
VACUUM pour rcuprer de la place et donc il peut tre utile d'essayer de maximiser l'interval entre les autovacuums forcs sur
de trs grosses tables statiques. videmment, vous pouvez le faire soit en augmentant autovacuum_freeze_max_age soit en
diminuant vacuum_freeze_min_age.
Le maximum efficace pour vacuum_freeze_table_age est 0.95 * autovacuum_freeze_max_age ; un paramtrage
plus haut que a sera limit ce maximum. Une valeur plus importante qie autovacuum_freeze_max_age n'aurait pas de
sens car un autovacuum de prservation contre la r-utilisation des identifiants de transactions serait dclench, et le multiplicateur
0,95 laisse un peu de place pour excuter un VACUUM manuel avant que cela ne survienne. Comme rgle d'or, vacuum_freeze_table_age devrait tre configur une valeur lgrement infrieure autovacuum_freeze_max_age, laissant
suffisamment d'espace pour qu'un VACUUM planifi rgulirement ou pour qu'un autovacuum dclench par des activits normales de suppression et de mise jour puissent tre activs pendant ce laps de temps. Le configurer de faon trop proche pourrait
dclencher des autovacuum de protection contre la r-utilisation des identifiants de transactions, mme si la table a t rcemment
l'objet d'un VACUUM pour rcuprer l'espace, alors que des valeurs basses amnent des parcours complets de table plus frquents.
Le seul inconvnient augmenter autovacuum_freeze_max_age (et vacuum_freeze_table_age avec elle) est que le
sous-rpertoire pg_clog du cluster prendre plus de place car il doit stocker le statut du COMMIT pour toutes les transactions depuis autovacuum_freeze_max_age. L'tat de COMMIT utilise deux bits par transaction, donc si autovacuum_freeze_max_age et vacuum_freeze_table_age ont une valeur maximum permise de deux milliards, pg_clog
peut grossir jusqu' la moiti d'un Go. Si c'est rien compar votre taille de base totale, configurer autovacuum_freeze_max_age son maximum permis est recommand. Sinon, le configurer suivant ce que vous voulez comme stockage maximum dans pg_clog. (La valeur par dfaut, 200 millions de transactions, se traduit en peu prs 50 Mo de stockage
dans pg_clog.)
Un inconvnient caus par la diminution de vacuum_freeze_min_age est que cela pourrait faire que VACUUM travaille
sans raison : modifier le XID de la ligne d'une table FrozenXID est une perte de temps si la ligne est modifie rapidement
aprs (ce qui fait qu'elle obtiendra un nouveau XID). Donc ce paramtre doit tre suffisamment important pour que les lignes ne
soient pas geles jusqu' ce qu'il soit pratiquement certain qu'elles ne seront plus modifies. Un autre inconvnient en diminuant ce
paramtre est que les dtails sur la transaction exacte qui a insr ou modifi une ligne seront perdus plus tt. Cette information est
quelque fois utile, particulirement lors d'une analyse de ce qui s'est mal pass sur une base aprs un problme. Pour ces deux raisons, baisser ce paramtre n'est pas recommand sauf pour les tables entirement statiques.
Pour tracer l'ge des plus anciens XID de la base, VACUUM stocke les statistiques sur XID dans les tables systmes pg_class et
pg_database. En particulier, la colonne relfrozenxid de la ligne pg_class d'une table contient le XID final du gel qui a t utilis par le dernier VACUUM pour cette table. Il est garanti que tous les XID plus anciens que ce XID ont t remplacs par FrozenXID pour cette table. De faon similaire, la colonne datfrozenxid de la ligne pg_database de la base est une limite infrieure des XID normaux apparaissant dans cette base -- c'est tout simplement le minimum des valeurs relfrozenxid par table
dans cette base. Pour examiner cette information, le plus simple est d'excuter des requtes comme :
SELECT c.oid::regclass as table_name,
greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age
FROM pg_class c
LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
WHERE c.relkind = 'r';
SELECT datname, age(datfrozenxid) FROM pg_database;
La colonne age mesure le nombre de transactions partir du XID final vers le XID de transaction en cours.
VACUUM parcourt habituellement seulement les pages qui ont t modifies depuis le dernier VACUUM mais relfrozenxid
peut seulement tre avanc quand la table est parcourue compltement. La table est parcourue entirement quand relfrozenxid est age de plus de vacuum_freeze_table_age transactions, quand l'option FREEZE de la commande VACUUM est
utilise ou quand toutes les pages se trouvent ncessiter un VACUUM pour supprimer les versions mortes des lignes. Aprs que
VACUUM ait parcouru la table complte age(relfrozenxid) devrait tre un peu plus grande que le paramtre vacuum_freeze_min_age qui a t utilis (la diffrence tant due au nombre de transactions dmarres depuis que VACUUM a
commenc son travail). Si aucun parcours de table complet ne se trouve excut via un VACUUM sur cette table, lorsque autovacuum_freeze_max_age est atteint, un autovacuum sera rapidement forc sur la table.
Si, pour une certaine raison, l'autovacuum choue effacer les anciens XID d'une table, le systme commencera mettre des
messages d'avertissement comme ceci quand les plus anciens XID de la base atteignent les 10 millions de transactions partir du
point de rinitialisation :
WARNING:

database "mydb" must be vacuumed within 177009986 transactions


397

Planifier les tches de maintenance

HINT:

To avoid a database shutdown, execute a database-wide VACUUM in "mydb".

(Une commande VACUUM manuelle devrait rsoudre le problme, comme suggr par l'indice ; mais notez que la commande
VACUUM doit tre excute par un superutilisateur, sinon elle chouera mettre jour les catalogues systmes et ne pourra donc
pas faire avancer le datfrozenxid de la base.) Si ces avertissements sont ignors, le systme s'arrtera et refusera de commencer toute nouvelle transaction ds qu'il n'en restera qu'un million avant la rinitialisation :
ERROR: database is not accepting commands to avoid wraparound data loss in database
"mydb"
HINT: Stop the postmaster and use a standalone backend to VACUUM in "mydb".
La marge de scurit de un million de transactions existe pour permettre l'administrateur de rcuprer ces donnes sans perte en
excutant manuellement les commandes VACUUM requises. Nanmoins, comme le systme n'excute pas de commandes tant
qu'il n'est pas sorti du mode d'arrt par scurit, la seule faon de le faire est de stopper le serveur et d'utiliser un moteur simple
utilisateur pour excuter le VACUUM. Le mode d'arrt n'est pas pris en compte par le moteur simple utilisateur. Voir la page de
rfrence de postgres(1) pour des dtails sur l'utilisation du moteur simple utilisateur.

23.1.5. Le dmon auto-vacuum


PostgreSQL dispose d'une fonctionnalit optionnelle mais hautement recommande appele autovacuum, dont le but est
d'automatiser l'excution des commandes VACUUM et ANALYZE . Une fois activ, autovacuum vrifie les tables ayant un
grand nombre de lignes insres, mises jour ou supprimes. Ces vrifications utilisent la fonctionnalit de rcupration de statistiques ; du coup, autovacuum ne peut pas tre utilis sauf si track_counts est configur true. Dans la configuration par dfaut,
l'autovacuum est activ et les paramtres lis sont correctement configurs.
Le dmon autovacuum est constitu de plusieurs processus. Un processus dmon permanent appel autovacuum launcher
(autrement dit le lanceur d'autovacuum) est en charge de lancer des processus travailleur (autovacuum worker) pour toutes les
bases de donnes. Le lanceur distribuera le travail dans le temps mais essaiera de lancer un nouveau travailleur sur chaque base de
donnes chaque autovacuum_naptime secondes. (Du coup, si l'installation a N bases de donnes, un nouveau autovacuum worker
sera lanc tous les autovacuum_naptime/N secondes.) Un maximum de autovacuum_max_workers processus autovacuum
worker est autoris s'excuter en mme temps. S'il y a plus de autovacuum_max_workers bases traiter, la prochaine base
de donnes sera traite ds qu'un autre travailleur a termin. Chaque processus travailleur vrifiera chaque table de leur base de
donnes et excutera un VACUUM et/ou un ANALYZE suivant les besoins.
Si plusieurs grosses tables deviennent toutes ligibles pour un VACUUM dans un court espace de temps, tous les processus travailleurs pourraient avoir excuter des VACUUM sur ces tables pendant un long moment. Ceci aura pour rsultat que d'autres
tables et d'autres bases de donnes ne pourront pas tre traites tant qu'un processus travailleur ne sera pas disponible. Il n'y a pas
de limite sur le nombre de processus travailleurs sur une seule base, mais ils essaient d'viter de rpter le travail qui a dj t fait
par d'autres. Notez que le nombre de processus travailleurs en cours d'excution n'est pas dcompt des limites max_connections
et superuser_reserved_connections.
Les tables dont la valeur de relfrozenxid est plus importante que autovacuum_freeze_max_age sont toujours l'objet d'un VACUUM (cela s'applique aux tables dont le 'freeze max age' a t modifi par les paramtres de stockage ; voyez plus bas). Sinon, si
le nombre de lignes obsoltes depuis le dernier VACUUM dpasse une limite de vacuum , la table bnficie d'un VACUUM.
La limite est dfinie ainsi :
limite du vacuum = limite de base du vacuum + facteur d'chelle du vacuum * nombre de
lignes
o la limite de base du vacuum est autovacuum_vacuum_threshold, le facteur d'chelle du vacuum est autovacuum_vacuum_scale_factor et le nombre de lignes est pg_class.reltuples. Le nombre de lignes obsoltes est obtenu partir du
rcuprateur de statistiques ; c'est un nombre peu prs prcis, mis jour aprs chaque instruction UPDATE et DELETE (il est
seulement peu prs prcis car certaines informations pourraient tre perdues en cas de grosse charge). Si la valeur de relfrozenxid pour la table est suprieure vacuum_freeze_table_age, la table complte est parcourue pour geler les anciennes
lignes et pour avancer relfrozenxid, sinon seules les pages qui ont t modifies depuis le dernier VACUUM sont parcourues
par l'opration de VACUUM.
Pour ANALYZE, une condition similaire est utilise : la limite, dfinie comme
limite du analyze = limite de base du analyze + facteur d'chelle du analyze * nombre
de lignes
est compare au nombre de lignes insres, mises jour et supprimes depuis le dernier ANALYZE.
Les tables temporaires ne peuvent pas tre accdes par l'autovacuum. Du coup, les oprations appropries de VACUUM et
d'ANALYZE devraient tre traites par des commandes SQL de session.
Les limites et facteurs d'chelle par dfaut sont pris dans postgresql.conf, mais il est possible de les surcharger table par
398

Planifier les tches de maintenance

table ; voir la section intitule Paramtres de stockage pour plus d'informations. Si un paramtre a t modifi via les paramtres de stockage, cette valeur est utilise ; sinon les paramtres globaux sont utiliss. Voir Section 18.10, Nettoyage
(vacuum) automatique pour plus d'informations sur les paramtres globaux.
En plus des valeurs de la limite de base et des facteurs d'chelle, il existe six autres paramtres autovacuum pouvant tre configurs pour chaque table via les paramtres de stockage. Le premier paramtre, autovacuum_enabled, peut tre configur
false pour instruire le dmon autovacuum de laisser cette table particulire. Dans ce cas, autovacuum touchera seulement la
table quand il devra le faire pour prvenir la rinitialisation de l'ID de transaction. Deux autres paramtres, le dlai du cot du VACUUM (autovacuum_vacuum_cost_delay) et la limite du cot du VACUUM (autovacuum_vacuum_cost_limit),
sont utiliss pour configurer des valeurs spcifiques aux tables pour la fonctionnalit de dlai de VACUUM bas sur le cot (voir
Section 18.4.3, Report du VACUUM en fonction de son cot ). autovacuum_freeze_min_age, autovacuum_freeze_max_age et autovacuum_freeze_table_age sont utiliss pour configurer des valeurs par table, respectivement vacuum_freeze_min_age, autovacuum_freeze_max_age et vacuum_freeze_table_age.
Lorsque plusieurs processus autovacuum sont en cours d'excution, la limite de cot est rpartie parmi tous les processus pour
que l'impact total sur le systme soit identique quelque soit le nombre de processus en cours d'excution.

23.2. R-indexation rgulire


Dans certains cas, reconstruire priodiquement les index par la commande REINDEX(7) vaut la peine.
Les pages de l'index B-tree, qui sont devenues compltement vides, sont rclames pour leur r-utilisation. Mais, il existe toujours
une possibilit d'utilisation peu efficace de l'espace : si, sur une page, seulement plusieurs cls d'index ont t supprims, la page
reste alloue. En consquence, si seulement quelques cls sont supprimes, vous devrez vous attendre ce que l'espace disque soit
trs mal utilis. Dans de tels cas, la rindexation priodique est recommande.
Le potentiel d'inflation des index qui ne sont pas des index B-tree n'a pas t particulirement analys. Surveiller priodiquement
la taille physique de ces index est une bonne ide.
De plus, pour les index B-tree, un index tout juste construit est lgrement plus rapide qu'un index qui a t mis jour plusieurs
fois parce que les pages adjacentes logiquement sont habituellement aussi physiquement adjacentes dans un index nouvellement
cr (cette considration ne s'applique pas aux index non B-tree). Il pourrait tre intressant de r-indexer priodiquement simplement pour amliorer la vitesse d'accs.

23.3. Maintenance du fichier de traces


Sauvegarder les journaux de trace du serveur de bases de donnes dans un fichier plutt que dans /dev/NULL est une bonne
ide. Les journaux sont d'une utilit incomparable lorsqu'arrive le moment o des problmes surviennent. Nanmoins, les journaux
ont tendance tre volumineux (tout spcialement des niveaux de dbogage importants) et vous ne voulez pas les sauvegarder
indfiniment. Vous avez besoin de faire une rotation des journaux pour que les nouveaux journaux sont commencs et que les
anciens soient supprims aprs une priode de temps raisonnable.
Si vous redirigez simplement stderr du postgres dans un fichier, vous aurez un journal des traces mais la seule faon de le tronquer sera d'arrter et de relancer le serveur. Ceci peut convenir si vous utilisez PostgreSQL dans un environnement de dveloppement mais peu de serveurs de production trouveraient ce comportement acceptable.
Une meilleure approche est d'envoyer la sortie stderr du serveur dans un programme de rotation de journaux. Il existe un programme interne de rotation que vous pouvez utiliser en configurant le paramtre logging_collector true dans postgresql.conf. Les paramtres de contrle pour ce programme sont dcrits dans Section 18.8.1, O tracer . Vous pouvez aussi utiliser cette approche pour capturer les donnes des journaux applicatifs dans un format CSV (valeurs spares par des virgules) lisible par une machine
Sinon, vous pourriez prfrer utiliser un programme externe de rotation de journaux si vous en utilisez dj un avec d'autres serveurs. Par exemple, l'outil rotatelogs inclus dans la distribution Apache peut tre utilis avec PostgreSQL. Pour cela, envoyez
via un tube la sortie stderr du serveur dans le programme dsir. Si vous lancez le serveur avec pg_ctl, alors stderr est dj
directement renvoy dans stdout, donc vous avez juste besoin d'ajouter la commande via un tube, par exemple :
pg_ctl start | rotatelogs /var/log/pgsql_log 86400
Une autre approche de production pour la gestion des journaux de trace est de les envoyer syslog et de laisser syslog grer la rotation des fichiers. Pour cela, initialisez le paramtre de configuration log_destination syslog (pour tracer uniquement
via syslog) dans postgresql.conf. Ensuite, vous pouvez envoyer un signal SIGHUP au dmon syslog quand vous voulez le
forcer crire dans un nouveau fichier. Si vous voulez automatiser la rotation des journaux, le programme logrotate peut tre
configur pour fonctionner avec les journaux de traces provenant de syslog.
Nanmoins, sur beaucoup de systmes, syslog n'est pas trs fiable, particulirement avec les messages trs gros ; il pourrait tronquer ou supprimer des messages au moment o vous en aurez le plus besoin. De plus, sur Linux, syslog synchronisera tout mes399

Planifier les tches de maintenance

sage sur disque, amenant des performances assez pauvres. (Vous pouvez utiliser un - au dbut du nom de fichier dans le fichier de configuration syslog pour dsactiver la synchronisation.)
Notez que toutes les solutions dcrites ci-dessus font attention lancer de nouveaux journaux de traces des intervalles configurables mais ils ne grent pas la suppression des vieux fichiers de traces, qui ne sont probablement plus trs utiles. Vous voudrez
probablement configurer un script pour supprimer priodiquement les anciens journaux. Une autre possibilit est de configurer le
programme de rotation pour que les anciens journaux de traces soient crass de faon cyclique.
pgFouine est un projet externe qui analyse les journaux applicatifs d'une faon trs pousse. check_postgres fournit des alertes Nagios quand des messages importants apparat dans les journaux applicatifs, mais dtecte aussi de nombreux autres cas.

400

Chapitre 24. Sauvegardes et restaurations


Comme tout ce qui contient des donnes importantes, les bases de donnes PostgreSQL doivent tre sauvegardes rgulirement. Bien que la procdure soit assez simple, il est important de comprendre les techniques et hypothses sous-jacentes.
Il y a trois approches fondamentalement diffrentes pour sauvegarder les donnes de PostgreSQL :

la sauvegarde SQL ;

la sauvegarde au niveau du systme de fichiers ;

l'archivage continu.

Chacune a ses avantages et ses inconvnients. Elles sont toutes analyses, chacune leur tour, dans les sections suivantes.

24.1. Sauvegarde SQL


Le principe est de produire un fichier texte de commandes SQL (appel fichier dump ), qui, si on le renvoie au serveur, recre une base de donnes identique celle sauvegarde. PostgreSQL propose pour cela le programme utilitaire pg_dump(1).
L'usage basique est :
pg_dump base_de_donnees > fichier_de_sortie
pg_dump crit son rsultat sur la sortie standard. Son utilit est explique plus loin.
pg_dump est un programme client PostgreSQL classique (mais plutt intelligent). Cela signifie que la sauvegarde peut tre effectue depuis n'importe quel ordinateur ayant accs la base. Mais pg_dump n'a pas de droits spciaux. Il doit, en particulier,
avoir accs en lecture toutes les tables sauvegarder, si bien qu'il doit tre lanc pratiquement toujours en tant que superutilisateur de la base.
Pour prciser le serveur de bases de donnes que pg_dump doit contacter, on utilise les options de ligne de commande -h
serveur et -p port. Le serveur par dfaut est le serveur local ou celui indiqu par la variable d'environnement PGHOST. De
la mme faon, le port par dfaut est indiqu par la variable d'environnement PGPORT ou, en son absence, par la valeur par dfaut prcise la compilation. Le serveur a normalement reu les mmes valeurs par dfaut la compilation.
Comme tout programme client PostgreSQL, pg_dump se connecte par dfaut avec l'utilisateur de base de donnes de mme
nom que l'utilisateur systme courant. L'utilisation de l'option -U ou de la variable d'environnement PGUSER permettent de modifier le comportement par dfaut. Les connexions de pg_dump sont soumises aux mcanismes normaux d'authentification des
programmes clients (dcrits dans le Chapitre 19, Authentification du client).
Un des gros avantages de pg_dump sur les autres mthodes de sauvegarde dcrites aprs est que la sortie de pg_dump peut tre
gnralement re-charge dans des versions plus rcentes de PostgreSQL, alors que les sauvegardes au niveau fichier et
l'archivage continu sont tous les deux trs spcifique la version du serveur pg_dump est aussi la seule mthode qui fonctionnera lors du transfert d'une base de donnes vers une machine d'une architecture diffrente (comme par exemple d'un serveur 32
bits un serveur 64 bits).
Les sauvegardes cres par pg_dump sont cohrentes, ce qui signifie que la sauvegarde reprsente une image de la base de donnes au moment o commence l'excution de pg_dump. pg_dump ne bloque pas les autres oprations sur la base lorsqu'il fonctionne (sauf celles qui ncessitent un verrou exclusif, comme la plupart des formes d'ALTER TABLE.)

Important
Si la base de donnes utilise les OID (par exemple en tant que cls trangres), il est impratif d'indiquer
pg_dump de sauvegarder aussi les OID. Pour cela, on utilise l'option -o sur la ligne de commande.

24.1.1. Restaurer la sauvegarde


Les fichiers texte crs par pg_dump peuvent tre lus par le programme psql. La syntaxe gnrale d'une commande de restauration est
psql base_de_donnees < fichier_d_entree
o fichier_d_entree est le fichier en sortie de la commande pg_dump. La base de donnes base_de_donnees n'est
pas cre par cette commande. Elle doit tre cre partir de template0 avant d'excuter psql (par exemple avec createdb
-T template0 base_de_donnees). psql propose des options similaires celles de pg_dump pour indiquer le serveur de
bases de donnes sur lequel se connecter et le nom d'utilisateur utiliser. La page de rfrence de psql(1) donne plus
d'informations.
401

Sauvegardes et restaurations

Tous les utilisateurs possdant des objets ou ayant certains droits sur les objets de la base sauvegarde doivent exister pralablement la restauration de la sauvegarde. S'ils n'existent pas, la restauration choue pour la cration des objets dont ils sont propritaires ou sur lesquels ils ont des droits (quelque fois, cela est souhaitable mais ce n'est habituellement pas le cas).
Par dfaut, le script psql continue de s'excuter aprs la dtection d'une erreur SQL. Vous pouvez excuter psql avec la variable
ON_ERROR_STOP configure pour modifier ce comportement. psql quitte alors avec un code d'erreur 3 si une erreur SQL survient :
psql --set ON_ERROR_STOP=on base_de_donnes < infile
Dans tous les cas, une sauvegarde partiellement restaure est obtenue. Si cela n'est pas souhaitable, il est possible d'indiquer que la
sauvegarde complte doit tre restaure au cours d'une transaction unique. De ce fait, soit la restauration est valide dans son ensemble, soit elle est entirement annule. Ce mode est choisi en passant l'option -1 ou --single-transaction en ligne de
commande psql. Dans ce mode, la plus petite erreur peut annuler une restauration en cours depuis plusieurs heures. Nanmoins,
c'est probablement prfrable au nettoyage manuel d'une base rendue complexe par une sauvegarde partiellement restaure.
La capacit de pg_dump et psql crire et lire dans des tubes permet de sauvegarder une base de donnes directement d'un serveur sur un autre. Par exemple :
pg_dump -h serveur1 base_de_donnees | psql -h serveur2 base_de_donnees

Important
Les fichiers de sauvegarde produits par pg_dump sont relatifs template0. Cela signifie que chaque langage,
procdure, etc. ajout template1 est aussi sauvegard par pg_dump. En consquence, si une base template1
modifie est utilise lors de la restauration, il faut crer la base vide partir de template0, comme dans
l'exemple plus haut.
Aprs la restauration d'une sauvegarde, il est conseill d'excuter ANALYZE(7) sur chaque base de donnes pour que l'optimiseur
de requtes dispose de statistiques utiles ; voir Section 23.1.3, Maintenir les statistiques du planificateur et Section 23.1.5, Le
dmon auto-vacuum pour plus d'informations. Pour plus de conseils sur le chargement efficace de grosses quantits de donnes
dans PostgreSQL, on peut se rfrer la Section 14.4, Remplir une base de donnes .

24.1.2. Utilisation de pg_dumpall


pg_dump ne sauvegarde qu'une seule base la fois, et ne sauvegarde pas les informations relatives aux rles et tablespaces (parce
que ceux-ci portent sur l'ensemble des bases du cluster, et non sur une base particulire). Pour permettre une sauvegarde aise de
tout le contenu d'un cluster, le programme pg_dumpall(1) est fourni. pg_dumpall sauvegarde toutes les bases de donnes d'un
cluster (ensemble des bases d'une instance) PostgreSQL et prserve les donnes communes au cluster, telles que les rles et tablespaces. L'utilisation basique de cette commande est :
pg_dumpall > fichier_de_sortie
Le fichier de sauvegarde rsultant peut tre restaur avec psql :
psql -f fichier_d_entree postgres
(N'importe quelle base de donnes peut tre utilise pour la connexion mais si le rechargement est excut sur un cluster vide, il
est prfrable d'utiliser postgres.) Il faut obligatoirement avoir le profil superutilisateur pour restaurer une sauvegarde faite
avec pg_dumpall, afin de pouvoir restaurer les informations sur les rles et les tablespaces. Si les tablespaces sont utiliss, il faut
s'assurer que leurs chemins sauvegards sont appropris la nouvelle installation.
pg_dumpall fonctionne en mettant des commandes pour recrer les rles, les tablespaces et les bases vides, puis en invoquant
pg_dump pour chaque base de donnes. Cela signifie que, bien que chaque base de donnes est cohrente en interne, les images
des diffrentes bases de donnes peuvent ne pas tre tout fait synchronises.

24.1.3. Grer les grosses bases de donnes


Certains systmes d'exploitation ont des limites sur la taille maximum des fichiers qui posent des problme lors de la cration de
gros fichiers de sauvegarde avec pg_dump. Heureusement, pg_dump peut crire sur la sortie standard, donc vous pouvez utiliser
les outils Unix standards pour contourner ce problme potentiel. Il existe plusieurs autres mthodes :
Compresser le fichier de sauvegarde. Tout programme de compression habituel est utilisable. Par exemple gzip :
pg_dump base_de_donnees | gzip > nom_fichier.gz
Pour restaurer :
gunzip -c nom_fichier.gz | psql base_de_donnees
402

Sauvegardes et restaurations

ou
cat nom_fichier.gz | gunzip | psql base_de_donnees
Couper le fichier avec split. La commande split permet de dcouper le fichier en fichiers plus petits, de taille acceptable par le
systme de fichiers sous-jacent. Par exemple, pour faire des morceaux de 1 Mo :
pg_dump base_de_donnees | split -b 1m - nom_fichier
Pour restaurer :
cat nom_fichier* | psql base_de_donnees
Utilisation du format de sauvegarde personnalis de pg_dump. Si PostgreSQL est install sur un systme o la bibliothque
de compression zlib est disponible, le format de sauvegarde personnalis peut tre utilis pour compresser les donnes la vole.
Pour les bases de donnes volumineuses, cela produit un fichier de sauvegarde d'une taille comparable celle du fichier produit
par gzip, avec l'avantage supplmentaire de permettre de restaurer des tables slectivement. La commande qui suit sauvegarde une
base de donnes en utilisant ce format de sauvegarde :
pg_dump -Fc base_de_donnees > nom_fichier
Le format de sauvegarde personnalis ne produit pas un script utilisable par psql. Ce script doit tre restaur avec pg_restore, par
exemple :
pg_restore -d nom_base nom_fichier
Voir les pages de rfrence de pg_dump(1) et pg_restore(1) pour plus de dtails.
Pour les trs grosses bases de donnes, il peut tre ncessaire de combiner split avec une des deux autres approches.

24.2. Sauvegarde de niveau systme de fichiers


Une autre stratgie de sauvegarde consiste copier les fichiers utiliss par PostgreSQL pour le stockage des donnes. Dans la
Section 17.2, Crer un groupe de base de donnes , l'emplacement de ces fichiers est prcis. N'importe quelle mthode de sauvegarde peut tre utilise, par exemple :
tar -cf sauvegarde.tar /usr/local/pgsql/data
Cependant, deux restrictions rendent cette mthode peu pratique ou en tout cas infrieure la mthode pg_dump.
1. Le serveur de base de donnes doit tre arrt pour obtenir une sauvegarde utilisable. Toutes les demi-mesures, comme la suppression des connexions, ne fonctionnent pas (principalement parce que tar et les outils similaires ne font pas une image atomique de l'tat du systme de fichiers, mais aussi cause du tampon interne du serveur). Les informations concernant la faon
d'arrter le serveur PostgreSQL se trouvent dans la Section 17.5, Arrter le serveur .
Le serveur doit galement tre arrt avant de restaurer les donnes.
2. Quiconque s'est aventur dans les dtails de l'organisation de la base de donnes peut tre tent de ne sauvegarder et restaurer
que certaines tables ou bases de donnes particulires. Ce n'est pas utilisable sans les fichiers journaux de validation
pg_clog/* qui contiennent l'tat de la validation de chaque transaction. Un fichier de table n'est utilisable qu'avec cette information. Bien entendu, il est impossible de ne restaurer qu'une table et les donnes pg_clog associes car cela rendrait toutes
les autres tables du serveur inutilisables. Les sauvegardes du systme de fichiers fonctionnent, de ce fait, uniquement pour les
sauvegardes et restaurations compltes d'un cluster de bases de donnes.
Une autre approche la sauvegarde du systme de fichiers consiste raliser une image cohrente (consistent snapshot) du rpertoire des donnes. Il faut pour cela que le systme de fichiers supporte cette fonctionnalit (et qu'il puisse lui tre fait
confiance). La procdure typique consiste raliser une image gele (frozen snapshot) du volume contenant la base de donnes et ensuite de copier entirement le rpertoire de donnes (pas seulement quelques parties, voir plus haut) de l'image sur un
priphrique de sauvegarde, puis de librer l'image gele. Ceci fonctionne mme si le serveur de la base de donnes est en cours
d'excution. Nanmoins, une telle sauvegarde copie les fichiers de la base de donnes dans un tat o le serveur n'est pas correctement arrt ; du coup, au lancement du serveur partir des donnes sauvegardes, PostgreSQL peut penser que le serveur s'est
stopp brutalement et rejouer les journaux WAL. Ce n'est pas un problme, mais il faut en tre conscient (et s'assurer d'inclure les
fichiers WAL dans la sauvegarde). Vous pouvez raliser un CHECKPOINT avant de prendre la sauvegarde pour rduire le temps
de restauration.
Si la base de donnes est rpartie sur plusieurs systmes de fichiers, il n'est peut-tre pas possible d'obtenir des images geles
exactement simultanes de tous les disques. Si les fichiers de donnes et les journaux WAL sont sur des disques diffrents, par
exemple, ou si les tablespaces sont sur des systmes de fichiers diffrents, une sauvegarde par images n'est probablement pas utili403

Sauvegardes et restaurations

sable parce que ces dernires doivent tre simultanes. La documentation du systme de fichiers doit tre tudie avec attention
avant de faire confiance la technique d'images cohrentes dans de telles situations.
S'il n'est pas possible d'obtenir des images simultanes, il est toujours possible d'teindre le serveur de bases de donnes suffisamment longtemps pour tablir toutes les images geles. Une autre possibilit est de faire une sauvegarde de la base en archivage
continu (Section 24.3.2, Raliser une sauvegarde de base ) parce que ces sauvegardes ne sont pas sensibles aux modifications
des fichiers pendant la sauvegarde. Cela n'impose d'activer l'archivage en continu que pendant la priode de sauvegarde ; la restauration est faite en utilisant la restauration d'archive en ligne (Section 24.3.3, Rcupration partir d'un archivage continu ).
Une autre option consiste utiliser rsync pour raliser une sauvegarde du systme de fichiers. Ceci se fait tout d'abord en lanant
rsync alors que le serveur de bases de donnes est en cours d'excution, puis en arrtant le serveur juste assez longtemps pour lancer rsync une deuxime fois. Le deuxime rsync est beaucoup plus rapide que le premier car il a relativement peu de donnes
transfrer et le rsultat final est cohrent, le serveur tant arrt. Cette mthode permet de raliser une sauvegarde du systme de
fichiers avec un arrt minimal.
Une sauvegarde des fichiers de donnes va tre gnralement plus volumineuse qu'une sauvegarde SQL. (pg_dump ne sauvegarde
pas le contenu des index, mais la commande pour les recrer). Cependant, une sauvegarde des fichiers de donnes peut tre plus
rapide.

24.3. Archivage continu et rcupration d'un instantan (PITR)


PostgreSQL maintient en permanence des journaux WAL (write ahead log) dans le sous-rpertoire pg_xlog/ du rpertoire de
donnes du cluster. Ces journaux enregistrent chaque modification effectue sur les fichiers de donnes des bases. Ils existent
principalement pour se prmunir des suites d'un arrt brutal : si le systme s'arrte brutalement, la base de donnes peut tre restaure dans un tat cohrent en rejouant les entres des journaux enregistres depuis le dernier point de vrification. Nanmoins, l'existence de ces journaux rend possible l'utilisation d'une troisime stratgie pour la sauvegarde des bases de donnes : la
combinaison d'une sauvegarde de niveau systme de fichiers avec la sauvegarde des fichiers WAL. Si la rcupration est ncessaire, la sauvegarde des fichiers est restaure, puis les fichiers WAL sauvegards sont rejous pour amener la sauvegarde jusqu'
la date actuelle. Cette approche est plus complexe administrer que toutes les autres approches mais elle apporte des bnfices significatifs :

Il n'est pas ncessaire de disposer d'une sauvegarde des fichiers parfaitement cohrente comme point de dpart. Toute incohrence dans la sauvegarde est corrige par la r-excution des journaux (ceci n'est pas significativement diffrent de ce qu'il se
passe lors d'une rcupration aprs un arrt brutal). La fonctionnalit d'image du systme de fichiers n'est alors pas ncessaire,
tar ou tout autre outil d'archivage est suffisant.

Puisqu'une longue squence de fichiers WAL peut tre assemble pour tre rejoue, une sauvegarde continue est obtenue en
continuant simplement archiver les fichiers WAL. C'est particulirement intressant pour les grosses bases de donnes dont
une sauvegarde complte frquente est difficilement ralisable.

Les entres WAL ne doivent pas obligatoirement tre rejoues intgralement. La r-excution peut tre stoppe en tout point,
tout en garantissant une image cohrente de la base de donnes telle qu'elle tait ce moment-l. Ainsi, cette technique autorise la rcupration d'un instantan (PITR) : il est possible de restaurer l'tat de la base de donnes telle qu'elle tait en tout
point dans le temps depuis la dernire sauvegarde de base.

Si la srie de fichiers WAL est fournie en continu une autre machine charge avec le mme fichier de sauvegarde de base, on
obtient un systme de reprise intermdiaire (warm standby) : tout moment, la deuxime machine peut tre monte et disposer d'une copie quasi-complte de la base de donnes.

Note
pg_dump et pg_dumpall ne font pas de sauvegardes au niveau systme de fichiers. Ce type de sauvegarde est qualifi de logique et ne contiennent pas suffisamment d'informations pour permettre le rejeu des journaux de transactions.
Tout comme la technique de sauvegarde standard du systme de fichiers, cette mthode ne supporte que la restauration d'un cluster de bases de donnes complet, pas d'un sous-ensemble. De plus, un espace d'archivage important est requis : la sauvegarde de la
base peut tre volumineuse et un systme trs utilis engendre un trafic WAL archiver de plusieurs Mo. Malgr tout, c'est la
technique de sauvegarde prfre dans de nombreuses situations o une haute fiabilit est requise.
Une rcupration fructueuse partir de l'archivage continu (aussi appel sauvegarde chaud par certains vendeurs de SGBD)
ncessite une squence ininterrompue de fichiers WAL archivs qui s'tend au moins jusqu'au point de dpart de la sauvegarde.
Pour commencer, il faut configurer et tester la procdure d'archivage des journaux WAL avant d'effectuer la premire sauvegarde
de base. C'est pourquoi la suite du document commence par prsenter les mcanismes d'archivage des fichiers WAL.
404

Sauvegardes et restaurations

24.3.1. Configurer l'archivage WAL


Au sens abstrait, un systme PostgreSQL fonctionnel produit une squence infinie d'enregistrements WAL. Le systme divise
physiquement cette squence en fichiers de segment WAL de 16 Mo chacun (en gnral, mais cette taille peut tre modifie lors
de la construction de PostgreSQL). Les fichiers segment reoivent des noms numriques pour reflter leur position dans la squence abstraite des WAL. Lorsque le systme n'utilise pas l'archivage des WAL, il ne cre que quelques fichiers segment, qu'il
recycle en renommant les fichiers devenus inutiles. Un fichier segment dont le contenu prcde le dernier point de vrification
est suppos inutile et peut tre recycl.
Lors de l'archivage des donnes WAL, le contenu de chaque fichier segment doit tre captur ds qu'il est rempli pour sauvegarder
les donnes ailleurs avant son recyclage. En fonction de l'application et du matriel disponible, sauvegarder les donnes
ailleurs peut se faire de plusieurs faons : les fichiers segment peuvent tre copis dans un rpertoire NFS mont sur une autre
machine, tre crits sur une cartouche (aprs s'tre assur qu'il existe un moyen d'identifier le nom d'origine de chaque fichier) ou
tre groups pour gravage sur un CD, ou toute autre chose. Pour fournir autant de flexibilit que possible l'administrateur de la
base de donnes, PostgreSQL essaie de ne faire aucune supposition sur la faon dont l'archivage est ralis. la place, PostgreSQL permet de prciser la commande shell excuter pour copier le fichier segment complet l'endroit dsir. La commande peut tre aussi simple qu'un cp ou impliquer un shell complexe -- c'est l'utilisateur qui dcide.
Pour activer l'archivage des journaux de transaction, on positionne le paramtre de configuration wal_level archive (ou
hot_standby), archive_mode on, et on prcise la commande shell utiliser dans le paramtre archive_command de la configuration. En fait, ces paramtres seront toujours placs dans le fichier postgresql.conf. Dans cette chane, un %p est remplac par le chemin absolu de l'archive alors qu'un %f n'est remplac que par le nom du fichier. (Le nom du chemin est relatif au rpertoire de travail du serveur, c'est--dire le rpertoire des donnes du cluster.) %% est utilis pour crire le caractre % dans la
commande. La commande la plus simple ressemble :
archive_command = 'test ! -f /mnt/serveur/repertoire_archive/%f && cp %p
/mnt/serveur/repertoire_archive/%f' # Unix
archive_command = 'copy "%p" "C:\\serveur\\repertoire_archive\\%f"' # Windows
qui copie les segments WAL archivables dans le rpertoire /mnt/serveur/repertoire_archive. (Ceci est un exemple,
pas une recommandation, et peut ne pas fonctionner sur toutes les plateformes.) Aprs le remplacement des paramtres %p et %f,
la commande rellement excute peut ressembler :
test ! -f /mnt/serveur/repertoire_archive/00000001000000A900000065 && cp
pg_xlog/00000001000000A900000065
/mnt/serveur/repertoire_archive/00000001000000A900000065
Une commande similaire est produite pour chaque nouveau fichier archiver.
La commande d'archivage est excute sous l'identit de l'utilisateur propritaire du serveur PostgreSQL. La srie de fichiers
WAL en cours d'archivage contient absolument tout ce qui se trouve dans la base de donnes, il convient donc de s'assurer que les
donnes archives sont protges des autres utilisateurs ; on peut, par exemple, archiver dans un rpertoire sur lequel les droits de
lecture ne sont positionns ni pour le groupe ni pour le reste du monde.
Il est important que la commande d'archivage ne renvoie le code de sortie zro que si, et seulement si, l'excution a russi. En obtenant un rsultat zro, PostgreSQL suppose que le fichier segment WAL a t archiv avec succs et qu'il peut le supprimer ou
le recycler. Un statut diffrent de zro indique PostgreSQL que le fichier n'a pas t archiv ; il essaie alors priodiquement
jusqu' la russite de l'archivage.
La commande d'archivage doit, en gnral, tre conue pour refuser d'craser tout fichier archive qui existe dj. C'est une fonctionnalit de scurit importante pour prserver l'intgrit de l'archive dans le cas d'une erreur de l'administrateur (comme l'envoi
de la sortie de deux serveurs diffrents dans le mme rpertoire d'archivage).
Il est conseill de tester la commande d'archivage propose pour s'assurer, qu'en effet, elle n'crase pas un fichier existant, et
qu'elle retourne un statut diffrent de zro dans ce cas. La commande pour Unix en exemple ci-dessus le garantit en incluant une
tape test spare. Sur certaines plateformes Unix, la commande cp dispose d'une option, comme -i pouvant tre utilis pour
faire la mme chose, mais en moins verbeux. Cependant, vous ne devriez pas vous baser l-dessus sans vous assurer que le code
de sortie renvoy est le bon. (en particulier, la commande cp de GNU renvoie un code zro quand -i est utilis et que le fichier
cible existe dj, ce qui n'est pas le comportement dsir.)
Lors de la conception de la configuration d'archivage, il faut considrer ce qui peut se produire si la commande d'archivage choue
de faon rpte, que ce soit parce qu'une intervention de l'oprateur s'avre ncessaire ou par manque d'espace dans le rpertoire
d'archivage. Ceci peut arriver, par exemple, lors de l'criture sur une cartouche sans changeur automatique ; quand la cartouche est
pleine, rien ne peut tre archiv tant que la cassette n'est pas change. Toute erreur ou requte un oprateur humain doit tre rapporte de faon approprie pour que la situation puisse tre rsolue rapidement. Le rpertoire pg_xlog/ continue se remplir de
fichiers de segment WAL jusqu' la rsolution de la situation. (Si le systme de fichiers contenant pg_xlog/ se remplit, PostgreSQL s'arrte en mode PANIC. Aucune transaction valide n'est perdue mais la base de donnes est inaccessible tant que de
l'espace n'a pas t libr.)
405

Sauvegardes et restaurations

La vitesse de la commande d'archivage n'est pas importante, tant qu'elle suit le rythme de gnration des donnes WAL du serveur. Les oprations normales continuent mme si le processus d'archivage est un peu plus lent. Si l'archivage est significativement plus lent, alors la quantit de donnes qui peut tre perdue crot. Cela signifie aussi que le rpertoire pg_xlog/ contient un
grand nombre de fichiers segment non archivs, qui peuvent finir par dpasser l'espace disque disponible. Il est conseill de surveiller le processus d'archivage pour s'assurer que tout fonctionne normalement.
Lors de l'criture de la commande d'archivage, il faut garder l'esprit que les noms de fichier archiver peuvent contenir jusqu'
64 caractres et tre composs de toute combinaison de lettres ASCII, de chiffres et de points. Il n'est pas ncessaire de conserver
le chemin relatif original (%p) mais il est ncessaire de se rappeler du nom du fichier (%f).
Bien que l'archivage WAL autorise restaurer toute modification ralise sur les donnes de la base, il ne restaure pas les modifications effectues sur les fichiers de configuration (c'est--dire postgresql.conf, pg_hba.conf et pg_ident.conf) car
ceux-ci sont dits manuellement et non au travers d'oprations SQL. Il est souhaitable de conserver les fichiers de configuration
un endroit o ils sont sauvegards par les procdures standard de sauvegarde du systme de fichiers. Voir la Section 18.2,
Emplacement des fichiers pour savoir comment modifier l'emplacement des fichiers de configuration.
La commande d'archivage n'est appele que sur les segments WAL complets. Du coup, si le serveur engendre peu de trafic WAL
(ou qu'il y a des priodes de calme o le trafic WAL est lger), il peut y avoir un long dlai entre la fin d'une transaction et son enregistrement sr dans le stockage d'archive. Pour placer une limite sur l'anciennet des donnes archives, on configure archive_timeout qui force le serveur changer de fichier segment WAL pass ce dlai. Les fichiers archivs lors d'un tel forage ont
toujours la mme taille que les fichiers complets. Il est donc dconseill de configurer un dlai archive_timeout trop court -cela fait grossir anormalement le stockage. Une minute pour archive_timeout est gnralement raisonnable.
De plus, le changement d'un segment peut tre forc manuellement avec pg_switch_xlog. Cela permet de s'assurer qu'une
transaction tout juste termine est archive aussi vite que possible. D'autres fonctions utilitaires relatives la gestion des WAL
sont disponibles dans Tableau 9.56, Fonctions de contrle de la sauvegarde .
Quand wal_level est configur minimal, certaines commandes SQL sont optimises pour viter la journalisation des transactions, de la faon dcrite dans Section 14.4.7, Dsactiver l'archivage des journaux de transactions et la rplication en flux .
Si l'archivage ou la rplication en flux est activ lors de l'excution d'une de ces instructions, les journaux de transaction ne
contiennent pas suffisamment d'informations pour une rcupration via les archives. (La rcupration aprs un arrt brutal n'est
pas affecte.) Pour cette raison, wal_level ne peut tre modifi qu'au lancement du serveur. Nanmoins, archive_command
peut tre modifi par rechargement du fichier de configuration. Pour arrter temporairement l'archivage, on peut placer une chane
vide ('') pour archive_command. Les journaux de transaction sont alors accumuls dans pg_xlog/ jusqu'au rtablissement
d'un paramtre archive_command fonctionnel.

24.3.2. Raliser une sauvegarde de base


La procdure pour raliser une sauvegarde de base est relativement simple :
1. S'assurer que l'archivage WAL est activ et fonctionnel.
2. Se connecter la base de donnes en tant que superutilisateur et lancer la commande :
SELECT pg_start_backup('label');
o label est une chane utilise pour identifier de faon unique l'opration de sauvegarde (une bonne pratique est d'utiliser le
chemin complet du fichier de sauvegarde). pg_start_backup cre un fichier de label de sauvegarde nomm backup_label dans le rpertoire du cluster. Ce fichier contient les informations de la sauvegarde, ceci incluant le moment du
dmarrage et le label.
La base de donnes de connexion utilise pour lancer cette commande n'a aucune importance. Le rsultat de la fonction peut
tre ignor, mais il faut grer l'erreur ventuelle avant de continuer.
Par dfaut, pg_start_backup peut prendre beaucoup de temps pour arriver son terme. Ceci est d au fait qu'il ralise un
point de vrification (checkpoint), et que les entres/sorties pour l'tablissement de ce point de vrification seront rparties sur
une grande dure, par dfaut la moiti de l'intervalle entre deux points de vrification (voir le paramtre de configuration
checkpoint_completion_target). Habituellement, ce comportement est apprciable, car il minimise l'impact du traitement des
requtes. Pour commencer la sauvegarde aussi rapidement que possible, utiliser :
SELECT pg_start_backup('label', true);
Cela force l'excution du point de vrification aussi rapidement que possible.
3. Effectuer la sauvegarde l'aide de tout outil de sauvegarde du systme de fichiers, tel tar ou cpio (mais ni pg_dump ni
pg_dumpall). Il n'est ni ncessaire ni dsirable de stopper les oprations normales de la base de donnes pour cela.
4. Se connecter nouveau la base de donnes en tant que superutilisateur et lancer la commande :
406

Sauvegardes et restaurations

SELECT pg_stop_backup();
Cela met fin au processus de sauvegarde et ralise une bascule automatique vers le prochain segment WAL. Cette bascule est
ncessaire pour permettre au dernier fichier de segment WAL crit pendant la sauvegarde d'tre immdiatement archivable.
5. Une fois que les fichiers des segments WAL utiliss lors de la sauvegarde sont archivs, c'est termin. Le fichier identifi par le
rsultat de pg_stop_backup est le dernier segment ncessaire pour produire un jeu complet de fichiers de backup. Si archive_mode est activ, pg_stop_backup ne rend pas la main avant que le dernier segment n'ait t archiv. L'archivage
de ces fichiers est automatique puisque archive_command est configur. Dans la plupart des cas, c'est rapide, mais il est
conseill de surveiller le systme d'archivage pour s'assurer qu'il n'y a pas de retard. Si le processus d'archivage a pris du retard
en raison d'checs de la commande d'archivage, il continuera d'essayer jusqu' ce que l'archive russisse et que le backup soit
complet. Pour positionner une limite au temps d'excution de pg_stop_backup, il faut positionner statement_timeout une valeur approprie.
Vous pouvez aussi utiliser l'outil pg_basebackup(1) pour faire la sauvegarde, la place d'une copie manuelle des fichiers. Cet outil
fera l'quivalent des tapes pg_start_backup(), copie et pg_stop_backup() automatiquement, et transfert la sauvegarde via une connexion standard PostgreSQL en utilisant le protocole de rplication, au lieu d'avoir besoin d'un accs au niveau du systme de fichiers. pg_basebackup n'interfre pas avec les sauvegardes de niveau systme de fichiers prises l'aide de
pg_start_backup()/pg_stop_backup().
Certains outils de sauvegarde de fichiers mettent des messages d'avertissement ou d'erreur si les fichiers qu'ils essaient de copier
sont modifis au cours de la copie. Cette situation, normale lors de la sauvegarde d'une base active, ne doit pas tre considre
comme une erreur ; il suffit de s'assurer que ces messages puissent tre distingus des autres messages. Certaines versions de
rsync, par exemple, renvoient un code de sortie distinct en cas de disparition de fichiers source . Il est possible d'crire un script
qui considre ce code de sortie comme normal.
De plus, certaines versions de GNU tar retournent un code d'erreur qu'on peut confondre avec une erreur fatale si le fichier a t
tronqu pendant sa copie par tar. Heureusement, les versions 1.16 et suivantes de GNU tar retournent 1 si le fichier a t modifi
pendant la sauvegarde et 2 pour les autres erreurs.
Il n'est pas utile d'accorder de l'importance au temps pass entre pg_start_backup et le dbut rel de la sauvegarde, pas plus
qu'entre la fin de la sauvegarde et pg_stop_backup ; un dlai de quelques minutes ne pose pas de problme. (Nanmoins, si le
serveur est normalement utilis alors que full_page_writes est dsactiv, une perte de performances entre
pg_start_backup et pg_stop_backup peut tre constate car l'activation du paramtre full_page_writes est force
lors du mode de sauvegarde.) Il convient toutefois de s'assurer que ces tapes sont effectues squentiellement, sans chevauchement. Dans le cas contraire, la sauvegarde est invalide.
La sauvegarde doit inclure tous les fichiers du rpertoire du groupe de bases de donnes (/usr/local/pgsql/data, par
exemple). Si des tablespaces qui ne se trouvent pas dans ce rpertoire sont utiliss, il ne faut pas oublier de les inclure (et s'assurer
galement que la sauvegarde archive les liens symboliques comme des liens, sans quoi la restauration va corrompre les tablespaces).
Nanmoins, les fichiers du sous-rpertoire pg_xlog/, contenu dans le rpertoire du cluster, peuvent tre omis. Ce lger ajustement permet de rduire le risque d'erreurs lors de la restauration. C'est facile raliser si pg_xlog/ est un lien symbolique vers
quelque endroit extrieur au rpertoire du cluster, ce qui est toutefois une configuration courante, pour des raisons de performance.
Il peut tre intressant d'exclure postmaster.pid et postmaster.opts, qui enregistrent des informations sur le postmaster
en cours d'excution, mais pas sur le postmaster qui va utiliser cette sauvegarde. De plus, ces fichiers peuvent poser problme
pg_ctl.
La sauvegarde n'est utilisable que si les fichiers de segment WAL engendrs pendant ou aprs cette sauvegarde sont prservs.
Pour faciliter cela, la fonction pg_stop_backup cre un fichier d'historique de la sauvegarde immdiatement stock dans la
zone d'archivage des WAL. Ce fichier est nomm d'aprs le nom du premier fichier segment WAL ncessaire l'utilisation de la
sauvegarde. Ainsi, si le fichier WAL de dmarrage est 0000000100001234000055CD, le nom du fichier d'historique ressemble 0000000100001234000055CD.007C9330.backup (le deuxime nombre dans le nom de ce fichier contient la
position exacte l'intrieur du fichier WAL et peut en gnral tre ignor). Une fois que la sauvegarde du systme de fichiers et
des segments WAL utiliss pendant celle-ci (comme prcis dans le fichier d'historique des sauvegardes) est archive de faon
sre, tous les segments WAL archivs de noms numriquement plus petits ne sont plus ncessaires la rcupration de la sauvegarde du systme de fichiers et peuvent tre supprims. Toutefois, il est prfrable de conserver plusieurs jeux de sauvegarde pour
tre absolument certain de pouvoir rcuprer les donnes.
Le fichier d'historique de la sauvegarde est un simple fichier texte. Il contient le label pass pg_start_backup, l'heure et les
segments WAL de dbut et de fin de la sauvegarde. Si le label est utilis pour identifier l'endroit o le fichier de sauvegarde associ est conserv, alors le fichier d'historique archiv est suffisant pour savoir quel fichier de sauvegarde restaurer, en cas de besoin.
Puisqu'il faut conserver tous les fichiers WAL archivs depuis la dernire sauvegarde de base, l'intervalle entre les sauvegardes de
base est habituellement choisi en fonction de l'espace de stockage qu'on accepte de consommer en fichiers d'archives WAL. Il faut
407

Sauvegardes et restaurations

galement considrer le temps dpenser pour la rcupration, si celle-ci s'avre ncessaire -- le systme doit rejouer tous les segments WAL et ceci peut prendre beaucoup de temps si la dernire sauvegarde de base est ancienne.
La fonction pg_start_backup cre un fichier nomm backup_label dans le rpertoire du cluster de bases de donnes. Ce
fichier est ensuite supprim par pg_stop_backup. Ce fichier est archiv dans le fichier de sauvegarde. Le fichier de label de la
sauvegarde inclut la chane de label passe pg_start_backup, l'heure laquelle pg_start_backup a t excut et le
nom du fichier WAL initial. En cas de confusion, il est ainsi possible de regarder dans le fichier sauvegarde et de dterminer avec
prcision de quelle session de sauvegarde provient ce fichier.
Il est aussi possible de faire une sauvegarde alors que le serveur est arrt. Dans ce cas, pg_start_backup et
pg_stop_backup ne peuvent pas tre utiliss. L'utilisateur doit alors se dbrouiller pour identifier les fichiers de sauvegarde et
dterminer jusqu'o remonter avec les fichiers WAL associs. Il est gnralement prfrable de suivre la procdure d'archivage
continu dcrite ci-dessus.

24.3.3. Rcupration partir d'un archivage continu


Le pire est arriv et il faut maintenant repartir d'une sauvegarde. Voici la procdure :
1. Arrter le serveur s'il est en cours d'excution.
2. Si la place ncessaire est disponible, copier le rpertoire complet de donnes du cluster et tous les tablespaces dans un emplacement temporaire en prvision d'un ventuel besoin ultrieur. Cette prcaution ncessite qu'un espace suffisant sur le systme
soit disponible pour contenir deux copies de la base de donnes existante. S'il n'y a pas assez de place disponible, il faut au minimum copier le contenu du sous-rpertoire pg_xlog du rpertoire des donnes du cluster car il peut contenir des journaux
qui n'ont pas t archivs avant l'arrt du serveur.
3. Effacer tous les fichiers et sous-rpertoires existant sous le rpertoire des donnes du cluster et sous les rpertoires racines des
tablespaces.
4. Restaurer les fichiers de la base de donnes partir de la sauvegarde des fichiers. Il faut veiller ce qu'ils soient restaurs avec
le bon propritaire (l'utilisateur systme de la base de donnes, et non pas root !) et avec les bons droits. Si des tablespaces
sont utiliss, il faut s'assurer que les liens symboliques dans pg_tblspc/ ont t correctement restaurs.
5. Supprimer tout fichier prsent dans pg_xlog/ ; ils proviennent de la sauvegarde et sont du coup probablement obsoltes. Si
pg_xlog/ n'a pas t archiv, il suffit de recrer ce rpertoire en faisant attention le crer en tant que lien symbolique, si
c'tait le cas auparavant.
6. Si des fichiers de segment WAL non archivs ont t sauvegards dans l'tape 2, les copier dans pg_xlog/. Il est prfrable
de les copier plutt que de les dplacer afin qu'une version non modifie de ces fichiers soit toujours disponible si un problme
survient et qu'il faille recommencer.
7. Crer un fichier de commandes de rcupration recovery.conf dans le rpertoire des donnes du cluster (voir Chapitre 26,
Configuration de la rcupration). Il peut, de plus, tre judicieux de modifier temporairement le fichier pg_hba.conf pour
empcher les utilisateurs ordinaires de se connecter tant qu'il n'est pas certain que la rcupration a russi.
8. Dmarrer le serveur. Le serveur se trouve alors en mode rcupration et commence la lecture des fichiers WAL archivs dont il
a besoin. Si la rcupration se termine sur une erreur externe, le serveur peut tout simplement tre relanc. Il continue alors la
rcupration. la fin du processus de rcupration, le serveur renomme recovery.conf en recovery.done (pour viter
de retourner accidentellement en mode de rcupration), puis passe en mode de fonctionnement normal.
9. Inspecter le contenu de la base de donnes pour s'assurer que la rcupration a bien fonctionn. Dans le cas contraire, retourner
l'tape 1. Si tout va bien, le fichier pg_hba.conf peut-tre restaur pour autoriser les utilisateurs se reconnecter.
Le point cl de tout ceci est l'criture d'un fichier de configuration de rcupration qui dcrit comment et jusqu'o rcuprer. Le fichier recovery.conf.sample (normalement prsent dans le rpertoire d'installation share/) peut tre utilis comme prototype. La seule chose qu'il faut absolument prciser dans recovery.conf, c'est restore_command qui indique PostgreSQL comment rcuprer les fichiers de segment WAL archivs. l'instar d'archive_command, c'est une chane de commande shell. Elle peut contenir %f, qui est remplac par le nom du journal souhait, et %p, qui est remplac par le chemin du rpertoire o copier le journal. (Le nom du chemin est relatif au rpertoire de travail du serveur, c'est--dire le rpertoire des donnes du cluster.) Pour crire le caractre % dans la commande, on utilise %%. La commande la plus simple ressemble :
restore_command = 'cp /mnt/serveur/rpertoire_archive/%f %p'
qui copie les segments WAL prcdemment archivs partir du rpertoire /mnt/serveur/rpertoire_archive. Il est
toujours possible d'utiliser une commande plus complique, voire mme un script shell qui demande l'utilisateur de monter la
cassette approprie.
Il est important que la commande retourne un code de sortie diffrent de zro en cas d'chec. Des fichiers absents de l'archive se408

Sauvegardes et restaurations

ront demands la commande ; elle doit renvoyer autre chose que zro dans ce cas. Ce n'est pas une condition d'erreur. Tous les
fichiers demands ne seront pas des segmets WAL; vous pouvez aussi vous attendre des demandes de fichiers suffixs par
.backup or .history. Il faut galement garder l'esprit que le nom de base du chemin %p diffre de %f ; il ne sont pas interchangeables.
Les segments WAL qui ne se trouvent pas dans l'archive sont recherchs dans pg_xlog/ ; cela autorise l'utilisation de segments
rcents non archivs. Nanmoins, les segments disponibles dans l'archive sont utiliss de prfrence aux fichiers contenus dans
pg_xlog/. Le systme ne surcharge pas le contenu de pg_xlog/ lors de la rcupration des fichiers archivs.
Normalement, la rcupration traite tous les segments WAL disponibles, restaurant du coup la base de donnes l'instant prsent
(ou aussi proche que possible, en fonction des segments WAL disponibles). Une rcupration normale se finit avec un message
fichier non trouv , le texte exact du message d'erreur dpendant du choix de restore_command. Un message d'erreur au
dbut de la rcupration peut galement apparatre concernant un fichier nomm dont le nom ressemble 00000001.history.
Ceci est aussi normal et n'indique par un problme dans les situations de rcupration habituelles. Voir Section 24.3.4, Lignes
temporelles (Timelines) pour plus d'informations.
Pour rcuprer un moment prcis (avant que le DBA junior n'ait supprim la table principale), il suffit d'indiquer le point d'arrt
requis dans recovery.conf. Le point d'arrt, aussi nomm recovery target (cible de rcupration), peut tre prcis par une
combinaison date/heure, un point de rcupration nomm ou par le dernier identifiant de transaction. Actuellement, seules les options date/heure et point de rcupration nomm sont vraiment utilisables car il n'existe pas d'outils permettant d'identifier avec
prcision l'identifiant de transaction utiliser.

Note
Le point d'arrt doit tre postrieur la fin de la sauvegarde de la base (le moment o pg_stop_backup se termine). Une sauvegarde ne peut pas tre utilise pour repartir d'un instant o elle tait encore en cours (pour ce faire,
il faut rcuprer la sauvegarde prcdente et rejouer partir de l).
Si la rcupration fait face une corruption des donnes WAL, elle se termine ce point et le serveur ne dmarre pas. Dans un tel
cas, le processus de rcupration peut alors tre r-excut partir du dbut en prcisant une cible de rcupration antrieure
au point de rcupration pour permettre cette dernire de se terminer correctement. Si la rcupration choue pour une raison externe (arrt brutal du systme ou archive WAL devenue inaccessible), la rcupration peut tre simplement relance. Elle redmarre alors quasiment l o elle a chou. Le redmarrage de la restauration fonctionne comme les points de contrle du droulement normal : le serveur force une criture rgulire de son tat sur les disques et actualise alors le fichier pg_control pour indiquer que les donnes WAL dj traites n'ont plus tre parcourues.

24.3.4. Lignes temporelles (Timelines)


La possibilit de restaurer la base de donnes partir d'un instantan cre une complexit digne des histoires de science-fiction
traitant du voyage dans le temps et des univers parallles.
Par exemple, dans l'historique original de la base de donnes, supposez qu'une table critique ait t supprime 17h15 mardi soir,
mais personne n'a ralis cette erreur avant mercredi midi. Sans stress, la sauvegarde est rcupre et restaure dans l'tat o elle
se trouvait 17h14 mardi soir. La base est fonctionnelle. Dans cette histoire de l'univers de la base de donnes, la table n'a jamais
t supprime. Or, l'utilisateur ralise peu aprs que ce n'tait pas une si grande ide et veut revenir un quelconque moment du
mercredi matin. Cela n'est pas possible, si, alors que la base de donnes est de nouveau fonctionnelle, elle rutilise certaines squences de fichiers WAL qui permettent de retourner ce point. Il est donc ncessaire de pouvoir distinguer les sries
d'enregistrements WAL engendres aprs la rcupration de l'instantan de celles issues de l'historique originel de la base.
Pour grer ces difficults, PostgreSQL inclut la notion de lignes temporelles (ou timelines). Quand une rcupration d'archive
est termine, une nouvelle ligne temporelle est cre pour identifier la srie d'enregistrements WAL produits aprs cette restauration. Le numro d'identifiant de la timeline est inclus dans le nom des fichiers de segment WAL. De ce fait, une nouvelle timeline
ne rcrit pas sur les donnes engendres par des timelines prcdentes. En fait, il est possible d'archiver plusieurs timelines diffrentes. Bien que cela semble tre une fonctionnalit inutile, cela peut parfois sauver des vies. Dans une situation o l'instantan
rcuprer n'est pas connu avec certitude, il va falloir tester les rcuprations de diffrents instantans jusqu' trouver le meilleur.
Sans les timelines, ce processus engendre vite un bazar ingrable. Avec les timelines, il est possible de rcuprer n'importe quel
tat prcdent, mme les tats de branches temporelles abandonnes.
Chaque fois qu'une nouvelle timeline est cre, PostgreSQL cre un fichier d' historique des timelines qui indique quelle timeline il est attach, et depuis quand. Ces fichiers d'historique sont ncessaires pour permettre au systme de choisir les bons fichiers de segment WAL lors de la rcupration partir d'une archive qui contient plusieurs timelines. Ils sont donc archivs
comme tout fichier de segment WAL. Puisque ce sont de simples fichiers texte, il est peu coteux et mme judicieux de les
conserver indfiniment (contrairement aux fichiers de segment, volumineux). Il est possible d'ajouter des commentaires au fichier
d'historique expliquant comment et pourquoi cette timeline a t cre. De tels commentaires s'avrent prcieux lorsque
l'exprimentation conduit de nombreuses timelines.
409

Sauvegardes et restaurations

Par dfaut, la rcupration s'effectue sur la timeline en vigueur au cours de la la sauvegarde. Si l'on souhaite effectuer la rcupration dans une timeline fille (c'est--dire retourner un tat enregistr aprs une tentative de rcupration), il faut prciser
l'identifiant de la timeline dans recovery.conf. Il n'est pas possible de rcuprer dans des timelines antrieures la sauvegarde.

24.3.5. Conseils et exemples


Quelques conseils de configuration de l'archivage continue sont donns ici.

24.3.5.1. Configuration de la rcupration


Il est possible d'utiliser les capacits de sauvegarde de PostgreSQL pour produire des sauvegardes autonomes chaud. Ce sont
des sauvegardes qui ne peuvent pas tre utilises pour la rcupration un instant donn, mais ce sont des sauvegardes qui sont typiquement plus rapide obtenir et restaurer que ceux issus de pg_dump. (Elles sont aussi bien plus volumineuses qu'un export
pg_dump, il se peut donc que l'avantage de rapidit soit ngatif.)
En vue d'effectuer des sauvegardes chaud autonomes, on positionne wal_level archive (ou hot_standby), archive_mode on, et on configure archive_command de telle sorte que l'archivage ne soit ralis que lorsqu'un fichier de
bascule existe. Par exemple :
archive_command = 'test ! -f /var/lib/pgsql/backup_in_progress || (test ! -f
/var/lib/pgsql/archive/%f && cp %p /var/lib/pgsql/archive/%f)'
Cette commande ralise l'archivage ds lors que /var/lib/pgsql/backup_in_progress existe. Dans le cas contraire,
elle renvoie silencieusement le code de statut zro (permettant PostgreSQL de recycler le journal de transactions non dsir).
Avec cette prparation, une sauvegarde peut tre prise en utilisant un script comme celui-ci :
touch /var/lib/pgsql/backup_in_progress
psql -c "select pg_start_backup('hot_backup');"
tar -cf /var/lib/pgsql/backup.tar /var/lib/pgsql/data/
psql -c "select pg_stop_backup();"
rm /var/lib/pgsql/backup_in_progress
tar -rf /var/lib/pgsql/backup.tar /var/lib/pgsql/archive/
Le fichier de bascule, /var/lib/pgsql/backup_in_progress, est cr en premier, activant l'archivage des journaux de
transactions pleins. Aprs la sauvegarde, le fichier de bascule est supprim. Les journaux de transaction archivs sont ensuite ajouts la sauvegarde pour que la sauvegarde de base et les journaux requis fassent partie du mme fichier tar. Rappelez vous
d'ajouter de la gestion d'erreur vos scripts.

24.3.5.2. Compression des journaux archivs


Si la taille du stockage des archives est un problme, utilisez pg_compresslog, http://pglesslog.projects.postgresql.org, afin
d'enlever les inutiles full_page_writes et les espaces de fin des journaux de transactions. Vous pouvez utiliser gzip pour compresser encore davantage le rsultat de pg_compresslog :
archive_command = 'pg_compresslog %p - | gzip > /var/lib/pgsql/archive/%f'
Vous aurez alors besoin d'utiliser gunzip et pg_decompresslog pendant la rcupration :
restore_command = 'gunzip < /mnt/server/archivedir/%f | pg_decompresslog %p'

24.3.5.3. Scripts archive_command


Nombreux sont ceux qui choisissent d'utiliser des scripts pour dfinir leur archive_command, de sorte que leur postgresql.conf semble trs simple :
archive_command = 'local_backup_script.sh "%p" "%f"'
Utiliser un script spar est conseill chaque fois qu'il est envisag d'utiliser plusieurs commandes pour le processus d'archivage.
Ainsi toute la complexit est gre dans le script qui peut tre crit dans un langage de scripts populaires comme bash ou perl.
Quelques exemples de besoins rsolus dans un script :

410

Sauvegardes et restaurations

copier des donnes vers un stockage distant ;

copier les journaux de transaction en groupe pour qu'ils soient transfrs toutes les trois heures plutt qu'un la fois ;

s'interfacer avec d'autres outils de sauvegarde et de rcupration ;

s'interfacer avec un outil de surveillance pour y renvoyer les erreurs.

Astuce
Lors de l'utilisation du script archive_command, il est prfrable d'activer logging_collector. Tout message envoy dans stderr partir du script apparatra dans les traces du serveur, permettant un diagnostic plus ais de
configurations complexes en cas de problme.

24.3.6. Restrictions
Au moment o ces lignes sont crites, plusieurs limitations de la technique d'achivage continu sont connues. Elles seront probablement corriges dans une prochaine version :

Les oprations sur les index de hachage ne sont pas traces dans les journaux de transactions. Ces index ne sont donc pas actualiss lorsque la sauvegarde est rejoue. Cela signifie que toute nouvelle insertion sera ignore par l'index, que les lignes
mises jour sembleront disparatre et que les lignes supprimes auront toujours leur pointeurs. En d'autres termes, si vous modifier une table disposant d'un index hash, alors vous obtiendrez des rsultats errons sur un serveur en attente. Lorsque la restauration se termine, il est recommand de lancer manuellement la commande REINDEX(7) sur chacun des index la fin de la
rcupration.

Si une commande CREATE DATABASE(7) est excute alors qu'une sauvegarde est en cours, et que la base de donnes modle utilise par l'instruction CREATE DATABASE est son tour modifie pendant la sauvegarde, il est possible que la rcupration propage ces modifications dans la base de donnes cre. Pour viter ce risque, il est prfrable de ne pas modifier les
bases de donnes modle lors d'une sauvegarde de base.

Les commandes CREATE TABLESPACE(7) sont traces dans les WAL avec le chemin absolu et sont donc rejoues en tant
que crations de tablespace suivant le mme chemin absolu. Cela n'est pas forcment souhaitable si le journal est rejoue sur
une autre machine. De plus, cela peut s'avrer dangereux mme lorsque le journal est rejou sur la mme machine, mais dans
un rpertoire diffrent : la r-excution surcharge toujours le contenu du tablespace original. Pour viter de tels problmes, la
meilleure solution consiste effectuer une nouvelle sauvegarde de la base aprs la cration ou la suppression de tablespace.

Il faut de plus garder l'esprit que le format actuel des WAL est extrmement volumineux car il inclut de nombreuses images des
pages disques. Ces images de page sont conues pour supporter la rcupration aprs un arrt brutal, puisqu'il peut tre ncessaire
de corriger des pages disque partiellement crites. En fonction du matriel et des logiciels composant le systme, le risque
d'criture partielle peut tre suffisamment faible pour tre ignor, auquel cas le volume total des traces archives peut tre considrablement rduit par la dsactivation des images de page l'aide du paramtre full_page_writes (lire les notes et avertissements
dans Chapitre 29, Fiabilit et journaux de transaction avant de le faire). Dsactiver les images de page n'empche pas l'utilisation
des traces pour les oprations PITR. Un piste ventuelle de dveloppement futur consiste compresser les donnes des WAL archivs en supprimant les copies inutiles de pages mme si full_page_writes est actif. Entre temps, les administrateurs
peuvent souhaiter rduire le nombre d'images de pages inclus dans WAL en augmentant autant que possible les paramtres
d'intervalle entre les points de vrification.

411

Chapitre 25. Haute disponibilit, rpartition de


charge et rplication
Des serveurs de bases de donnes peuvent travailler ensemble pour permettre un serveur secondaire de prendre rapidement la
main si le serveur principal choue (haute disponibilit, ou high availability), ou pour permettre plusieurs serveurs de servir les
mmes donnes (rpartition de charge, ou load balancing). Idalement, les serveurs de bases de donnes peuvent travailler ensemble sans jointure.
Il est ais de faire cooprer des serveurs web qui traitent des pages web statiques en rpartissant la charge des requtes web sur
plusieurs machines. Dans les faits, les serveurs de bases de donnes en lecture seule peuvent galement cooprer facilement.
Malheureusement, la plupart des serveurs de bases de donnes traitent des requtes de lecture/criture et, de ce fait, collaborent
plus difficilement. En effet, alors qu'il suffit de placer une seule fois les donnes en lecture seule sur chaque serveur, une criture sur n'importe quel serveur doit, elle, tre propage tous les serveurs afin que les lectures suivantes sur ces serveurs renvoient des rsultats cohrents.
Ce problme de synchronisation reprsente la difficult fondamentale la collaboration entre serveurs. Comme la solution au
problme de synchronisation n'est pas unique pour tous les cas pratiques, plusieurs solutions co-existent. Chacune rpond de
faon diffrente et minimise cet impact au regard d'une charge spcifique.
Certaines solutions grent la synchronisation en autorisant les modifications des donnes sur un seul serveur. Les serveurs qui
peuvent modifier les donnes sont appels serveur en lecture/criture, matre ou serveur primaire. Les serveurs qui suivent les
modifications du matre sont appels standby, ou serveurs esclaves. Un serveur en standby auquel on ne peut pas se connecter
tant qu'il n'a pas t promu en serveur matre est appel un serveur en warm standby, et un qui peut accepter des connections et
rpondre des requtes en lecture seule est appel un serveur en hot standby.
Certaines solutions sont synchrones, ce qui signifie qu'une transaction de modification de donnes n'est pas considre valide
tant que tous les serveurs n'ont pas valid la transaction. Ceci garantit qu'un failover ne perd pas de donnes et que tous les serveurs en rpartition de charge retournent des rsultats cohrents, quel que soit le serveur interrog. Au contraire, les solutions
asynchrones autorisent un dlai entre la validation et sa propagation aux autres serveurs. Cette solution implique une ventuelle
perte de transactions lors de la bascule sur un serveur de sauvegarde, ou l'envoi de donnes obsoltes par les serveurs charge
rpartie. La communication asynchrone est utilise lorsque la version synchrone est trop lente.
Les solutions peuvent aussi tre catgorises par leur granularit. Certaines ne grent que la totalit d'un serveur de bases alors
que d'autres autorisent un contrle par table ou par base.
Il importe de considrer les performances dans tout choix. Il y a gnralement un compromis trouver entre les fonctionnalits
et les performances. Par exemple, une solution compltement synchrone sur un rseau lent peut diviser les performances par
plus de deux, alors qu'une solution asynchrone peut n'avoir qu'un impact minimal sur les performances.
Le reste de cette section souligne diffrentes solutions de failover, de rplication et de rpartition de charge. Un glossaire est
aussi disponible.

25.1. Comparaison de diffrentes solutions


Failover sur disque partag
Le failover (ou bascule sur incident) sur disque partag limine la surcharge de synchronisation par l'existence d'une seule
copie de la base de donnes. Il utilise un seul ensemble de disques partag par plusieurs serveurs. Si le serveur principal
choue, le serveur en attente est capable de monter et dmarrer la base comme s'il rcuprait d'un arrt brutal. Cela permet
un failover rapide sans perte de donnes.
La fonctionnalit de matriel partag est commune aux priphriques de stockage en rseau. Il est galement possible
d'utiliser un systme de fichiers rseau bien qu'il faille porter une grande attention au systme de fichiers pour s'assurer qu'il
a un comportement POSIX complet (voir Section 17.2.1, Systmes de fichiers rseaux ). Cette mthode comporte une limitation significative : si les disques ont un problme ou sont corrompus, le serveur primaire et le serveur en attente sont
tous les deux non fonctionnels. Un autre problme est que le serveur en attente ne devra jamais accder au stockage partag
tant que le serveur principal est en cours d'excution.
Rplication de systme de fichiers (priphrique bloc)
Il est aussi possible d'utiliser cette fonctionnalit d'une autre faon avec une rplication du systme de fichiers, o toutes les
modifications d'un systme de fichiers sont renvoyes sur un systme de fichiers situ sur un autre ordinateur. La seule restriction est que ce miroir doit tre construit de telle sorte que le serveur en attente dispose d'une version cohrente du systme de fichiers -- spcifiquement, les critures sur le serveur en attente doivent tre ralises dans le mme ordre que celles
sur le matre. DRBD est une solution populaire de rplication de systmes de fichiers pour Linux.
412

Haute disponibilit, rpartition de charge et


rplication
Warm et Hot Standby en utilisant PITR
Les serveurs warm et hot standby (voir Section 25.2, Serveurs de Standby par transfert de journaux ) peuvent conserver
leur cohrence en lisant un flux d'enregistrements de WAL. Si le serveur principal choue, le serveur standby contient pratiquement toutes les donnes du serveur principal et peut rapidement devenir le nouveau serveur matre. Ceci est asynchrone et
ne peut se faire que pour le serveur de bases complet.
Un serveur de standby en PITR peut tre implment en utilisant la recopie de journaux par fichier (Section 25.2, Serveurs
de Standby par transfert de journaux ) ou la streaming replication (rplication en continu, voir Section 25.2.5, Streaming
Replication ), ou une combinaison des deux. Pour des informations sur le hot standby, voyez Section 25.5, Hot Standby ..
Rplication matre/esclave bas sur des triggers
Une configuration de rplication matre/esclave envoie toutes les requtes de modification de donnes au serveur matre. Ce
serveur envoie les modifications de donnes de faon asynchrone au serveur esclave. L'esclave peut rpondre aux requtes en
lecture seule alors que le serveur matre est en cours d'excution. Le serveur esclave est idal pour les requtes vers un entrept de donnes.
Slony-I est un exemple de ce type de rplication, avec une granularit par table et un support des esclaves multiples.
Comme il met jour le serveur esclave de faon asynchrone (par lots), il existe une possibilit de perte de donnes pendant un
failover.
Middleware de rplication bas sur les instructions
Avec les middleware de rplication bass sur les instructions, un programme intercepte chaque requte SQL et l'envoie un
ou tous les serveurs. Chaque serveur opre indpendamment. Les requtes en lecture/criture doivent tre envoyes tous les
serveurs pour que chaque serveur reoive les modifications. Les requtes en lecture seule ne peuvent tre envoyes qu' un
seul serveur, ce qui permet de distribuer la charge de lecture.
Si les requtes sont envoyes sans modification, les fonctions comme random(), CURRENT_TIMESTAMP ainsi que les squences ont des valeurs diffrentes sur les diffrents serveurs. Cela parce que chaque serveur opre indpendamment alors
que les requtes SQL sont diffuses (et non les donnes modifies). Si cette solution est inacceptable, le middleware ou
l'application doivent demander ces valeurs un seul serveur, et les utiliser dans des requtes d'criture. Une autre solution est
d'utiliser cette solution de rplication avec une configuration matre-esclave traditionnelle, c'est dire que les requtes de modification de donnes ne sont envoyes qu'au matre et sont propages aux esclaves via une rplication matre-esclave, pas par
le middleware de rplication. Il est impratif que toute transaction soit valide ou annule sur tous les serveurs, ventuellement par validation en deux phases (PREPARE TRANSACTION(7) et COMMIT PREPARED(7). Pgpool-II et Continuent
Tungsten sont des exemples de ce type de rplication.
Rplication asynchrone multi-matres
Pour les serveurs qui ne sont pas connects en permanence, comme les ordinateurs portables ou les serveurs distants, conserver la cohrence des donnes entre les serveurs est un challenge. L'utilisation de la rplication asynchrone multi-matres permet chaque serveur de fonctionner indpendamment. Il communique alors priodiquement avec les autres serveurs pour
identifier les transactions conflictuelles. La gestion des conflits est alors confie aux utilisateurs ou un systme de rgles de
rsolution. Bucardo est un exemple de ce type de rplication.
Rplication synchrone multi-matres
Dans les rplications synchrones multi-matres, tous les serveurs acceptent les requtes en criture. Les donnes modifies
sont transmises du serveur d'origine tous les autres serveurs avant toute validation de transaction.
Une activit importante en criture peut tre la cause d'un verrouillage excessif et conduire un effondrement des performances. Dans les faits, les performances en criture sont souvent pis que celles d'un simple serveur.
Tous les serveurs acceptent les requtes en lecture.
Certaines implantations utilisent les disques partags pour rduire la surcharge de communication.
Les performances de la rplication synchrone multi-matres sont meilleures lorsque les oprations de lecture reprsentent
l'essentiel de la charge, alors que son gros avantage est l'acceptation des requtes d'criture par tous les serveurs -- il n'est pas
ncessaire de rpartir la charge entre les serveurs matres et esclaves et, parce que les modifications de donnes sont envoyes
d'un serveur l'autre, les fonctions non dterministes, comme random(), ne posent aucun problme.
PostgreSQL n'offre pas ce type de rplication, mais la validation en deux phases de PostgreSQL (PREPARE TRANSACTION(7) et COMMIT PREPARED(7)) autorise son intgration dans une application ou un middleware.
Solutions commerciales
Parce que PostgreSQL est libre et facilement extensible, certaines socits utilisent PostgreSQL dans des solutions commerciales fermes (closed-source) proposant des fonctionnalits de bascule sur incident (failover), rplication et rpartition de
charge.
La Tableau 25.1, Matrice de fonctionnalits : haute disponibilit, rpartition de charge et rplication rsume les possibilits des
413

Haute disponibilit, rpartition de charge et


rplication
diffrentes solutions listes plus-haut.
Tableau 25.1. Matrice de fonctionnalits : haute disponibilit, rpartition de charge et rplication

Fonctionnali- Bascule par Rplication


t
disques parta- par systme
gs
(Shared de fichiers
Disk Failover)
Exemple
d'implmentati
on

NAS

DRBD

Mthode
de Disque partag Blocs disque
communication
Ne requiert aucun matriel
spcial

Secours semiautomatique
(Hot/Warm
Standby) par
PITR

Rplication
matre/esclave
bas sur les
triggers

PITR

Slony

pgpool-II

Bucardo

WAL

Lignes de
tables

SQL

Lignes de
tables

Lignes de
tables et verrous de ligne

Autorise plusieurs serveurs


matres
Pas de surcharge sur le
serveur matre

Pas d'attente
entre serveurs

Pas de perte de
donnes en cas
de panne du
matre

Les esclaves
acceptent les
requtes
en
lecture seule

Hot only

Granularit de
niveau table
Ne ncessite
pas de rsolution de conflit

Middleware
Rplication
Rplication
de rplication asynchrone
synchrone
sur instruc- multi-matres multi-matres
tions

Certaines solutions n'entrent pas dans les catgories ci-dessus :


Partitionnement de donnes
Le partitionnement des donnes divise les tables en ensembles de donnes. Chaque ensemble ne peut tre modifi que par un
seul serveur. Les donnes peuvent ainsi tre partitionnes par bureau, Londres et Paris, par exemple, avec un serveur dans
chaque bureau. Si certaines requtes doivent combiner des donnes de Londres et Paris, il est possible d'utiliser une application qui requte les deux serveurs ou d'implanter une rplication matre/esclave pour conserver sur chaque serveur une copie
en lecture seule des donnes de l'autre bureau.
Excution de requtes en parallle sur plusieurs serveurs
La plupart des solutions ci-dessus permettent plusieurs serveurs de rpondre des requtes multiples, mais aucune ne permet une seule requte d'tre excute sur plusieurs serveurs pour se terminer plus rapidement. Cette solution autorisent plusieurs serveurs travailler ensemble sur une seule requte. Ceci s'accomplit habituellement en rpartissant les donnes entre
les serveurs, chaque serveur excutant une partie de la requte pour renvoyer les rsultats un serveur central qui les combine
et les renvoie l'utilisateur. Pgpool-II offre cette possibilit. Cela peut galement tre implant en utilisant les outils PL/
Proxy.

414

Haute disponibilit, rpartition de charge et


rplication

25.2. Serveurs de Standby par transfert de journaux


L'archivage en continu peut tre utilis pour crer une configuration de cluster en haute disponibilit (HA) avec un ou plusieurs
serveurs de standby prts prendre la main sur les oprations si le serveur primaire fait dfaut. Cette fonctionnalit est gnralement appele warm standby ou log shipping.
Les serveurs primaire et de standby travaillent de concert pour fournir cette fonctionnalit, bien que les serveurs ne soient que faiblement coupls. Le serveur primaire opre en mode d'archivage en continu, tandis que le serveur de standby opre en mode de rcupration en continu, en lisant les fichiers WAL provenant du primaire. Aucune modification des tables de la base ne sont requises pour activer cette fonctionnalit, elle entrane donc moins de travail d'administration par rapport d'autres solutions de rplication. Cette configuration a aussi un impact relativement faible sur les performances du serveur primaire.
Dplacer directement des enregistrements de WAL d'un serveur de bases de donnes un autre est habituellement appel log shipping. PostgreSQL implmente le log shipping par fichier, ce qui signifie que les enregistrements de WAL sont transfrs un fichier (segment de WAL) la fois. Les fichiers de WAL (16Mo) peuvent tre transfrs facilement et de faon peu coteuse sur
n'importe quelle distance, que ce soit sur un systme adjacent, un autre systme sur le mme site, ou un autre systme l'autre
bout du globe. La bande passante requise pour cette technique varie en fonction du dbit de transactions du serveur primaire. La
technique de streaming replication permet d'optimiser cette bande passante en utilisant une granularit plus fine que le log shipping par fichier. Pour cela, les modifications apportes au journal de transactions sont traites sous forme de flux au travers d'une
connexion rseau (voir Section 25.2.5, Streaming Replication ).
Il convient de noter que le log shipping est asynchrone, c'est dire que les enregistrements de WAL sont transfrs aprs que la
transaction ait t valide. Par consquent, il y a un laps de temps pendant lequel une perte de donnes pourrait se produire si le
serveur primaire subissait un incident majeur; les transactions pas encore transfres seront perdues. La taille de la fentre de
temps de perte de donnes peut tre rduite par l'utilisation du paramtre archive_timeout, qui peut tre abaiss des valeurs
de quelques secondes. Toutefois, un paramtre si bas augmentera de faon considrable la bande passante ncessaire pour le transfert de fichiers. L'utilisation de la technique de streaming replication (voir Section 25.2.5, Streaming Replication ) permet de
diminuer la taille de la fentre de temps de perte de donnes.
La performance de la rcupration est suffisamment bonne pour que le standby ne soit en gnral qu' quelques instants de la
pleine disponibilit partir du moment o il aura t activ. C'est pour cette raison que cette configuration de haute disponibilit
est appele warm standby. Restaurer un serveur d'une base de sauvegarde archive, puis appliquer tous les journaux prendra largement plus de temps, ce qui fait que cette technique est une solution de 'disaster recovery' (reprise aprs sinistre), pas de haute disponibilit. Un serveur de standby peut aussi tre utilis pour des requtes en lecture seule, dans quel cas il est appel un serveur de
Hot Standby. Voir Section 25.5, Hot Standby pour plus d'information.

25.2.1. Prparatifs
Il est habituellement prfrable de crer les serveurs primaire et de standby de faon ce qu'ils soient aussi similaires que possible, au moins du point de vue du serveur de bases de donnes. En particulier, les chemins associs avec les tablespaces seront
passs d'un noeud l'autre sans conversion, ce qui implique que les serveurs primaire et de standby doivent avoir les mmes chemins de montage pour les tablespaces si cette fonctionnalit est utilise. Gardez en tte que si CREATE TABLESPACE(7) est
excut sur le primaire, tout nouveau point de montage ncessaire pour cela doit tre cr sur le primaire et tous les standby avant
que la commande ne soit excute. Le matriel n'a pas besoin d'tre exactement le mme, mais l'exprience monte que maintenir
deux systmes identiques est plus facile que maintenir deux diffrents sur la dure de l'application et du systme. Quoi qu'il en
soit, l'architecture hardware doit tre la mme -- rpliquer par exemple d'un serveur 32 bits vers un 64 bits ne fonctionnera pas.
De manire gnrale, le log shipping entre serveurs excutant des versions majeures diffrentes de PostgreSQL est impossible.
La politique du PostgreSQL Global Development Group est de ne pas raliser de changement sur les formats disques lors des
mises jour mineures, il est par consquent probable que l'excution de versions mineures diffrentes sur le primaire et le standby
fonctionne correctement. Toutefois, il n'y a aucune garantie formelle de cela et il est fortement conseill de garder le serveur primaire et celui de standby au mme niveau de version autant que faire se peut. Lors d'une mise jour vers une nouvelle version mineure, la politique la plus sre est de mettre jour les serveurs de standby d'abord -- une nouvelle version mineure est davantage
susceptible de lire les enregistrements WAL d'une ancienne version mineure que l'inverse.

25.2.2. Fonctionnement du Serveur de Standby


En mode de standby, le serveur applique continuellement les WAL reus du serveur matre. Le serveur de standby peut lire les
WAL d'une archive WAL (voir restore_command) ou directement du matre via une connexion TCP (streaming replication). Le
serveur de standby essaiera aussi de restaurer tout WAL trouv dans le rpertoire pg_xlog du cluster de standby. Cela se produit
habituellement aprs un redmarrage de serveur, quand le standby rejoue nouveau les WAL qui ont t reu du matre avant le
redmarrage, mais vous pouvez aussi copier manuellement des fichiers dans pg_xlog tout moment pour qu'ils soient rejous.
Au dmarrage, le serveur de standby commence par restaurer tous les WAL disponibles l'endroit o se trouvent les archives, en
appelant la restore_command. Une fois qu'il a puis tous les WAL disponibles cet endroit et que restore_command
choue, il essaye de restaurer tous les WAL disponibles dans le rpertoire pg_xlog. Si cela choue, et que la rplication en flux a
415

Haute disponibilit, rpartition de charge et


rplication
t active, le standby essaye de se connecter au serveur primaire et de dmarrer la rception des WAL depuis le dernier enregistrement valide trouv dans les archives ou pg_xlog. Si cela choue ou que la streaming replication n'est pas configure, ou que
la connexion est plus tard dconnecte, le standby retourne l'tape 1 et essaye de restaurer le fichier partir de l'archive nouveau. Cette boucle de retentatives de l'archive, pg_xlog et par la streaming replication continue jusqu' ce que le serveur soit
stopp ou que le failover (bascule) soit dclench par un fichier trigger (dclencheur).
Le mode de standby est quitt et le serveur bascule en mode de fonctionnement normal quand pg_ctl promote est excut ou
qu'un fichier de trigger est trouv (trigger_file). Avant de basculer, tout WAL immdiatement disponible dans l'archive ou
le pg_xlog sera restaur, mais aucune tentative ne sera faite pour se connecter au matre.

25.2.3. Prparer le Matre pour les Serveurs de Standby


Mettez en place un archivage en continu sur le primaire vers un rpertoire d'archivage accessible depuis le standby, comme dcrit
dans Section 24.3, Archivage continu et rcupration d'un instantan (PITR) . La destination d'archivage devrait tre accessible
du standby mme quand le matre est inaccessible, c'est dire qu'il devrait se trouver sur le serveur de standby lui-mme ou un
autre serveur de confiance, pas sur le serveur matre.
Si vous voulez utiliser la streaming replication, mettez en place l'authentification sur le serveur primaire pour autoriser les
connexions de rplication partir du (des) serveur de standby ; c'est--dire, crez un rle et mettez en place une ou des entres appropries dans pg_hba.conf avec le champ database positionn replication. Vrifiez aussi que max_wal_senders
est positionn une valeur suffisamment grande dans le fichier de configuration du serveur primaire.
Effectuez une sauvegarde de base comme dcrit dans Section 24.3.2, Raliser une sauvegarde de base pour initialiser le serveur de standby.

25.2.4. Paramtrer un Serveur de Standby


Pour paramtrer le serveur de standby, restaurez la sauvegarde de base effectu sur le serveur primaire (voir (see Section 24.3.3,
Rcupration partir d'un archivage continu ). Crez un fichier de commande de rcupration recovery.conf dans le rpertoire de donnes du cluster de standby, et positionnez standby_mode on. Positionnez restore_command une simple
commande qui recopie les fichiers de l'archive de WAL. Si vous comptez disposer de plusieurs serveurs de stanby pour mettre en
uvre de la haute disponibilit, dfinissez recovery_target_timeline latest, pour indiquer que le serveur de standby
devra prendre en compte la ligne temporelle dfinie lors de la bascule un autre serveur de standby.

Note
N'utilisez pas pg_standby ou des outils similaires avec le mode de standby intgr dcrit ici. restore_command
devrait retourner immdiatement si le fichier n'existe pas; le serveur essayera la commande nouveau si ncessaire.
Voir Section 25.4, Mthode alternative pour le log shipping pour utiliser des outils tels que pg_standby.
Si vous souhaitez utiliser la streaming replication, renseignez primary_conninfo avec une chane de connexion libpq, contenant le nom d'hte (ou l'adresse IP) et tout dtail supplmentaire ncessaire pour se connecter au serveur primaire. Si le primaire a
besoin d'un mot de passe pour l'authentification, le mot de passe doit aussi tre spcifi dans primary_conninfo.
Si vous mettez en place le serveur de standby pour des besoins de haute disponibilit, mettez en place l'archivage de WAL, les
connexions et l'authentification l'identique du serveur primaire, parce que le serveur de standby fonctionnera comme un serveur
primaire aprs la bascule.
Si vous utilisez une archive WAL, sa taille peut tre rduite en utilisant l'option archive_cleanup_command pour supprimer les fichiers qui ne sont plus ncessaires au serveur de standby. L'outil pg_archivecleanup est conu spcifiquement pour tre utilis
avec archive_cleanup_command dans des configurations typiques de standby, voir pg_archivecleanup. Notez toutefois que
si vous utilisez l'archive des fins de sauvegarde, vous avez besoin de garder les fichiers ncessaires pour restaurer partir de
votre dernire sauvegarde de base, mme si ces fichiers ne sont plus ncessaires pour le standby.
If you're using a WAL archive, its size can be minimized using the parameter to remove files that are no longer required by the
standby server. Note however, that if you're using the archive for backup purposes, you need to retain files needed to recover from
at least the latest base backup, even if they're no longer needed by the standby.
Un simple exemple de recovery.conf est:
standby_mode = 'on'
primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
restore_command = 'cp /path/to/archive/%f %p'
archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'
Vous pouvez avoir n'importe quel nombre de serveurs de standby, mais si vous utilisez la streaming replication, assurez vous
416

Haute disponibilit, rpartition de charge et


rplication
d'avoir positionn max_wal_senders suffisamment haut sur le primaire pour leur permettre de se connecter simultanment.

25.2.5. Streaming Replication


La streaming replication permet un serveur de standby de rester plus jour qu'il n'est possible avec l'envoi de journaux par fichiers. Le standby se connecte au primaire, qui envoie au standby les enregistrements de WAL ds qu'ils sont gnrs, sans attendre qu'un fichier de WAL soit rempli.
La streaming replication est asynchrone par dfaut (voir Section 25.2.6, Rplication synchrone ), auquel cas il y a un petit dlai
entre la validation d'une transaction sur le primaire et le moment o les changements sont visibles sur le standby. Le dlai est toutefois beaucoup plus petit qu'avec l'envoi de fichiers, habituellement en dessous d'une seconde en partant de l'hypothse que le
standby est suffisamment puissant pour supporter la charge. Avec la streaming replication, archive_timeout n'est pas ncessaire pour rduire la fentre de perte de donnes.
Si vous utilisez la streaming replication sans archivage en continu des fichiers, vous devez positionner wal_keep_segments
sur le matre une valeur suffisamment grande pour garantir que les anciens segments de WAL ne sont pas recycls trop tt, alors
que le standby pourrait toujours avoir besoin d'eux pour rattraper son retard. Si le standby prend trop de retard, il aura besoin d'tre
rinitialis partir d'une nouvelle sauvegarde de base. Si vous positionnez une archive de WAL qui est accessible du standby,
wal_keep_segments n'est pas ncessaire, puisque le standby peut toujours utiliser l'archive pour rattraper son retard.
Pour utiliser la streaming replication, mettez en place un serveur de standby en mode fichier comme dcrit dans Section 25.2,
Serveurs de Standby par transfert de journaux . L'tape qui transforme un standby en mode fichier en standby en streaming replication est de faire pointer primary_conninfo dans le fichier recovery.conf vers le serveur primaire. Positionnez listen_addresses et les options d'authentification (voir pg_hba.conf) sur le primaire pour que le serveur de standby puisse se
connecter la pseudo-base replication sur le serveur primaire (voir Section 25.2.5.1, Authentification ).
Sur les systmes qui supportent l'option de keepalive sur les sockets, positionner tcp_keepalives_idle, tcp_keepalives_interval et
tcp_keepalives_count aide le primaire reconnatre rapidement une connexion interrompue.
Positionnez le nombre maximum de connexions concurrentes partir des serveurs de standby (voir max_wal_senders pour les dtails).
Quand le standby est dmarr et que primary_conninfo est positionn correctement, le standby se connectera au primaire
aprs avoir rejou tous les fichiers WAL disponibles dans l'archive. Si la connexion est tablie avec succs, vous verrez un processus walreceiver dans le standby, et un processus walsender correspondant sur le primaire.

25.2.5.1. Authentification
Il est trs important que les privilges d'accs pour la rplications soient paramtrs pour que seuls les utilisateurs de confiance
puissent lire le flux WAL, parce qu'il est facile d'en extraire des informations privilgies. Les serveurs de standby doivent
s'authentifier sur le primaire avec un compte dot de l'attribut REPLICATION. Par consquent, un rle avec les attributs REPLICATION et LOGIN doit tre cr sur le primaire.

Note
Il est recommand d'utiliser un compte utilisateur spcifique pour la rplication. Bien que l'attribut REPLICATION
soit accord aux comptes superutilisateurs par dfaut, il n'est pas recommand d'utiliser un compte superutilisateur
pour la rplication. Mme si l'attribut REPLICATION laisse beaucoup de libert un utilisateur, il ne l'autorise pas
modifier les donnes sur le primaire, alors que l'attribut SUPERUSER le permet.
L'authentification cliente pour la rplication est contrle par un enregistrement de pg_hba.conf spcifiant replication
dans le champ database. Par exemple, si le standby s'excute sur un hte d'IP 192.168.1.100 et que le nom de l'utilisateur
pour la rplication est foo, l'administrateur peut ajouter la ligne suivante au fichier pg_hba.conf sur le primaire:
# Autoriser l'utilisateur "foo" de l'hte 192.168.1.100 se connecter au primaire
# en tant que standby de replication si le mot de passe de l'utilisateur est
correctement fourni
#
# TYPE DATABASE
USER
ADDRESS
METHOD
host
replication
foo
192.168.1.100/32
md5
Le nom d'hte et le numro de port du primaire, le nom d'utilisateur de la connexion, et le mot de passe sont spcifis dans le fichier recovery.conf. Le mot de passe peut aussi tre enregistr dans le fichier ~/.pgpass sur le serveur en attente (en prcisant replication dans le champ database). Par exemple, si le primaire s'excute sur l'hte d'IP 192.168.1.50, port
5432, que le nom de l'utilisateur pour la rplication est foo, et que le mot de passe est foopass, l'administrateur peut ajouter la
417

Haute disponibilit, rpartition de charge et


rplication
ligne suivante au fichier recovery.conf sur le standby:
# Le standby se connecte au primaire qui s'excute sur l'hte 192.168.1.50
# et port 5432 en tant qu'utilisateur "foo" dont le mot de passe est "foopass"
primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'

25.2.5.2. Supervision
Un important indicateur de sant de la streaming replication est le nombre d'enregistrements gnrs sur le primaire, mais pas encore appliqus sur le standby. Vous pouvez calculer ce retard en comparant le point d'avancement des critures du WAL sur le primaire avec le dernier point d'avancement reu par le standby. Ils peuvent tre rcuprs en utilisant
pg_current_xlog_location sur le primaire et pg_last_xlog_receive_location sur le standby, respectivement
(voir Tableau 9.56, Fonctions de contrle de la sauvegarde et Tableau 9.57, Fonctions d'information sur la restauration
pour plus de dtails). Le point d'avancement de la rception dans le standby est aussi affich dans le statut du processus de rception des WAL (wal receiver), affich par la commande ps (voyez Section 27.1, Outils Unix standard pour plus de dtails).
Vous pouvez obtenir la liste des processus metteurs de WAL au moyen de la vue pg_stat_replication D'importantes diffrences entre les champs pg_current_xlog_location et sent_location peuvent indiquer que le serveur matre est en
surcharge, tandis que des diffrences entre sent_location et pg_last_xlog_receive_location sur le standby
peuvent soit indiquer une latence rseau importante, soit que le standby est surcharg.

25.2.6. Rplication synchrone


La streaming rplication mise en uvre par PostgreSQL est asynchrone par dfaut. Si le serveur primaire est hors-service, les
transactions produites alors peuvent ne pas avoir t rpliques sur le serveur de standby, impliquant une perte de donnes. La
quantit de donnes perdues est proportionnelle au dlai de rplication au moment de la bascule.
La rplication synchrone permet de confirmer que tous les changements effectus par une transaction ont bien t transfres un
serveur de standby synchrone. Cette proprit tend le niveau de robustesse standard offert par un commit. En science informatique, ce niveau de protection est appel 2-safe replication.
Lorsque la rplication synchrone est utilise, chaque validation portant sur une criture va ncessiter d'attendre la confirmation de
l'criture de cette validation sur les journaux de transaction des disques du serveur primaire et des serveurs en standby. Le seul
moyen possible pour que des donnes soient perdues est que les serveur primaire et de standby soient hors service au mme moment. Ce mcanisme permet d'assurer un niveau plus lev de robustesse, en admettant que l'administrateur systme ait pris garde
l'emplacement et la gestion de ces deux serveurs. Attendre aprs la confirmation de l'criture augmente la confiance que
l'utilisateur pourra avoir sur la conservation des modifications dans le cas o un serveur serait hors service mais il augmente aussi
en consquence le temps de rponse chaque requte. Le temps minimum d'attente est celui de l'aller-retour entre les serveurs primaire et de standby.
Les transactions o seule une lecture est effectue ou qui consistent annuler une transaction ne ncessitent pas d'attendre les serveurs de standby. Les validations concernant les transactions imbriques ne ncessitent pas non plus d'attendre la rponse des serveurs de standby, cela n'affecte en fait que les validations principales. De longues oprations comme le chargement de donnes ou
la cration d'index n'attendent pas le commit final pour synchroniser les donnes. Toutes les actions de validation en deux tapes
ncessitent d'attendre la validation du standby, incluant autant l'opration de prparation que l'opration de validation.

25.2.6.1. Configuration de base


Une fois la streaming replication configure, la configuration de la rplication synchrone ne demande qu'une unique tape de
configuration supplmentaire : la variable synchronous_standby_names doit tre dfinie une valeur non vide. La variable synchronous_commit doit aussi tre dfinie on, mais comme il s'agit d'une valeur par dfaut, il n'est pas ncessaire de la modifier. Cette configuration va entraner l'attente de la confirmation de l'criture permanente de chaque validation sur le serveur de
standby, mme si cette criture peut s'avrer tre longue. La variable synchronous_commit peut tre dfinie soit par des utilisateurs, soit par le fichier de configuration pour des utilisateurs ou des bases de donnes fixes, soit dynamiquement par des applications, pour contrler la robustesse des changes transactionnels.
Suite l'enregistrement sur disque d'une validation sur le serveur primaire, l'enregistrement WAL est envoy au serveur de standby. Le serveur de standby retourne une rponse chaque fois qu'un nouveau lot de donnes WAL est crit sur disque, moins que
la variable wal_receiver_status_interval soit dfinie zro sur le serveur de standby. Lorsque le premier serveur de
standby est sollicit, tel que spcifi dans la variable synchronous_standby_names sur le serveur primaire, la rponse de
ce serveur de standby sera utilise pour prvenir les utilisateurs en attente de confirmation de l'enregistrement du commit. Ces paramtres permettent l'administrateur de spcifier quels serveurs de standby suivront un comportement synchrone. Remarquez ici
que la configuration de la rplication synchrone se situe sur le serveur matre.
Habituellement, un signal d'arrt rapide (fast shutdown) annule les transactions en cours sur tous les processus serveur. Cependant,
dans le cas de la rplication asynchrone, le serveur n'effectuera pas un arrt complet avant que chaque enregistrement WAL ne soit
418

Haute disponibilit, rpartition de charge et


rplication
transfr aux serveurs de standby connects.

25.2.6.2. S'organiser pour obtenir de bonnes performances


La rplication synchrone ncessite souvent d'organiser avec une grande attention les serveurs de standby pour apporter un bon niveau de performances aux applications. Les phases d'attente d'criture n'utilisent pas les ressources systmes, mais les verrous
transactionnels restent positionns jusqu' ce que le transfert vers les serveurs de standby soit confirm. En consquence, une utilisation non avertie de la rplication synchrone aura pour impact une baisse des performances de la base de donne d'une application due l'augmentation des temps de rponses et un moins bon support de la charge.
PostgreSQL permet aux dveloppeurs d'application de spcifier le niveau de robustesse employer pour la rplication. Cela
peut tre spcifi pour le systme entier, mais aussi pour des utilisateurs ou des connexions spcifiques, ou encore pour des transactions individuelles.
Par exemple, une rpartition du travail pour une application pourrait tre constitue de : 10 % de modifications concernant des articles de clients importants, et 90 % de modifications de moindre importance et qui ne devraient pas avoir d'impact sur le mtier si
elles venaient tre perdues, comme des dialogues de messagerie entre utilisateurs.
Les options de rplication synchrone spcifies par une application (sur le serveur primaire) permettent de n'utiliser la rplication
synchrone que pour les modifications les plus importantes, sans affecter les performances sur la plus grosse partie des traitements.
Les options modifiables par les applications sont un outil important permettant d'apporter les bnfices de la rplication synchrone
aux applications ncessitant de la haute performance.
Il est conseill de disposer d'une bande passante rseau suprieure la quantit de donnes WAL gnres.

25.2.6.3. S'organiser pour la haute disponibilit


Les oprations de validation effectues avec la variable synchronous_commit dfinie on ncessiteront d'attendre la rponse
du serveur de standby. Cette rponse pourrait ne jamais arriver si le seul ou le dernier serveur de standby venait tre hors service.
La meilleure solution pour viter la perte de donnes est de s'assurer de ne jamais perdre le dernier serveur de standby. Cette politique peut tre mise en oeuvre en dfinissant plusieurs serveurs de standby via la variable synchronous_standby_names.
Le premier serveur de standby nomm dans cette variable sera utilis comme serveur de standby synchrone. Les serveurs suivants
prendront le rle de serveur de standby synchrone si le premier venait tre hors service.
Au moment o le premier serveur de standby s'attache au serveur primaire, il est possible qu'il ne soit pas exactement synchronis.
Cet tat est appel le mode catchup. Une fois la diffrence entre le serveur de standby et le serveur primaire ramene zro, le
mode streaming est atteint. La dure du mode catchup peut tre longue surtout juste aprs la cration du serveur de standby. Si
le serveur de standby est arrt sur cette priode, alors la dure du mode CATCHUP sera d'autant plus longue. Le serveur de
standby ne peut devenir un serveur de standby synchrone que lorsque le mode streaming est atteint.
Si le serveur primaire redmarre alors que des oprations de commit taient en attente de confirmation, les transactions en attente
ne seront rellement enregistres qu'au moment o la base de donne du serveur primaire sera redmarre. Il n'y a aucun moyen de
savoir si tous les serveurs de standby ont reu toutes les donnes WAL ncessaires au moment o le serveur primaire est dclar
hors-service. Des transactions pourraient ne pas tre considres comme sauvegardes sur le serveur de standby, mme si elles
l'taient sur le serveur primaire. La seule garantie offerte dans ce cadre est que l'application ne recevra pas de confirmation explicite de la russite d'une opration de validation avant qu'il soit sr que les donnes WAL sont reues proprement par le serveur de
standby.
Si le dernier serveur de standby est perdu, il est conseill de dsactiver la variable synchronous_standby_names et de recharger le fichier de configuration sur le serveur primaire.
Si le serveur primaire n'est pas accessible par les serveurs de standby restants, il est conseill de basculer vers le meilleur candidat
possible parmi ces serveurs de standby.
S'il est ncessaire de recrer un serveur de standby alors que des transactions sont en attente de confirmation, prenez garde ce
que les commandes pg_start_backup() et pg_stop_backup() soient excutes dans un contexte o la variable synchronous_commit vaut off car, dans le cas contraire, ces requtes attendront indfiniment l'apparition de ce serveur de standby.

25.3. Bascule (Failover)


Si le serveur primaire plante alors le serveur de standby devrait commencer les procdures de failover.
Si le serveur de standby plante alors il n'est pas ncessaire d'effectuer un failover. Si le serveur de standby peut tre redmarr,
mme plus tard, alors le processus de rcupration peut aussi tre redmarr au mme moment, en bnficiant du fait que la rcupration sait reprendre o elle en tait. Si le serveur de standby ne peut pas tre redmarr, alors une nouvelle instance complte
de standby devrait tre cr.
Si le serveur primaire plante, que le serveur de standby devient le nouveau primaire, et que l'ancien primaire redmarre, vous de419

Haute disponibilit, rpartition de charge et


rplication
vez avoir un mcanisme pour informer l'ancien primaire qu'il n'est plus primaire. C'est aussi quelquefois appel STONITH (Shoot
The Other Node In The Head, ou Tire Dans La Tte De L'Autre Noeud), qui est ncessaire pour viter les situations o les deux
systmes pensent qu'ils sont le primaire, ce qui amnerait de la confusion, et finalement de la perte de donnes.
Beaucoup de systmes de failover n'utilisent que deux systmes, le primaire et le standby, connects par un mcanisme de type
ligne de vie (heartbeat) pour vrifier continuellement la connexion entre les deux et la viabilit du primaire. Il est aussi possible
d'utiliser un troisime systme (appel un serveur tmoin) pour viter certains cas de bascule inappropris, mais la complexit supplmentaire peut ne pas tre justifie moins d'tre mise en place avec suffisamment de prcautions et des tests rigoureux.
PostgreSQL ne fournit pas le logiciel systme ncessaire pour identifier un incident sur le primaire et notifier le serveur de base
de standby. De nombreux outils de ce genre existent et sont bien intgrs avec les fonctionnalits du systme d'exploitation ncessaires la bascule, telles que la migration d'adresse IP.
Une fois que la bascule vers le standby se produit, il n'y a plus qu'un seul serveur en fonctionnement. C'est ce qu'on appelle un tat
dgrad. L'ancien standby est maintenant le primaire, mais l'ancien primaire est arrt et pourrait rester arrt. Pour revenir un
fonctionnement normal, un serveur de standby doit tre recr, soit sur l'ancien systme primaire quand il redevient disponible, ou
sur un troisime, peut tre nouveau, systme. Une fois que ceci est effectu, le primaire et le standby peuvent tre considrs
comme ayant chang de rle. Certaines personnes choisissent d'utiliser un troisime serveur pour fournir une sauvegarde du nouveau primaire jusqu' ce que le nouveau serveur de standby soit recr, bien que ceci complique visiblement la configuration du
systme et les procdures d'exploitation.
Par consquent, basculer du primaire vers le serveur de standby peut tre rapide mais requiert du temps pour re-prparer le cluster
de failover. Une bascule rgulire du primaire vers le standby est utile, car cela permet une priode d'interruption de production
sur chaque systme pour maintenance. Cela vous permet aussi pour vous assurer que votre mcanisme de bascule fonctionnera
rellement quand vous en aurez besoin. Il est conseill que les procdures d'administration soient crites.
Pour dclencher le failover d'un serveur de standby en log-shipping, excutez la commande pg_ctl promote ou crez un fichier
trigger (dclencheur) avec le nom de fichier et le chemin spcifis par le paramtre trigger_file de recovery.conf. Si
vous comptez utiliser la commande pg_ctl promote pour effectuer la bascule, la variable trigger_file n'est pas ncessaire.
S'il s'agit d'ajouter des serveurs qui ne seront utiliss que pour allger le serveur primaire des requtes en lecture seule, et non pas
pour des considrations de haute disponibilit, il n'est pas ncessaire de les rveiller (promote).

25.4. Mthode alternative pour le log shipping


Une alternative au mode de standby intgr dcrit dans les sections prcdentes est d'utiliser une restore_command qui scrute
le dpt d'archives. C'tait la seule mthode disponible dans les versions 8.4 et infrieures. Dans cette configuration, positionnez
standby_mode off, parce que vous implmentez la scrutation ncessaire au fonctionnement standby vous-mmes. Voir le module pg_standby pour une implmentation de rfrence de ceci.
Veuillez noter que dans ce mode, le serveur appliquera les WAL fichier par fichier, ce qui entrane que si vous requtez sur le serveur de standby (voir Hot Standby), il y a un dlai entre une action sur le matre et le moment o cette action devient visible sur le
standby, correspondant au temps ncessaire remplir le fichier de WAL. archive_timeout peut tre utilis pour rendre ce dlai plus court. Notez aussi que vous ne pouvez combiner la streaming replication avec cette mthode.
Les oprations qui se produisent sur le primaire et les serveurs de standby sont des oprations normales d'archivage et de recovery.
Le seul point de contact entre les deux serveurs de bases de donnes est l'archive de fichiers WAL qu'ils partagent: le primaire
crivant dans l'archive, le secondaire lisant de l'archive. Des prcautions doivent tre prises pour s'assurer que les archives WAL
de serveurs primaires diffrents ne soient pas mlanges ou confondues. L'archive n'a pas besoin d'tre de grande taille si elle n'est
utilise que pour le fonctionnement de standby.
La magie qui permet aux deux serveurs faiblement coupls de fonctionner ensemble est une simple restore_command utilise
sur le standby qui quand on lui demande le prochain fichier de WAL, attend que le primaire le mette disposition. La restore_command est spcifie dans le fichier recovery.conf sur le serveur de standby. La rcupration normale demanderait
un fichier de l'archive WAL, en retournant un chec si le fichier n'tait pas disponible. Pour un fonctionnement en standby, il est
normal que le prochain fichier WAL ne soit pas disponible, ce qui entrane que le standby doive attendre qu'il apparaisse. Pour les
fichiers se terminant en .backup ou .history il n'y a pas besoin d'attendre, et un code retour diffrent de zro doit tre retourn. Une restore_command d'attente peut tre crite comme un script qui boucle aprs avoir scrut l'existence du prochain fichier de WAL. Il doit aussi y avoir un moyen de dclencher la bascule, qui devrait interrompre la restore_command , sortir le
la boucle et retourner une erreur file-not-found au serveur de standby. Cela met fin la rcupration et le standby dmarrera alors
comme un serveur normal.
Le pseudocode pour une restore_command approprie est:
triggered = false;
while (!NextWALFileReady() && !triggered)
{
420

Haute disponibilit, rpartition de charge et


rplication
sleep(100000L);
/* wait for ~0.1 sec */
if (CheckForExternalTrigger())
triggered = true;
}
if (!triggered)
CopyWALFileForRecovery();
Un exemple fonctionnel de restore_command d'attente est fournie par le module pg_standby. Il devrait tre utilis en tant que
rfrence, comme la bonne faon d'implmenter correctement la logique dcrite ci-dessus. Il peut aussi tre tendu pour supporter
des configurations et des environnements spcifiques.
La mthode pour dclencher une bascule est une composante importante de la planification et de la conception. Une possibilit est
d'utiliser la commande restore_command. Elle est excute une fois pour chaque fichier WAL, mais le processus excutant la
restore_command est cr et meurt pour chaque fichier, il n'y a donc ni dmon ni processus serveur, et on ne peut utiliser ni
signaux ni gestionnaire de signaux. Par consquent, la restore_command n'est pas approprie pour dclencher la bascule. Il
est possible d'utiliser une simple fonctionnalit de timeout, particulirement si utilise en conjonction avec un paramtre archive_timeout sur le primaire. Toutefois, ceci est sujet erreur, un problme rseau ou un serveur primaire charg pouvant
suffire dclencher une bascule. Un systme de notification comme la cration explicite d'un fichier trigger est idale, dans la mesure du possible.

25.4.1. Implmentation
La procdure simplifi pour configurer un serveur de test en utilisant cette mthode alternative est la suivante. Pour tous les dtails
sur chaque tape, rfrez vous aux sections prcdentes suivant les indications.
1. Paramtrez les systmes primaire et standby de faon aussi identique que possible, y compris deux copies identiques de PostgreSQL au mme niveau de version.
2. Activez l'archivage en continu du primaire vers un rpertoire d'archives WAL sur le serveur de standby. Assurez vous que archive_mode, archive_command et archive_timeout sont positionns correctement sur le primaire (voir Section 24.3.1,
Configurer l'archivage WAL ).
3. Effectuez une sauvegarde de base du serveur primaire( voir Section 24.3.2, Raliser une sauvegarde de base ), , et chargez
ces donnes sur le standby.
4. Commencez la rcupration sur le serveur de standby partir de l'archive WAL locale, en utilisant un recovery.conf qui
spcifie une restore_command qui attend comme dcrit prcdemment (voir Section 24.3.3, Rcupration partir d'un
archivage continu ).
Le rcupration considre l'archive WAL comme tant en lecture seule, donc une fois qu'un fichier WAL a t copi sur le systme de standby il peut tre copi sur bande en mme temps qu'il est lu par le serveur de bases de donnes de standby. Ainsi, on
peut faire fonctionner un serveur de standby pour de la haute disponibilit en mme temps que les fichiers sont stocks pour de la
reprise aprs sinistre.
des fins de test, il est possible de faire fonctionner le serveur primaire et de standby sur le mme systme. Cela n'apporte rien en
termes de robustesse du serveur, pas plus que cela ne pourrait tre dcrit comme de la haute disponibilit.
.

25.4.2. Log Shipping par Enregistrements


Il est aussi possible d'implmenter du log shipping par enregistrements en utilisant cette mthode alternative, bien qu'elle ncessite
des dveloppements spcifiques, et que les modifications ne seront toujours visibles aux requtes de hot standby qu'aprs que le fichier complet de WAL ait t recopi.
Un programme externe peut appeler la fonction pg_xlogfile_name_offset() (voir Section 9.24, Fonctions
d'administration systme ) pour obtenir le nom de fichier et la position exacte en octets dans ce fichier de la fin actuelle du WAL.
Il peut alors accder au fichier WAL directement et copier les donnes de la fin prcdente connue la fin courante vers les serveurs de standby. Avec cette approche, la fentre de perte de donnes est la priode de scrutation du programme de copie, qui peut
tre trs petite, et il n'y a pas de bande passante gaspille en forant l'archivage de fichiers WAL partiellement remplis. Notez que
les scripts restore_command des serveurs de standby ne peuvent traiter que des fichiers WAL complets, les donnes copies
de faon incrmentale ne sont donc d'ordinaire pas mises disposition des serveurs de standby. Elles ne sont utiles que si le serveur primaire tombe -- alors le dernier fichier WAL partiel est fourni au standby avant de l'autoriser s'activer. L'implmentation
correcte de ce mcanisme requiert la coopration entre le script restore_command et le programme de recopie des donnes.
partir de PostgreSQL version 9.0, vous pouvez utiliser la streaming replication (voir Section 25.2.5, Streaming Replication ) pour bnficier des mmes fonctionnalits avec moins d'efforts.
421

Haute disponibilit, rpartition de charge et


rplication

25.5. Hot Standby


Hot Standby est le terme utilis pour dcrire la possibilit de se connecter et d'excuter des requtes en lecture seule alors que le
serveur est en rcupration d'archive or standby mode. C'est utile la fois pour la rplication et pour restaurer une sauvegarde un
tat dsir avec une grande prcision. Le terme Hot Standby fait aussi rfrence la capacit du serveur passer de la rcupration au fonctionnement normal tandis-que les utilisateurs continuent excuter des requtes et/ou gardent leurs connexions ouvertes.
Excuter des requtes en mode hot standby est similaire au fonctionnement normal des requtes, bien qu'il y ait quelques diffrences d'utilisation et d'administration notes ci-dessous.

25.5.1. Aperu pour l'utilisateur


Quand le paramtre hot_standby est configur true sur un serveur en attente, le serveur commencera accepter les connexions
une fois que la restauration est parvenue un tat cohrent. Toutes les connexions qui suivront seront des connexions en lecture
seule ; mme les tables temporaires ne pourront pas tre utilises.
Les donnes sur le standby mettent un certain temps pour arriver du serveur primaire, il y aura donc un dlai mesurable entre primaire et standby. La mme requte excute presque simultanment sur le primaire et le standby pourrait par consquent retourner
des rsultats diffrents. On dit que la donne est cohrente terme avec le primaire. Une fois que l'enregistrement de validation
(COMMIT) d'une transaction est rejou sur le serveur en attente, les modifications ralises par cette transaction seront visibles
par toutes les images de bases obtenues par les transactions en cours sur le serveur en attente. Ces images peuvent tre prises au
dbut de chaque requte ou de chaque transaction, suivant le niveau d'isolation des transactions utilis ce moment. Pour plus de
dtails, voir Section 13.2, Isolation des transactions .
Les transactions excutes pendant la priode de restauration sur un serveur en mode hotstandby peuvent inclure les commandes
suivantes :

Accs par requte - SELECT, COPY TO

Commandes de curseur - DECLARE, FETCH, CLOSE

Paramtres - SHOW, SET, RESET

Commandes de gestion de transaction

BEGIN, END, ABORT, START TRANSACTION

SAVEPOINT, RELEASE, ROLLBACK TO SAVEPOINT

Blocs d'EXCEPTION et autres sous-transactions internes

LOCK TABLE, mais seulement quand explicitement dans un de ces modes: ACCESS SHARE, ROW SHARE ou ROW EXCLUSIVE.

Plans et ressources - PREPARE, EXECUTE, DEALLOCATE, DISCARD

Plugins et extensions - LOAD

Les transactions lances pendant la restauration d'un serveur en hotstandby ne se verront jamais affectes un identifiant de transactions et ne peuvent pas tre crites dans les journaux de transactions. Du coup, les actions suivantes produiront des messages
d'erreur :

Langage de Manipulation de Donnes (LMD ou DML) - INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE. Notez qu'il n'y a pas d'action autorise qui entranerait l'excution d'un trigger pendant la rcupration. Cette restriction s'applique
mme pour les tables temporaires car les lignes de ces tables ne peuvent tre lues et crites s'il n'est pas possible d'affecter un
identifiant de transactions, ce qui n'est actuellement pas possible dans un environnement Hot Standby.

Langage de Dfinition de Donnes (LDD ou DDL) - CREATE, DROP, ALTER, COMMENT. Cette restriction s'applique
aussi aux tables temporaires car, pour mener bien ces oprations, cela ncessiterait de mettre jour les catalogues systmes.

SELECT ... FOR SHARE | UPDATE, car les verrous de lignes ne peuvent pas tre pris sans mettre jour les fichiers de
donnes.

Rules sur des ordres SELECT qui gnrent des commandes LMD.

LOCK qui demandent explicitement un mode suprieur ROW EXCLUSIVE MODE.

LOCK dans sa forme courte par dfaut, puisqu'il demande ACCESS EXCLUSIVE MODE.
422

Haute disponibilit, rpartition de charge et


rplication

Commandes de gestion de transaction qui positionnent explicitement un tat n'tant pas en lecture-seule:

BEGIN READ WRITE, START TRANSACTION READ WRITE

SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE

SET transaction_read_only = off

Commandes de two-phase commit PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED


parce que mme les transactions en lecture seule ont besoin d'crire dans le WAL durant la phase de prparation (la premire
des deux phases du two-phase commit).

Mise jour de squence - nextval(), setval()

LISTEN, UNLISTEN, NOTIFY

Dans le cadre normal, les transactions en lecture seule permettent la mise jour des squences et l'utilisation des instructions
LISTEN, UNLISTEN et NOTIFY, donc les sessions Hot Standby ont des restrictions lgrement infrieures celles de sessions
en lecture seule ordinaires. Il est possible que certaines des restrictions soient encore moins importantes dans une prochaine version.
Lors du fonctionnement en serveur hotstandby, le paramtre transaction_read_only est toujours true et ne peut pas tre
modifi. Tant qu'il n'y a pas de tentative de modification sur la base de donnes, les connexions sur un serveur en hotstandby se
comportent de faon pratiquement identiques celles sur un serveur normal. Quand une bascule (failover ou switchover) survient,
la base de donnes bascule dans le mode de traitement normal. Les sessions resteront connectes pendant le changement de mode.
Quand le mode hotstandby est termin, il sera possible de lancer des transactions en lecture/criture, y compris pour les sessions
connectes avant la bascule.
Les utilisateurs pourront dterminer si leur session est en lecture seule en excutant SHOW transaction_read_only. De plus, un
jeu de fonctions (Tableau 9.57, Fonctions d'information sur la restauration ) permettent aux utilisateurs d' accder des informations propos du serveur de standby. Ceci vous permet d'crire des programmes qui sont conscients de l'tat actuel de la base.
Vous pouvez vous en servir pour superviser l'avancement de la rcupration, ou pour crire des programmes complexes qui restaurent la base dans des tats particuliers.

25.5.2. Gestion des conflits avec les requtes


Les noeuds primaire et standby sont de bien des faons faiblement coupls. Des actions sur le primaire auront un effet sur le standby. Par consquent, il y a un risque d'interactions ngatives ou de conflits entre eux. Le conflit le plus simple comprendre est la
performance : si un gros chargement de donnes a lieu sur le primaire, il gnrera un flux similaire d'enregistrements WAL sur le
standby, et les requtes du standby pourrait entrer en comptition pour les ressources systmes, comme les entres-sorties.
Il y a aussi d'autres types de conflits qui peuvent se produire avec le Hot Standby. Ces conflits sont des conflits durs dans le sens
o des requtes pourraient devoir tre annules et, dans certains cas, des sessions dconnectes, pour les rsoudre. L'utilisateur
dispose de plusieurs moyens pour grer ces conflits. Voici les diffrents cas de conflits possibles :

Des verrous en accs exclusif pris sur le serveur matre, incluant la fois les commandes LOCK exclusives et quelques actions de type DDL, entrent en conflit avec les accs de table des requtes en lecture seule.

La suppression d'un tablespace sur le serveur matre entre en conflit avec les requtes sur le serveur standby qui utilisent ce tablespace pour les fichiers temporaires.

La suppression d'une base de donnes sur le serveur matre entre en conflit avec les sessions connectes sur cette base de donnes sur le serveur en attente.

La copie d'un enregistrement nettoy par un VACUUM entre en conflit avec les transactions sur le serveur en attente qui
peuvent toujours voir au moins une des lignes supprimer.

La copie d'un enregistrement nettoy par un VACUUM entre en conflit avec les requtes accdant la page cible sur le serveur en attente, qu'elles voient ou non les donnes supprimer.

Sur le serveur matre, ces cas rsultent en une attente supplmentaire ; l'utilisateur peut choisir d'annuler une des actions en conflit.
Nanmoins, sur le serveur en attente, il n'y a pas de choix possibles : l'action enregistre dans les journaux de transactions est dj
survenue sur le serveur matre et le serveur en standby doit absolument russir l'appliquer. De plus, permettre que
l'enregistrement de l'action attende indfiniment pourrait avoir des effets fortement non dsirables car le serveur en attente sera de
plus en plus en retard par rapport au matre. Du coup, un mcanisme est fourni pour forcer l'annulation des requtes sur le serveur
en attente qui entreraient en conflit avec des enregistrements des journaux de transactions en attente.

423

Haute disponibilit, rpartition de charge et


rplication
Voici un exemple de problme type : un administrateur excute un DROP TABLE sur une table du serveur matre qui est actuellement utilis dans des requtes du serveur en attente. Il est clair que la requte ne peut pas continuer s'excuter si
l'enregistrement dans les journaux de transactions, correspondant au DROP TABLE est appliqu sur le serveur en attente. Si cette
situation survient sur le serveur matre, l'instruction DROP TABLE attendra jusqu' ce que l'autre requte se termine. Par contre,
quand le DROP TABLE est excut sur le serveur matre, ce dernier ne sait pas les requtes en cours d'excution sur le serveur en
attente, donc il n'attendra pas la fin de l'excution des requtes sur le serveur en attente. L'enregistrement de cette modification
dans les journaux de transactions arrivera au serveur en attente alors que la requte sur le serveur en attente est toujours en cours
d'excution, causant un conflit. Le serveur en attente doit soit retarder l'application des enregistrements des journaux de transactions (et tous ceux qui sont aprs aussi) soit annuler la requte en conflit, pour appliquer l'instruction DROP TABLE.
Quand une requte en conflit est courte, il est gnralement prfrable d'attendre un peu pour l'application du journal de transactions. Mais un dlai plus long n'est gnralement pas souhaitable. Donc, le mcanisme d'annulation dans l'application des enregistrements de journaux de transactions dispose de deux paramtres, max_standby_archive_delay et max_standby_streaming_delay,
qui dfinissent le dlai maximum autoris pour appliquer les enregistrements. Les requtes en conflit seront annules si
l'application des enregistrements prend plus de temps que celui dfini. Il existe deux paramtres pour que des dlais diffrents
puissent tre observs suivant le cas : lecture des enregistrements partir d'un journal archiv (par exemple lors de la restauration
initiale partir d'une sauvegarde ou lors d'un rattrapage si le serveur en attente accumulait du retard par rapport au matre) et
lecture des enregistrements partir de la rplication en flux.
Pour un serveur en attente dont le but principal est la haute-disponibilit, il est prfrable de configurer des valeurs assez basses
pour les paramtres de dlai, de faon ce que le serveur en attente ne soit pas trop en retard par rapport au serveur matre cause
des dlais suivis cause des requtes excutes sur le serveur en attente. Par contre, si le serveur en attente doit excuter des requtes longues, alors une valeur haute, voire infinie, du dlai pourrait tre prfrable. Nanmoins, gardez en tte qu'une requte
mettant du temps s'excuter pourrait empcher les autres requtes de voir les modifications rcentes sur le serveur primaire si
elle retarde l'application des enregistrements de journaux de transactions.
Une fois que le dlai spcifi par max_standby_archive_delay ou max_standby_streaming_delay a t dpass,
toutes les requtes en conflit seront annules. Ceci rsulte habituellement en une erreur d'annulation, bien que certains cas, comme
un DROP DATABASE, peuvent occassionner l'arrt complet de la connexion. De plus, si le conflit intervient sur un verrou dtenu par une transaction en attente, la session en conflit sera termine (ce comportement pourrait changer dans le futur).
Les requtes annules peuvent tre r-excutes immdiatement (aprs avoir commenc une nouvelle transaction, bien sr).
Comme l'annulation des requtes dpend de la nature des enregistrements dans le journal de transactions, une requte annule
pourrait trs bien russir si elle est de nouveau excute.
Gardez en tte que les paramtres de dlai sont compars au temps pass depuis que la donne du journal de transactions a t
reue par le serveur en attente. Du coup, la priode de grce accorde aux requtes n'est jamais suprieur au paramtre de dlai, et
peut tre considrablement infrieur si le serveur en attente est dj en retard suite l'attente de la fin de l'excution de requtes
prcdentes ou suite son impossibilit de conserver le rythme d'une grosse mise jour.
La raison la plus frquente des conflits entre les requtes en lecture seule et le rejeu des journaux de transactions est le nettoyage
avanc . Habituellement, PostgreSQL permet le nettoyage des anciennes versions de lignes quand aucune transaction ne peut
les voir pour s'assurer du respect des rgles de MVCC. Nanmoins, cette rgle peut seulement s'appliquer sur les transactions excutes sur le serveur matre. Donc il est possible que le nettoyage effectu sur le matre supprime des versions de lignes toujours
visibles sur une transaction excute sur le serveur en attente.
Les utilisateurs expriments peuvent noter que le nettoyage des versions de ligne ainsi que le gel des versions de ligne peuvent
potentiellement avoir un conflit avec les requtes excutes sur le serveur en attente. L'excution d'un VACUUM FREEZE manuel a de grandes chances de causer des conflits, y compris sur les tables sans lignes mises jour ou supprimes.
Les utilisateurs doivent s'attendre ce que les tables frquemment mises jour sur le serveur primaire seront aussi frquemment la
cause de requtes annules sur le serveur en attente. Dans un tel cas, le paramtrage d'une valeur finie pour
max_standby_archive_delay ou max_standby_streaming_delay peut tre considr comme similaire la configuration de statement_timeout.
Si le nombre d'annulations de requtes sur le serveur en attente est jug inadmissible, quelques solutions existent. La premire option est de dfinir la variable hot_standby_feedback qui permet d'empcher les conflits lis au nettoyage opr par la commande VACUUM en lui interdisant de nettoyer les lignes rcemment supprimes. Si vous le faites, vous devez noter que cela retardera le nettoyage des versions de lignes mortes sur le serveur matre, ce qui pourrait rsulter en une fragmentation non dsire
de la table. Nanmoins, cette situation ne sera pas meilleure si les requtes du serveur en attente s'excutaient directement sur le
serveur matre. Vous avez toujours le bnfice de l'excution sur un serveur distant. max_standby_archive_delay doit tre
configur avec une valeur suffisamment large dans ce cas car les journaux de transactions en retard pourraient dj contenir des
entres en conflit avec les requtes sur le serveur en attente.
Une autre option revient augmenter vacuum_defer_cleanup_age sur le serveur matre, pour que les lignes mortes ne soient pas
nettoyes aussi rapidement que d'habitude. Cela donnera plus de temps aux requtes pour s'excuter avant d'tre annules sur le
serveur en attente, sans voir configurer une valeur importante de max_standby_streaming_delay. Nanmoins, il est dif424

Haute disponibilit, rpartition de charge et


rplication
ficile de garantir une fentre spcifique de temps d'excution avec cette approche car vacuum_defer_cleanup_age est mesur en nombre de transactions sur le serveur matre.
Le nombre de requtes annules et le motif de cette annulation peut tre visualis avec la vue systme pg_stat_database_conflicts
sur le serveur de standby. La vue systme pg_stat_database contient aussi des informations synthtiques sur ce sujet.

25.5.3. Aperu pour l'administrateur


Si hot_standby est positionn on dans postgresql.conf et qu'une fichier recovery.conf est prsent, le serveur
fonctionnera en mode Hot Standby. Toutefois, il pourrait s'couler du temps avant que les connections en Hot Standby soient autorises, parce que le serveur n'acceptera pas de connexions tant que la rcupration n'aura pas atteint un point garantissant un tat
cohrent permettant aux requtes de s'excuter. Pendant cette priode, les clients qui tentent de se connecter seront rejets avec un
message d'erreur. Pour confirmer que le serveur a dmarr, vous pouvez soit tenter de vous connecter en boucle, ou rechercher ces
messages dans les journaux du serveur:
LOG:

entering standby mode

... puis, plus loin ...


LOG:
LOG:

consistent recovery state reached


database system is ready to accept read only connections

L'information sur la cohrence est enregistre une fois par checkpoint sur le primaire. Il n'est pas possible d'activer le hot standby
si on lit des WAL gnrs durant une priode pendant laquelle wal_level n'tait pas positionn hot_standby sur le primaire. L'arrive un tat cohrent peut aussi tre retarde si ces deux conditions se prsentent:

Une transaction en criture a plus de 64 sous-transactions

Des transactions en criture ont une dure trs importante

Si vous effectuez du log shipping par fichier ("warm standby"), vous pourriez devoir attendre jusqu' l'arrive du prochain fichier
de WAL, ce qui pourrait tre aussi long que le paramtre archive_timeout du primaire.
Certains paramtres sur le standby vont devoir tre revus si ils ont t modifis sur le primaire. Pour ces paramtres, la valeur sur
le standby devra tre gale ou suprieure celle du primaire. Si ces paramtres ne sont pas suffisamment levs le standby refusera de dmarrer. Il est tout fait possible de fournir de nouvelles valeurs plus leves et de redmarrer le serveur pour reprendre la
rcupration. Ces paramtres sont les suivants:

max_connections

max_prepared_transactions

max_locks_per_transaction

Il est important que l'administrateur slectionne le paramtrage appropri pour max_standby_archive_delay et


max_standby_streaming_delay. Le meilleur choix varie les priorits. Par exemple, si le serveur a comme tche principale d'tre un
serveur de haute-disponibilit, alors il est prfrable d'avoir une configuration assez basse, voire zro, de ces paramtres. Si le
serveur en attente est utilis comme serveur supplmentaire pour des requtes du type dcisionnel, il sera acceptable de mettre les
paramtres de dlai des valeurs allant jusqu' plusieurs heures, voire mme -1 (cette valeur signifiant qu'il est possible d'attendre
que les requtes se terminent d'elles-mme).
Les "hint bits" (bits d'indices) crits sur le primaire ne sont pas journaliss en WAL, il est donc probable que les les hint bits soient
rcrits sur le standby. Ainsi, le serveur de standby fera toujours des critures disques mme si tous les utilisateurs sont en lecture
seule; aucun changement ne se produira sur les donnes elles mmes. Les utilisateurs criront toujours les fichiers temporaires
pour les gros tris et re-gnreront les fichiers d'information relcache, il n'y a donc pas de morceau de la base qui soit rellement en
lecture seule en mode hot standby. Notez aussi que les critures dans des bases distantes en utilisant le module dblink , et d'autres
opration en dehors de la base s'appuyant sur des fonctions PL seront toujours possibles, mme si la transaction est en lecture
seule localement.
Les types suivants de commandes administratives ne sont pas acceptes durant le mode de rcupration:

Langage de Dfinition de Donnes (LDD ou DDL) - comme CREATE INDEX

Privilge et possession - GRANT, REVOKE, REASSIGN

Commandes de maintenance - ANALYZE, VACUUM, CLUSTER, REINDEX

Notez encore une fois que certaines de ces commandes sont en fait autorises durant les transactions en "lecture seule" sur le pri425

Haute disponibilit, rpartition de charge et


rplication
maire.
Par consquent, vous ne pouvez pas crer d'index supplmentaires qui existeraient uniquement sur le standby, ni des statistiques
qui n'existeraient que sur le standby. Si ces commandes administratives sont ncessaires, elles doivent tre excutes sur le primaire, et ces modifications se propageront terme au standby.
pg_cancel_backend() fonctionnera sur les processus utilisateurs, mais pas sur les processus de dmarrage, qui effectuent la
rcupration. pg_stat_activity ne montre pas d'entre pour le processus de dmarrage, et les transactions de rcupration ne sont
pas affiches comme actives. Ainsi, pg_prepared_xacts est toujours vide durant la rcupration. Si vous voulez traiter des transactions prpares douteuses, interrogez pg_prepared_xacts sur le primaire, et excutez les commandes pour rsoudre le problme
cet endroit.
pg_locks affichera les verrous possds par les processus, comme en temps normal. pg_locks affiche aussi une transaction virtuelle gre par le processus de dmarrage qui possde tous les AccessExclusiveLocks possds par les transactions rejoues par la rcupration. Notez que le processus de dmarrage n'acquiert pas de verrou pour effectuer les modifications la base,
et que par consquent les verrous autre que AccessExclusiveLocks ne sont pas visibles dans pg_locks pour le processus de
dmarrage; ils sont simplement censs exister.
Le plugin Nagios check_pgsql fonctionnera, parce que les informations simples qu'il vrifie existent. Le script de supervision
check_postgres fonctionnera aussi, mme si certaines valeurs retournes pourraient tre diffrentes ou sujettes confusion. Par
exemple, la date de dernier vacuum ne sera pas mise jour, puisqu'aucun vacuum ne se dclenche sur le standby. Les vacuums
s'excutant sur le primaire envoient toujours leurs modifications au standby.
Les options de contrle des fichiers de WAL ne fonctionneront pas durant la rcupration, comme pg_start_backup,
pg_switch_xlog, etc...
Les modules chargement dynamique fonctionnent, comme pg_stat_statements.
Les verrous consultatifs fonctionnent normalement durant la rcupration, y compris en ce qui concerne la dtection des verrous
mortels (deadlocks). Notez que les verrous consultatifs ne sont jamais tracs dans les WAL, il est donc impossible pour un verrou
consultatif sur le primaire ou le standby d'tre en conflit avec la r-application des WAL. Pas plus qu'il n'est possible d'acqurir un
verrou consultatif sur le primaire et que celui-ci initie un verrou consultatif similaire sur le standby. Les verrous consultatifs n'ont
de sens que sur le serveur sur lequel ils sont acquis.
Les systmes de rplications base de triggers tels que Slony, Londiste et Bucardo ne fonctionneront pas sur le standby du
tout, mme s'ils fonctionneront sans problme sur le serveur primaire tant que les modifications ne sont pas envoyes sur le serveur standby pour y tre appliques. Le rejeu de WAL n'est pas base de triggers, vous ne pouvez donc pas utiliser le standby
comme relai vers un systme qui aurait besoin d'critures supplmentaires ou utilise des triggers.
Il n'est pas possible d'assigner de nouveaux OID, bien que des gnrateurs d' UUID puissent tout de mme fonctionner, tant qu'ils
n'ont pas besoin d'crire un nouveau statut dans la base.
l'heure actuelle, la cration de table temporaire n'est pas autorise durant les transactions en lecture seule, certains scripts existants pourraient donc ne pas fonctionner correctement. Cette restriction pourrait tre leve dans une version ultrieure. Il s'agit la
fois d'un problme de respect des standards et un problme technique.
DROP TABLESPACE ne peut russir que si le tablespace est vide. Certains utilisateurs pourraient utiliser de faon active le tablespace via leur paramtre temp_tablespaces. S'il y a des fichiers temporaires dans le tablespace, toutes les requtes actives
sont annules pour s'assurer que les fichiers temporaires sont supprims, afin de supprimer le tablespace et de continuer
l'application des WAL.
Excuter DROP DATABASE ou ALTER DATABASE ... SET TABLESPACE sur le serveur matre gnrera un enregistrement dans les journaux de transactions qui causera la dconnexion de tous les utilisateurs actuellement connects cette base de
donnes. Cette action survient immdiatement, quelque soit la valeur du paramtre max_standby_streaming_delay. Notez que ALTER DATABASE ... RENAME ne dconnecte pas les utilisateurs qui, dans la plupart des cas, ne s'en apercevront
pas. Cela peut nanmoins confondre un programme qui dpendrait du nom de la base.
En fonctionnement normal (pas en rcupration), si vous excutez DROP USER ou DROP ROLE pour un rle ayant le privilge
LOGIN alors que cet utilisateur est toujours connect alors rien ne se produit pour cet utilisateur connect - il reste connect.
L'utilisateur ne peut toutefois pas se reconnecter. Ce comportement est le mme en rcupration, un DROP USER sur le primaire
ne dconnecte donc pas cet utilisateur sur le standby.
Le collecteur de statistiques est actif durant la rcupration. Tous les parcours, lectures, utilisations de blocs et d'index, etc... seront enregistrs normalement sur le standby. Les actions rejoues ne dupliqueront pas leur effets sur le primaire, l'application
d'insertions n'incrmentera pas la colonne Inserts de pg_stat_user_tables. Le fichier de statistiques est effac au dmarrage de la
rcupration, les statistiques du primaire et du standby diffreront donc; c'est vu comme une fonctionnalit, pas un bug.
Autovacuum n'est pas actif durant la rcupration, il dmarrera normalement la fin de la rcupration.
Le processus d'criture en arrire plan (background writer) est actif durant la rcupration et effectuera les restartpoints (points de
426

Haute disponibilit, rpartition de charge et


rplication
reprise) (similaires aux points de synchronisation ou checkpoints sur le primaire) et les activits normales de nettoyage de blocs.
Ceci peut inclure la mise jour des information de hint bit des donnes du serveur de standby. La commande CHECKPOINT est
accepte pendant la rcupration, bien qu'elle dclenche un restartpoint et non un checkpoint.

25.5.4. Rfrence des paramtres de Hot Standby


De nombreux paramtres ont t mentionns ci-dessus dans Section 25.5.2, Gestion des conflits avec les requtes et Section 25.5.3, Aperu pour l'administrateur .
Sur le primaire, les paramtres wal_level et vacuum_defer_cleanup_age peuvent tre utiliss. max_standby_archive_delay et
max_standby_streaming_delay n'ont aucun effet sur le primaire.
Sur le serveur en attente, les paramtres hot_standby, max_standby_archive_delay et max_standby_streaming_delay peuvent tre
utiliss. vacuum_defer_cleanup_age n'a pas d'effet tant que le serveur reste dans le mode standby, mais deviendra important quand
le serveur en attente deviendra un serveur matre.

25.5.5. Avertissements
Il y a plusieurs limitations de Hot Standby. Elles peuvent et seront probablement rsolues dans des versions ultrieures:

Les oprations sur les index hash ne sont pas crits dans la WAL l'heure actuelle, la rcupration ne mettra donc pas ces index jour.

Une connaissance complte des transactions en cours d'excution est ncessaire avant de pouvoir dclencher des instantans.
Des transactions utilisant un grand nombre de sous-transactions ( l'heure actuelle plus de 64) retarderont le dmarrage des
connexions en lecture seule jusqu' compltion de la plus longue transaction en criture. Si cette situation se produit, des messages explicatifs seront envoys dans la trace du serveur.

Des points de dmarrage valides pour les requtes de standby sont gnrs chaque checkpoint sur le matre. Si le standby est
teint alors que le matre est dj teint, il est tout fait possible ne ne pas pouvoir repasser en Hot Standby tant que le primaire n'aura pas t redmarr, afin qu'il gnre de nouveaux points de dmarrage dans les journaux WAL. Cette situation
n'est pas un problme dans la plupart des situations o cela pourrait se produire. Gnralement, si le primaire est teint et plus
disponible, c'est probablement en raison d'un problme srieux qui va de toutes faons forcer la conversion du standby en primaire. Et dans des situations o le primaire est teint intentionnellement, la procdure standard est de promouvoir le matre.

la fin de la rcupration, les AccessExclusiveLocks possds par des transactions prpares ncessiteront deux fois le
nombre d'entres normal dans la table de verrous. Si vous pensez soit excuter un grand nombre de transactions prpares prenant des AccessExclusiveLocks, ou une grosse transaction prenant beaucoup de AccessExclusiveLocks, il est
conseill d'augmenter la valeur de max_locks_per_transaction, peut-tre jusqu' une valeur double de celle du serveur primaire. Vous n'avez pas besoin de prendre ceci en compte si votre paramtre max_prepared_transactions est
0.

Il n'est pas encore possible de passer une transaction en mode d'isolation srialisable tout en supportant le hot standby (voir
Section 13.2.3, Niveau d'Isolation Serializable et Section 13.4.1, Garantir la Cohrence avec Des Transactions Serializable pour plus de dtails). Une tentative de modification du niveau d'isolation d'une transaction srialisable en hot standby
gnrera une erreur.

427

Chapitre 26. Configuration de la rcupration


Ce chapitre dcrit les paramtres disponibles dans le fichier recovery.conf. Ils ne s'appliquent que pendant la dure de la
rcupration. Ils doivent tre repositionns pour toute rcupration ultrieure que vous souhaiterez effectuer. Ils ne peuvent pas
tre modifis une fois que la rcupration a commenc.
Les paramtres de recovery.conf sont spcifis dans le format nom = 'valeur'. Un paramtre est dclar par ligne.
Les caractres dise (#) indiquent que le reste de la ligne est un commentaire. Pour inclure un guillemet dans une valeur de paramtre, crivez deux guillemets ('').
Un fichier d'exemple , share/recovery.conf.sample, est fourni dans le rpertoire share/ de l'installation.

26.1. Paramtres de rcupration de l'archive


restore_command (chane de caractres)
La commande d'interprteur excuter pour rcuprer un segment de la srie de fichiers WAL archivs. Ce paramtre est
ncessaire pour la rcupration partir de l'archive, mais optionnel pour la rplication flux continu. Tout %f dans la
chane est remplac par le nom du fichier rcuprer de l'archive, et tout %p est remplac par le chemin de destination de la
copie sur le serveur. (Le chemin est relatif au rpertoire courant de travail, c'est dire le rpertoire de donnes de
l'instance.) Tout %r est remplac par le nom du fichier contenant le dernier point de reprise (restartpoint) valide. Autrement
dit, le fichier le plus ancien qui doit tre gard pour permettre la rcupration d'tre redmarrable. Cette information peut
donc tre utilise pour tronquer l'archive au strict minimum ncessaire pour permettre de reprendre la restauration en cours.
%r n'est typiquement utilis que dans des configurations de warn-standby. (voir Section 25.2, Serveurs de Standby par
transfert de journaux ). crivez %% pour inclure un vrai caractre %.
Il est important que la commande ne retourne un code retour gal zro que si elle russit. La commande recevra des demandes concernant des fichiers n'existant pas dans l'archive; elle doit avoir un code retour diffrent de zro dans ce cas. Par
exemple:
restore_command = 'cp /mnt/server/archivedir/%f "%p"'
restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'

# Windows

archive_cleanup_command (string)
Ce paramtre optionel spcifie une commande d'interprteur qui sera excut chaque point de reprise. Le but de archive_cleanup_command est de fournir un mcanisme de nettoyage des vieux fichiers WAL archivs qui ne sont plus
ncessaires au serveur de standby. Tout %r est remplac par le nom du fichier contenant le dernier point de reprise
(restartpoint) valide. Autrement dit, le fichier le plus ancien qui doit tre conserv pour permettre la rcupration d'tre redmarrable. Du coup, tous les fichiers crs avant %r peuvent tre supprims sans problme. Cette information peut tre
utilise pour tronquer les archives au minimum ncessaire pour redmarrer partir de la restauration en Le module
pg_archivecleanup est souvent utilis dans archive_cleanup_command dans des configurations de standby seuls. Par
exemple :
archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r'
Notez nanmoins que si plusieurs serveurs en standby sont mis jour partir du mme rpertoire d'archives, vous devez
vous assurer que vous ne supprimez que les journaux de transactions qui ne sont plus utiles tous les serveurs. archive_cleanup_command n'est typiquement utilis que dans des configurations de warm-standby (voir Section 25.2,
Serveurs de Standby par transfert de journaux ). crivez %% pour inclure un vrai caractre %.
Si la commande retourne un code de retour diffrent de zro alors um message de journal WARNING sera crit.
recovery_end_command (chane de caractres)
Ce paramtre spcifie une commande d'interprteur qui sera excute une fois seulement, la fin de la rcupration. Ce paramtre est optionnel. Le but de recovery_end_command est de fournir un mcanisme pour un nettoyage la fin de la
rplication ou de la rcupration. Tout %r est remplac par le nom du fichier contenant le dernier point de reprise valide,
comme dans archive_cleanup_command.
Si la commande retourne un code de retour diffrent de zro alors um message de journal WARNING sera crit et la base
continuera son dmarrage malgr tout. Par contre, si la commande a t termine par un signal, la base n'effectuera pas son
dmarrage.

26.2. Paramtres de cible de rcupration


428

Configuration de la rcupration

recovery_target_name (string)
Ce paramtre spcifie le point de restauration nomm, cr avec pg_create_restore_point(), qui indiquera la fin de
la restauration. Au plus un paramtre parmi recovery_target_name, recovery_target_time ou recovery_target_xid peut
tre configur. Par dfaut, la restauration se fait jusqu'au dernier journal de transactions disponible.
recovery_target_time (timestamp)
Ce paramtre spcifie l'horodatage (timestamp) jusqu'auquel la rcupration se poursuivra. On ne peut spcifier qu'un seul des
paramtres recovery_target_time, recovery_target_name et recovery_target_xid au plus. Par dfaut, la rcupration
se poursuit jusqu' la fin du journal WAL. Le point prcis d'arrt dpend aussi de recovery_target_inclusive.
recovery_target_xid (chane de caractres)
Ce paramtre spcifie l'identifiant de transaction jusqu'auquel la rcupration se poursuivra. Gardez l'esprit que, bien que les
identifiants de transactions sont assigns squentiellement au dmarrage des transactions, elles peuvent se terminer dans un
ordre numrique diffrent. Les transactions qui seront rcupres sont celles qui auront ralis leur COMMIT avant la transaction spcifie (optionnellement incluse). On ne peut spcifier qu'un seul des paramtres recovery_target_time, recovery_target_name et recovery_target_xid au plus. Par dfaut, la rcupration se poursuit jusqu' la fin du journal WAL. Le
point prcis d'arrt dpend aussi de recovery_target_inclusive.
recovery_target_inclusive (boolen)
Spcifie si il faut s'arrter juste aprs la cible de rcupration spcifie (true), ou juste avant la cible de rcupration
(false). S'applique recovery_target_time comme recovery_target_xid, suivant celui qui est spcifi pour cette rcupration. Ceci indique si les transaction qui ont exactement le mme horodatage ou le mme identifiant de commit, respectivement, seront inclues dans la rcupration. La valeur par dfaut est (true).
recovery_target_timeline (chane de caractres)
Spcifie la ligne de temps (timeline) prcise sur laquelle effectuer la rcupration. Le comportement par dfaut est de rcuprer sur la mme timeline que celle en cours lorsque la sauvegarde de base a t effectue. Configurer ce paramtre latest
permet de restaurer jusqu' la dernire ligne de temps disponible dans les archives, ce qui est utile pour un serveur standby.
Sinon, vous n'aurez besoin de positionner ce paramtre que dans des cas complexes de re-rcupration, o vous aurez besoin
d'atteindre un tat lui mme atteint aprs une rcupration un moment dans le temps (point-in-time recovery). Voir Section 24.3.4, Lignes temporelles (Timelines) pour plus d'informations.
pause_at_recovery_target (boolean)
Spcifie si la restauration doit se mettre en pause quand la cible de restauration est atteinte. La valeur par dfaut est true. Cela
permet l'excution de requtes sur la base de donnes pour vrifier si la cible de restauration est bien celle souhaite. L'tat de
pause peut tre annule en utilisant pg_xlog_replay_resume() (voir Tableau 9.58, Fonctions de contrle de la restauration ), ce qui termine la restauration. Si la cible actuelle de restauration ne correspond pas au point d'arrt souhait, arrtez le serveur, modifiez la configuration de la cible de restauration une cible plus lointaine, et enfin redmarrez pour continuer la restauration.
Cette configuration n'a pas d'effet si hot_standby n'est pas active ou si une cible de restauration n'est pas configure.

26.3. Paramtres de serveur de Standby


standby_mode (boolen)
Spcifie s'il faut dmarrer le serveur PostgreSQL en tant que standby. Si ce paramtre est on, le serveur n'arrte pas la rcupration quand la fin du WAL archiv est atteinte, mais continue d'essayer de poursuivre la rcupration en rcuprant de
nouveaux segments en utilisant restore_command et/ou en se connectant au serveur primaire comme spcifi par le paramtre primary_conninfo.
primary_conninfo (chane de caractres)
Spcifie au serveur de standby la chane de connexion utiliser pour atteindre le primaire. Cette chane est dans le format accept par la fonction PQconnectdb de la libpq, dcrite dans Section 31.1, Fonctions de contrle de connexion la base de
donnes . Si une option n'est pas spcifie dans cette chane, alors la variable d'environnement correspondante (voir Section 31.13, Variables d'environnement ) est examine. Si la variable d'environnement n'est pas positionne non plus, la valeur par dfaut est utilise.
La chane de connexion devra spcifier le nom d'hte (ou adresse) du serveur primaire, ainsi que le numro de port si ce n'est
pas le mme que celui par dfaut du serveur de standby. Spcifiez aussi un nom d'utilisateur correspondant un rle qui a les
privilges REPLICATION et LOGIN sur le primaire (voir Section 25.2.5.1, Authentification ). Un mot de passe devra aussi tre fourni, si le primaire demande une authentification par mot de passe. Il peut tre fourni soit dans la chane primary_conninfo soit sparment dans un fichier ~/.pgpass sur le serveur de standby (utilisez replication comme
nom de base de donnes). Ne spcifiez pas de nom de base dans la chaneprimary_conninfo
Ce paramtre n'a aucun effet si standby_mode vaut off.
429

Configuration de la rcupration

trigger_file (chane de caractres)


Spcifie un fichier trigger dont la prsence met fin la rcupration du standby. Mme si cette valeur n'est pas configure,
vous pouvez toujours promouvoir le serveur en attente en utilisant pg_ctl promote. Ce paramtre n'a aucun effet si standby_mode vaut off.

430

Chapitre 27. Surveiller l'activit de la base de


donnes
Un administrateur de bases de donnes se demande frquemment : Que fait le systme en ce moment ? Ce chapitre discute
de la faon de le savoir.
Plusieurs outils sont disponibles pour surveiller l'activit de la base de donnes et pour analyser les performances. Une grande
partie de ce chapitre concerne la description du rcuprateur de statistiques de PostgreSQL mais personne ne devrait ngliger
les programmes de surveillance Unix standards tels que ps, top, iostat et vmstat. De plus, une fois qu'une requte peu performante a t identifie, des investigations supplmentaires pourraient tre ncessaires en utilisant la commande EXPLAIN(7) de
PostgreSQL. La Section 14.1, Utiliser EXPLAIN discute de EXPLAIN et des autres mthodes pour comprendre le comportement d'une seule requte.

27.1. Outils Unix standard


Sur la plupart des plateformes Unix, PostgreSQL modifie son titre de commande report par ps de faon ce que les processus serveur individuels puissent tre rapidement identifis. Voici un affichage d'exemple :
$ ps auxww | grep ^postgres
postgres
960 0.0 1.1 6104 1480 pts/1
postgres
963 0.0 1.1 7084 1472 pts/1
process
postgres
965 0.0 1.1 6152 1512 pts/1
collector process
postgres
998 0.0 2.3 6532 2992 pts/1
127.0.0.1 idle
postgres 1003 0.0 2.4 6532 3128 pts/1
regression [local] SELECT waiting
postgres 1016 0.1 2.4 6532 3080 pts/1
regression [local] idle in transaction

SN
SN

13:17
13:17

0:00 postgres -i
0:00 postgres: writer

SN

13:17

0:00 postgres: stats

SN

13:18

0:00 postgres: tgl runbogue

SN

13:19

0:00 postgres: tgl

SN

13:19

0:00 postgres: tgl

(L'appel appropri de ps varie suivant les diffrentes plateformes, de mme que les dtails affichs. Cet exemple est tir d'un
systme Linux rcent.) Le premier processus affich ici est le processus serveur matre, le processus serveur matre. Les arguments affichs pour cette commande sont les mmes qu' son lancement. Les deux processus suivant sont des processus en tche
de fond lancs automatiquement par le processus matre (le processus stats collector n'est pas prsent si vous avez configur
le systme pour qu'il ne lance pas le rcuprateur de statistiques). Chacun des autres processus est un processus serveur grant
une connexion cliente. Tous ces processus restant initialisent l'affichage de la ligne de commande de la forme
postgres: utilisateur base_de_donnes hte activit
L'utilisateur, la base de donnes et les lments de l'hte (client) restent identiques pendant toute la vie de connexion du client
mais l'indicateur d'activit change. L'activit pourrait tre idle (c'est--dire en attente d'une commande du client), idle in
transaction (en attente du client l'intrieur d'un bloc de BEGIN/COMMIT) ou un nom de commande du type SELECT.
De plus, waiting est ajout si le processus serveur est en attente d'un verrou dtenu par une autre session. Dans l'exemple cidessus, nous pouvons supposer que le processus 1003 attend que le processus 1016 ait termin sa transaction et, du coup, libre
un verrou.
Si vous avez dsactiv update_process_title, alors l'indicateur d'activit n'est pas mis jour ; le titre du processus est configur
une seule fois quand un nouveau processus est lanc. Sur certaines plateformes, ceci permet d'conomiser du temps. Sur
d'autres, cette conomie est insignifiante.

Astuce
Solaris requiert une gestion particulire. Vous devez utiliser /usr/ucb/ps plutt que /bin/ps. Vous devez aussi
utiliser deux options w et non pas seulement une. En plus, votre appel original de la commande postgres doit
avoir un affichage de statut dans ps plus petit que celui fourni par les autres processus serveur. Si vous chouez
dans les trois, l'affichage de ps pour chaque processus serveur sera la ligne de commande originale de postgres.

27.2. Le rcuprateur de statistiques


Le rcuprateur de statistiques de PostgreSQL est un sous-systme qui supporte la rcupration et les rapports d'informations
sur l'activit du serveur. Actuellement, le rcuprateur peut compter les accs aux tables et index la fois en terme de blocs
disque et de lignes individuelles. Il conserve aussi la trace du nombre total de lignes dans chaque table ainsi que des informa431

Surveiller l'activit de la base de donnes

tions sur les VACUUM et les ANALYZE pour chaque table. Il peut aussi compter le nombre d'appels aux fonctions dfinies par
l'utilisateur ainsi que le temps total dpens par chacune.
PostgreSQL supporte aussi la dtermination de la commande exacte en cours d'excution par les autres processus serveur. Cette
fonctionnalit indpendante ne dpend pas du rcuprateur de statistiques.

27.2.1. Configuration de la rcupration de statistiques


Comme la rcupration de statistiques ajoute un temps supplmentaire l'excution de la requte, le systme peut tre configur
pour rcuprer ou non des informations. Ceci est contrl par les paramtres de configuration qui sont normalement initialiss
dans postgresql.conf (voir Chapitre 18, Configuration du serveur pour plus de dtails sur leur initialisation).
Le paramtre track_counts contrle si les statistiques sont rcupres pour les accs aux tables et index.
Le paramtre track_functions active le calcul de statistiques sur l'utilisation des fonctions dfinies par l'utilisateur.
Le paramtre track_activities active la surveillance de la commande en cours d'excution par un processus serveur.
Normalement, ces paramtres sont configurs dans postgresql.conf de faon ce qu'ils s'appliquent tous les processus
serveur mais il est possible de les activer/dsactiver sur des sessions individuelles en utilisant la commande SET(7) (pour empcher les utilisateurs ordinaires de cacher leur activit l'administrateur, seuls les superutilisateurs sont autoriss modifier ces paramtres avec SET).
Le collecteur de statistiques transmet les informations rcupres aux processus du moteur (y compris l'autovacuum) via des fichiers temporaires. Ces fichiers sont stockes dans le sous-rpertoire pg_stat_tmp. Quand le processus pre est arrt, une copie permanente des donnes statistiques est stocke dans le sous-rpertoire global. Pour des performances accrues, le paramtre
stats_temp_directory peut tre point vers un systme de fichiers en RAM, diminuant fortement les besoins en entres/sorties.
Une transaction peut aussi voir des statistiques propres son activit (qui ne sont pas encore transmises au collecteur) dans les
vues pg_stat_xact_all_tables, pg_stat_xact_sys_tables, pg_stat_xact_user_tables et pg_stat_xact_user_functions, ou via les fonctions appeles par ces vues. Ces informations se mettent jour en continue pendant l'excution de la transaction.

27.2.2. Visualiser les statistiques rcupres


Plusieurs vues prdfinies, listes dans le Tableau 27.1, Vues statistiques standards , sont disponibles pour afficher les rsultats
de la rcupration de statistiques. Autrement, vous pouvez construire des vues personnalises en utilisant les fonctions statistiques
existantes.
En utilisant les statistiques pour surveiller l'activit en cours, il est important de raliser que l'information n'est pas mise jour instantanment. Chaque processus serveur individuel transmet les nouvelles statistiques au rcuprateur juste avant l'attente d'une
nouvelle commande du client ; donc une requte toujours en cours n'affecte pas les totaux affichs. De plus, le rcuprateur luimme met un nouveau rapport une fois par PGSTAT_STAT_INTERVAL millisecondes (500, sauf si cette valeur a t modifie
lors de la construction du serveur). Donc, les totaux affichs sont bien derrire l'activit relle. Nanmoins, l'information sur la requte en cours rcupre par track_activities est toujours jour.
Un autre point important est que, lorsqu'un processus serveur se voit demander d'afficher une des statistiques, il rcupre tout
d'abord le rapport le plus rcent mis par le processus de rcupration, puis continue d'utiliser cette image de toutes les vues et
fonctions statistiques jusqu' la fin de sa transaction en cours. De faon similaire, les informations sur les requtes en cours,
quelque soit le processus, sont rcupres quand une telle information est demande dans une transaction, et cette mme information sera affiche lors de la transaction. Donc, les statistiques afficheront des informations statiques tant que vous restez dans la
mme transaction. Ceci est une fonctionnalit, et non pas un bogue, car il vous permet de traiter plusieurs requtes sur les statistiques et de corrler les rsultats sans vous inquiter que les nombres aient pu changer. Mais si vous voulez voir les nouveaux rsultats pour chaque requte, assurez-vous de lancer les requtes en dehors de tout bloc de transaction. Autrement, vous pouvez appeler pg_stat_clear_snapshot(), qui annulera l'image statistique de la transaction en cours. L'utilisation suivante des informations statistiques causera la rcupration d'une nouvelle image.
Tableau 27.1. Vues statistiques standards

Nom de la vue

Description

pg_stat_activity

Une ligne par processus serveur, affichant l'OID de la base de donnes, le nom de la base, l'ID du processus, l'OID de l'utilisateur, son nom, le nom de l'application, l'adresse, le nom de l'hte (si disponible)
et le port du client, la date et l'heure laquelle le client s'est connect, de dbut de la transaction, et de
dbut de la requte, le statut d'attente de verrou du processus et le texte de la requte en cours
d'excution. Les colonnes renvoyant des donnes sur la requte en cours sont disponibles sauf si le paramtre track_activities a t dsactiv. De plus, ces colonnes sont seulement visibles si
l'utilisateur examinant cette vue est un superutilisateur ou est le propritaire du processus en cours de
rapport. Le nom de l'hte du client sera disponible seulement si log_hostname est activ ou s'il a t n432

Surveiller l'activit de la base de donnes

Nom de la vue

Description
cessaire de le rechercher pendant la phase d'authentification (pg_hba.conf).

pg_stat_bgwriter

Une seule ligne indiquant des statistiques du cluster complet provenant du processus d'criture en tche
de fond : nombre de points de vrification planifis, points de vrification demands, tampons crits
par les points de vrification et parcours de nettoyage, et le nombre de fois o le processus d'criture en
tche de fond a stopp un parcours de nettoyage parce qu'il a crit trop de tampons. Cela inclut aussi
des statistiques sur les tampons partags dont le nombre de tampons crit par les processus serveur
(c'est--dire par autre chose que le processus d'criture en tche de fond), sur le nombre de fois que les
processus serveurs ont excut eux-mmes des appels fsync (normalement, le processus d'criture en
tche de fond s'en occupe mme si le processus serveur a fait les critures), le nombre de tampons allous et l'horodatage de la dernire rinitialisation des statistiques.

pg_stat_database

Une ligne par base de donnes, affichant l'OID de la base de donnes, son nom, le nombre de processus
serveur actifs connects cette base, le nombre total de transactions valides et le nombre de celles qui
ont t annules, le nombre total de blocs disque lus, le nombre total de succs du tampon (c'est--dire
le nombre de lectures de blocs vites en trouvant dj le bloc dans le cache du tampon), le nombre de
lignes renvoyes, rcupres, insres, mises jour et supprimes, le nombre total de requtes annules
cause d'un conflit avec la restauration (sur les serveurs en standby) et l'horodatage de la dernire rinitialisation des statistiques.

pg_stat_database_confli Une ligne par base de donnes, affichant l'OID de la base, son nom et le nombre de requtes qui ont t
cts
annules dans cette base cause de tablespaces supprimes, de dlais dpasss pour les verrous,
d'images de base trop anciennes, de tampons verrouills et de verrous mortels. Ne contiendra que des
informations sur les serveurs en standby car les conflits ne surviennent pas sur les serveurs matres.
pg_stat_replication

Une ligne par processus walsender, affichant l'identifiant du processus, l'OID de l'utilisateur, le nom de
l'utilisateur, le nom de l'application, l'adresse du client, le nom d'hte (si disponible) et le numro de
port, la date et l'heure laquelle le processus serveur a commenc son excution, l'tat du processus et
la position dans les journaux de transactions. De plus, le serveur en standby rapporte la dernire position reue et crite dans les journaux de transactions, la dernire position qu'il a crite sur disque, et la
dernire position qu'il a rejoue. Cette information est aussi affiche ici. Si les noms d'applications du
serveur en standby correspondent un de noms configurs dans synchronous_standby_names,
alors la priorit de synchronisation est aussi affiche ici (cela correspond l'ordre dans lequel les serveurs en standby deviennent le serveur synchrone). Les colonnes dtaillant le travail de la connexion
sont seulement visibles si l'utilisateur qui examine la vue est un superutilisateur. Le nom de l'hte du
client sera disponible seulement si log_hostname est activ ou s'il a t ncessaire de rechercher le nom
d'hte de l'utilisateur pendant la phase d'authentification (pg_hba.conf).

pg_stat_all_tables

Pour chaque table dans la base de donnes en cours (ceci incluant les tables TOAST), l'OID de la table,
le nom du schma et de la table, le nombre de parcours squentiels raliss, le nombre de lignes vivantes rcupres par des parcours squentiels, le nombre de lignes vivantes rcupres par des parcours squentiels, le nombre de parcours d'index raliss (pour tous les index appartenant cette table),
le nombre de lignes vivantes rcupres par les parcours d'index, le nombre d'insertions, de modifications et de suppressions de ligne, le nombre de mises jour de ligne via HOT (donc sans mise jour
spare des index), le nombre de lignes vivantes et mortes, la dernire fois que la table a t la cible
d'un VACUUM manuel (sans l'option FULL), la dernire fois qu'elle a t la cible d'un VACUUM excut par le dmon autovacuum, la dernire fois que la table a t la cible d'un ANALYZE manuel, la
dernire fois qu'elle a t la cible d'un ANALYZE excut par le dmon autovacuum, le nombre de fois
que la table a t la cible d'un VACUUM manuel (sans l'option FULL), le nombre de fois qu'elle a t
la cible d'un VACUUM excut par le dmon autovacuum, le nombre de fois que la table a t la cible
d'un ANALYZE manuel, le nombre de fois qu'elle a t la cible d'un ANALYZE excut par le dmon
autovacuum.

pg_stat_sys_tables

Identique pg_stat_all_tables, sauf que seules les tables systmes sont affiches.

pg_stat_user_tables

Identique pg_stat_all_tables, sauf que seules les tables utilisateurs sont affiches.

pg_stat_xact_all_tables

Similaire pg_stat_all_tables, mais dcompte les actions prises dans la transaction en cours (qui ne
sont pas encore pris en compte dans la vue pg_stat_all_tables et les vues du mme type). Les colonnes
correspondant au nombre de lignes vivantes et mortes, ainsi que celles pour les actions du VACUUM
et de l'ANALYZE ne sont pas prsentes dans cette vue.

pg_stat_xact_sys_tables Identique pg_stat_xact_all_tables, sauf que seules les tables systmes sont affiches.
pg_stat_xact_user_table Identique pg_stat_xact_all_tables,, sauf que seules les tables utilisateurs sont affiches.
s
pg_stat_all_indexes

Pour chaque index de la base de donnes en cours, l'OID de la table et de l'index, le nom du schma, de
433

Surveiller l'activit de la base de donnes

Nom de la vue

Description
la table et de l'index, le nombre de parcours d'index initis sur cet index, le nombre d'entres de l'index
renvoyes par les parcours d'index, et le nombre de lignes actives de table rcupres par de simples
parcours d'index utilisant cet index.

pg_stat_sys_indexes

Identique pg_stat_all_indexes, sauf que seules les tables systmes sont affiches.

pg_stat_user_indexes

Identique pg_stat_all_indexes, sauf que seules les tables utilisateurs sont affiches.

pg_statio_all_tables

Pour chaque table de la base de donnes en cours (ceci incluant les tables TOAST), l'OID de la table, le
nom du schma et de la table, le nombre de blocs disque lus partir de cette table, le nombre de lectures tampon russies dans tous les index de cette table, le nombre de blocs disque lus et de lectures
tampon russies partir de la table TOAST (si elle existe), et, enfin, le nombre de blocs disque lus et le
nombre de lectures tampon russies partir de l'index de la table TOAST.

pg_statio_sys_tables

Identique pg_statio_all_tables, sauf que seules les tables systmes sont affiches.

pg_statio_user_tables

Identique pg_statio_all_tables, sauf que seules les tables utilisateur sont affiches.

pg_statio_all_indexes

Pour chaque index de la base de donnes en cours, l'OID de la table et de l'index, le nom du schma, de
la table et de l'index, le nombre de blocs disque lus et le nombre de lectures tampon russies pour cet
index.

pg_statio_sys_indexes

Identique pg_statio_all_indexes, sauf que seuls les index systmes sont affichs.

pg_statio_user_indexes

Identique pg_statio_all_indexes, sauf que seuls les index utilisateur sont affichs.

pg_statio_all_sequences Pour chaque squence de la base de donnes en cours, l'OID de la squence, le nom du schma et de la
squence, le nombre de blocs disque lus et le nombre de lectures russies du tampon pour cette squence.
pg_statio_sys_sequences Identique pg_statio_all_sequences, sauf que seules les squences systme sont affiches
(actuellement, aucune squence systme n'est dfinie, donc cette vue est toujours vide)
pg_statio_user_sequence Identique pg_statio_all_sequences, sauf que seules les squences utilisateur sont affiches.
s
pg_stat_user_functions

Pour les fonctions traces, OID de la fonction, schma, nom, nombre d'appels, temps total et temps de
la fonction. Ce dernier est le temps pass uniquement dans la fonction. Le temps total inclus le temps
pass dans les fonctions appeles. Les valeurs sont en millisecondes.

pg_stat_xact_user_funct Similaire pg_stat_user_functions, mais compte seulement les appels pendant la transaction en cours
ions
(qui ne sont pas encore inclus dans pg_stat_user_functions).
Les statistiques par index sont particulirement utiles pour dterminer les index utiliss et leur efficacit.
Les index peuvent tre utiliss soit directement soit via des parcours de bitmap . Dans un parcours de bitmap, les rsultats de
plusieurs index peuvent tre combins via des rgles AND ou OR ; donc il est difficile d'associer des rcuprations de lignes
d'en-ttes individuelles avec des index spcifiques quand un parcours de bitmap est utilis. Du coup, un parcours de bitmap incrmente le nombre dans pg_stat_all_indexes.idx_tup_read pour les index qu'il utilise et il incrmente le nombre
pg_stat_all_tables.idx_tup_fetch pour la table, mais il n'affecte pas pg_stat_all_indexes.idx_tup_fetch.

Note
Avant PostgreSQL 8.1, les totaux idx_tup_read et idx_tup_fetch taient pratiquement toujours gaux.
Maintenant, ils peuvent tre diffrents mme sans considrer les parcours de bitmap parce que idx_tup_read
compte les entres d'index rcupres partir de l'index alors que idx_tup_fetch compte les lignes actives rcupres partir de la table ; ce dernier sera moindre si des lignes mortes ou pas-encore-valides sont rcupres en
utilisant l'index.
Les vues pg_statio_ sont principalement utiles pour dterminer l'efficacit du cache tampon. Quand le nombre de lectures disques
relles est plus petit que le nombre de rcuprations valides par le tampon, alors le cache satisfait la plupart des demandes de lecture sans faire appel au noyau. Nanmoins, ces statistiques ne nous donnent pas l'histoire complte : cause de la faon dont PostgreSQL gre les entres/sorties disque, les donnes qui ne sont pas dans le tampon de PostgreSQL pourraient toujours rsider
dans le tampon d'entres/sorties du noyau et pourraient, du coup, tre toujours rcupres sans ncessiter une lecture physique. Les
utilisateurs intresss pour obtenir des informations plus dtailles sur le comportement des entres/sorties dans PostgreSQL
sont invits utiliser le rcuprateur de statistiques de PostgreSQL avec les outils du systme d'exploitation permettant une vue
de la gestion des entres/sorties par le noyau.
Il existe d'autres faons de regarder les statistiques. Cela se fait en crivant des requtes qui utilisent les mmes fonctions d'accs
434

Surveiller l'activit de la base de donnes

aux statistiques que les vues standards. Ces fonctions sont listes dans le Tableau 27.2, Fonctions d'accs aux statistiques . Les
fonctions d'accs par base de donnes prennent un OID de la base de donnes comme argument pour identifier la base de donnes
du rapport. Les fonctions par table et par index prennent l'OID de la table ou de l'index. Les fonctions des statistiques pour les appels de fonctions prennent un OID. (notez que seuls les tables et les index de la base de donnes en cours peuvent tre vus par ces
fonctions). Les fonctions d'accs au processus prennent le numro d'identifiant du processus.
Tableau 27.2. Fonctions d'accs aux statistiques

Fonction

Code de Description
retour

pg_stat_get_db_numbackends(oid)

integer

Nombre de processus actifs pour la base de


donnes

pg_stat_get_db_xact_commit(oid)

bigint

Nombre de transactions valides dans la


base de donnes

pg_stat_get_db_xact_rollback(oid)

bigint

Nombre de transactions annules dans la


base de donnes

pg_stat_get_db_blocks_fetched(oid)

bigint

Nombre de demandes de rcuprations de


blocs disque pour la base de donnes

pg_stat_get_db_blocks_hit(oid)

bigint

Nombre de demandes de rcuprations de


blocs disque trouvs dans le tampon pour la
base de donnes

pg_stat_get_db_tuples_returned(oid)

bigint

Nombre de lignes renvoyes pour la base

pg_stat_get_db_tuples_fetched(oid)

bigint

Nombre de lignes rcupres pour la base

pg_stat_get_db_tuples_inserted(oid)

bigint

Nombre de lignes insres dans la base

pg_stat_get_db_tuples_updated(oid)

bigint

Nombre de lignes mises jour dans la base

pg_stat_get_db_tuples_deleted(oid)

bigint

Nombre de lignes supprimes dans la base

pg_stat_get_db_conflict_tablespace(oid)

bigint

Nombre de requtes annules cause d'un


conflit dans la restauration avec des tablespaces supprimes

pg_stat_get_db_conflict_lock(oid)

bigint

Nombre de requtes annules cause d'un


conflit dans la restauration avec des verrous

pg_stat_get_db_conflict_snapshot(oid)

bigint

Nombre de requtes annules cause d'un


conflit dans la restauration avec
d'anciennes images de base

pg_stat_get_db_conflict_bufferpin(oid)

bigint

Nombre de requtes annules cause d'un


conflit dans la restauration avec des tampons verrouills

pg_stat_get_db_conflict_startup_deadlock(oid)

bigint

Nombre de requtes annules cause d'un


conflit dans la restauration avec des verrous
mortels

pg_stat_get_db_stat_reset_time(oid)

timestamptz

Horodatage de la dernire rinitialisation


des statistiques pour la base de donnes.
Initialis l'heure systme lors de la premire connexion chaque base de donnes.
L'heure de rinitialisation est mise jour
quand vous appelez pg_stat_reset sur
la base de donnes, ainsi qu'aprs excution
de
pg_stat_reset_single_table_co
unters sur une table ou un index.

pg_stat_get_numscans(oid)

bigint

Nombre de parcours squentiels raliss


lorsque l'argument est une table, ou nombre
de parcours d'index lorsque l'argument est
un index

pg_stat_get_tuples_returned(oid)

bigint

Nombre de lignes lues par les parcours s-

435

Surveiller l'activit de la base de donnes

Fonction

Code de Description
retour
quentiels lorsque l'argument est une table,
ou nombre de lignes d'index lues lorsque
l'argument est un index

pg_stat_get_tuples_fetched(oid)

bigint

Le nombre de lignes de table rcupres


par des parcours de bitmap quand
l'argument est une table, ou les lignes de
table rcupres par de simples parcours
d'index en utilisant cet index quand
l'argument est un index.

pg_stat_get_tuples_inserted(oid)

bigint

Nombre de lignes insres dans la table

pg_stat_get_tuples_updated(oid)

bigint

Nombre de lignes mises jour dans la table


(incluant les mises jour via HOT)

pg_stat_get_tuples_deleted(oid)

bigint

Nombre de lignes supprimes dans la table

pg_stat_get_tuples_hot_updated(oid)

bigint

Nombre de lignes mises jour via HOT


dans la table

pg_stat_get_live_tuples(oid)

bigint

Nombre de lignes vivantes dans la table

pg_stat_get_dead_tuples(oid)

bigint

Nombre de lignes mortes dans la table

pg_stat_get_blocks_fetched(oid)

bigint

Nombre de demandes de rcupration de


blocs disques pour la table ou l'index

pg_stat_get_blocks_hit(oid)

bigint

Nombre de demandes de blocs disque rcuprs dans le tampon pour la table ou


l'index

pg_stat_get_tuples_deleted(oid)

bigint

Nombre de lignes supprimes dans la table

pg_stat_get_blocks_fetched(oid)

bigint

Nombre de requtes de rcupration de


blocs disque pour les tables ou index

pg_stat_get_blocks_hit(oid)

bigint

Nombre de requtes de blocs disque trouvs en cache pour les tables ou index

pg_stat_get_last_vacuum_time(oid)

timestamptz

Date/heure du dernier VACUUM (sans


l'option FULL) survenu sur cette table la
demande de l'utilisateur

pg_stat_get_last_autovacuum_time(oid)

timestamptz

Date/heure du dernier ANALYZE lanc


par le dmon autovacuum survenu sur cette
table.

pg_stat_get_last_analyze_time(oid)

timestamptz

Date/heure du dernier VACUUM survenu


sur cette table la demande de l'utilisateur

pg_stat_get_last_autoanalyze_time(oid)

timestamptz

Date/heure du dernier ANALYZE lanc


par le dmon autovacuum survenu sur cette
table.

pg_stat_get_vacuum_count(oid)

bigint

Nombre de fois qu'un VACUUM non


FULL a t excut manuellement sur cette
table

pg_stat_get_autovacuum_count(oid)

bigint

Nombre de fois qu'un VACUUM a t excut automatiquement sur cette table par le
dmon autovacuum

pg_stat_get_analyze_count(oid)

bigint

Nombre de fois qu'un ANALYZE a t


excut manuellement sur cette table

pg_stat_get_autoanalyze_count(oid)

bigint

Nombre de fois qu'un ANALYZE a t


excut automatiquement sur cette table
par le dmon autovacuum

pg_stat_get_xact_numscans(oid)

bigint

Nombre de parcours squentiels raliss


quand l'argument est une table, ou nombre
de parcours d'index raliss quand

436

Surveiller l'activit de la base de donnes

Fonction

Code de Description
retour
l'argument est un index, pour la transaction
courante

pg_stat_get_xact_tuples_returned(oid)

bigint

Nombre de lignes lues par des parcours squentiels quand l'argument est une table, ou
nombre d'entres d'index renvoyes quand
l'argument est un index, pour la transaction
en cours

pg_stat_get_xact_tuples_fetched(oid)

bigint

Nombre de lignes de table rcupres par


des parcours de bitmap quand l'argument
est une table, ou nombre de lignes de table
rcupres par des parcours simples d'index
quand l'argument est un index, pour la transaction en cours

pg_stat_get_xact_tuples_inserted(oid)

bigint

Nombre de lignes insres dans la table,


pour la transaction en cours

pg_stat_get_xact_tuples_updated(oid)

bigint

Nombre de lignes mises jour (incluant les


mises jour HOT) dans la table, pour la
transaction en cours

pg_stat_get_xact_tuples_deleted(oid)

bigint

Nombre de lignes supprimes dans la table,


pour la transaction en cours

pg_stat_get_xact_tuples_hot_updated(oid)

bigint

Nombre de lignes mises jour via HOT


dans la table, pour la transaction en cours

pg_stat_get_xact_blocks_fetched(oid)

bigint

Nombre de demandes de lectures de blocs


disques pour la table ou l'index, pour la
transaction en cours

pg_stat_get_xact_blocks_hit(oid)

bigint

Nombre de demandes de lectures de blocs


disques pour la table ou l'index trouvs
dans le cache, pour la transaction en cours

pg_backend_pid()

integer

ID du processus pour le processus serveur


attach la session en cours

pg_stat_get_activity(integer)

setof
cord

pg_stat_get_function_calls(oid)

bigint

Nombre d'appels de la fonction.

pg_stat_get_function_time(oid)

bigint

Temps pass dans la fonction, en microsecondes. Inclut le temps pass dans les fonctions appeles par cette fonction.

pg_stat_get_function_self_time(oid)

bigint

Temps pass uniquement dans cette fonction. Le temps pass dans les fonctions appeles est exclu.

pg_stat_get_xact_function_calls(oid)

bigint

Nombre de fois o la fonction a t appele, dans la transaction en cours

pg_stat_get_xact_function_time(oid)

bigint

Temps pass dans la fonction, en microsecondes, pour la transaction en cours. Inclut


le temps pass dans les fonctions appeles
par cette fonction.

pg_stat_get_xact_function_self_time(oid)

bigint

Temps pass uniquement dans cette fonction pour la transaction en cours. Le temps
pass dans les fonctions appeles est exclu.

pg_stat_get_backend_idset()

setof inte- PID des processus serveurs actifs ce mo437

re- Renvoie un ensemble d'informations sur le


processus serveur correspondant au PID indiqu, ou un enregistrement pour chaque
processus serveur actif sur le systme si le
PID vaut NULL. Les champs renvoys sont
un sous-ensemble de ceux proposs par la
vue pg_stat_activity

Surveiller l'activit de la base de donnes

Fonction

Code de Description
retour
ger

ment (de 1 au nombre de processus serveurs actifs). Voir un exemple d'utilisation


dans le texte.

pg_stat_get_backend_pid(integer)

integer

ID du processus pour le processus serveur


donn

pg_stat_get_backend_dbid(integer)

oid

ID de la base de donnes pour le processus


serveur en cours

pg_stat_get_backend_userid(integer)

oid

ID de l'utilisateur pour le processus serveur


en cours

pg_stat_get_backend_activity(integer)

text

Commande active du processus serveur indiqu mais seulement si l'utilisateur courant


est un superutilisateur ou le mme utilisateur dont vient la commande (et que
track_activities est activ)

pg_stat_get_backend_waiting(integer)

boolean

True si le processus serveur indiqu attend


un verrou mais seulement si l'utilisateur
courant est un superutilisateur ou le mme
utilisateur dont vient la commande (et que
track_activities est activ)

pg_stat_get_backend_activity_start(integer)

timesDate/heure du lancement de la requte en


tamp with cours d'excution sur le processus serveur
time zone indiqu, mais seulement si l'utilisateur courant est un superutilisateur ou le mme utilisateur dont vient la commande (et que
track_activities est activ)

pg_stat_get_backend_xact_start(integer)

timesLe moment auquel le processus serveur intamp with diqu a t excut. Seulement si
time zone l'utilisateur est un superutilisateur ou le
mme utilisateur que celui qui a lanc la
session (et que track_activities est
activ)

pg_stat_get_backend_start(integer)

timesL'heure laquelle le processus serveur dontamp with n a t lanc ou NULL si l'utilisateur en


time zone cours n'est ni un superutilisateur ni
l'utilisateur de la session requte

pg_stat_get_backend_client_addr(integer)

inet

L'adresse IP du client connect au processus serveur donn. NULL si la connexion


est tablie sur un socket de domaine Unix.
Aussi NULL si l'utilisateur en cours n'est ni
un superutilisateur ni l'utilisateur de la session requte

pg_stat_get_backend_client_port(integer)

integer

Le numro de port TCP du client connect


au processus serveur donn. -1 si la
connexion est tablie sur un socket de domaine Unix. NULL si l'utilisateur en cours
n'est ni un superutilisateur ni l'utilisateur de
la session requte

pg_stat_get_bgwriter_timed_checkpoints()

bigint

Le nombre de fois o le processus


d'criture en tche de fond a lanc des
points de vrification planifis (donc parce
que checkpoint_timeout est arriv
expiration)

pg_stat_get_bgwriter_requested_checkpoints()

bigint

Nombre de fois o le processus d'criture


en tche de fond a lanc des points de vrification en se basant sur les demandes des
processus serveur parce que check-

438

Surveiller l'activit de la base de donnes

Fonction

Code de Description
retour
point_segments a t dpass ou parce
que la commande CHECKPOINT a t
lance

pg_stat_get_bgwriter_buf_written_checkpoints()

bigint

Nombre de tampons crits par le processus


d'criture en tche de fond lors de points de
vrification

pg_stat_get_bgwriter_buf_written_clean()

bigint

Nombre de tampons crits par le processus


d'criture en tche de fond pour le nettoyage de routine des pages sales

pg_stat_get_bgwriter_maxwritten_clean()

bigint

Nombre de fois o le processus d'criture


en tche de fond est arrt son parcours de
nettoyage parce qu'il a crit plus de tampons que ce qui est spcifi par le paramtre bgwriter_lru_maxpages

pg_stat_get_bgwriter_stat_reset_time()

timestamptz

Horodatage de la dernire rinitialisation


des statistiques pour le processus d'criture
en tche de fond, mis jour lors de
l'excution
de
pg_stat_reset_shared('bgwrite
r') sur l'instance.

pg_stat_get_buf_written_backend()

bigint

Nombre de tampons crits par les processus


serveur parce qu'ils ont besoin d'allouer un
nouveau tampon

pg_stat_get_buf_alloc()

bigint

Le nombre total d'allocations de tampons

pg_stat_get_wal_senders()

setof
cord

re- Un enregistrement pour chaque processus


walsender actif. Les champs renvoys sont
un sous-ensemble de ceux disponibles dans
la vue pg_stat_replication.

pg_stat_clear_snapshot()

void

Annule l'image statistique actuelle

pg_stat_reset()

void

Rinitialise zro tous les compteurs statistiques pour la base de donnes actuelle
(ncessite les droits superutilisateur)

pg_stat_reset_shared(text)

void

Rinitialise des compteurs de statistiques


partags pour le cluster de base de donnes
zro (ncessite les droits du superutilisateur).
Appeler
pg_stat_reset_shared('bgwrite
r') mettra zro toutes les valeurs affiches par pg_stat_bgwriter.

pg_stat_reset_single_table_counters(oid)

void

Rinitialise les statistiques pour une table


ou un index particulier dans la base de donnes en cours (ncessite les droits du superutilisateur).

pg_stat_reset_single_function_counters(oid)

void

Rinitialise les statistiques pour une fonction particulire dans la base de donnes en
cours (ncessite les droits du superutilisateur).

Note
pg_stat_get_blocks_fetched moins pg_stat_get_blocks_hit donne le nombre d'appels lancs
pour la table, l'index ou la base de donnes ; mais le nombre de lectures physiques relles est habituellement
moindre cause des tampons du noyau. Les colonnes statistiques *_blks_read utilisent cette soustraction,
c'est--dire lus en cache soustrait aux lus sur disque.
439

Surveiller l'activit de la base de donnes

Toutes les fonctions accdant aux informations sur les processus sont indexes par numro d'identifiant, sauf que
pg_stat_get_activity est index par PID. La fonction pg_stat_get_backend_idset fournit un moyen agrable de
gnrer une ligne pour chaque processus serveur actif. Par exemple, pour afficher les PID et les requtes en cours pour tous les
processus serveur :
SELECT pg_stat_get_backend_pid(s.backendid) AS procpid,
pg_stat_get_backend_activity(s.backendid) AS current_query
FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;

27.3. Visualiser les verrous


Un autre outil utile pour surveiller l'activit des bases de donnes est la table systme pg_locks. Elle permet l'administrateur systme de visualiser des informations sur les verrous restant dans le gestionnaire des verrous. Par exemple, cette fonctionnalit peut
tre utilise pour :

Visualiser tous les verrous en cours, tous les verrous sur les relations d'une base de donnes particulire ou tous les verrous dtenus par une session PostgreSQL particulire.

Dterminer la relation de la base de donnes disposant de la plupart des verrous non autoriss (et qui, du coup, pourraient tre
une source de contention parmi les clients de la base de donnes).

Dterminer l'effet de la contention des verrous sur les performances gnrales des bases de donnes, ainsi que l'chelle dans laquelle varie la contention sur le trafic de la base de donnes.

Les dtails sur la vue pg_locks apparaissent dans la Section 45.56, pg_locks . Pour plus d'informations sur les verrous et la gestion des concurrences avec PostgreSQL, rfrez-vous au Chapitre 13, Contrle d'accs simultan.

27.4. Traces dynamiques


PostgreSQL fournit un support pour les traces dynamiques du serveur de bases de donnes. Ceci permet l'appel un outil externe certains points du code pour tracer son excution.
Un certain nombre de sondes et de points de traage sont dj insrs dans le code source. Ces sondes ont pour but d'tre utilises
par des dveloppeurs et des administrateurs de base de donnes. Par dfaut, les sondes ne sont pas compiles dans PostgreSQL ;
l'utilisateur a besoin de prciser explicitement au script configure de rendre disponible les sondes.
Actuellement, seul l'outil DTrace, disponible sur OpenSolaris, Solaris 10 et Mac OS X Leopard, est support. DTrace devrait tre
disponible pour FreeBSD dans le futur et peut-tre pour d'autres systmes d'exploitation.Le projet SystemTap pour Linux fournit
aussi un quivalent DTrace. Le support d'autres outils de traces dynamiques est possible thoriquement en modifiant les dfinitions des macros dans src/include/utils/probes.h.

27.4.1. Compiler en activant les traces dynamiques


Par dfaut, les sondes ne sont pas disponibles, donc vous aurez besoin d'indiquer explicitement au script configure de les activer
dans PostgreSQL. Pour inclure le support de DTrace, ajoutez --enable-dtrace aux options de configure. Lire Section 15.4, Procdure d'installation pour plus d'informations.

27.4.2. Sondes disponibles


Un certain nombre de sondes standards sont fournies dans le code source, comme indiqu dans Tableau 27.3, Sondes disponibles
pour DTrace . Tableau 27.4, Types dfinis utiliss comme paramtres de sonde prcise les types utiliss dans les sondes.
D'autres peuvent tre ajoutes pour amliorer la surveillance de PostgreSQL.
Tableau 27.3. Sondes disponibles pour DTrace

Nom

Paramtres

Aperu

transaction-start

(LocalTransactionId)

Sonde qui se dclenche au lancement


d'une nouvelle transaction. arg0 est
l'identifiant de transaction.

transaction-commit

(LocalTransactionId)

Sonde qui se dclenche quand une transaction se termine avec succs. arg0 est
l'identifiant de transaction.

transaction-abort

(LocalTransactionId)

Sonde qui se dclenche quand une transaction choue. arg0 est l'identifiant de

440

Surveiller l'activit de la base de donnes

Nom

Paramtres

Aperu
transaction.

query-start

(const char *)

Sonde qui se dclenche lorsque le traitement d'une requte commence. arg0 est la
requte.

query-done

(const char *)

Sonde qui se dclenche lorsque le traitement d'une requte se termine. arg0 est la
requte.

query-parse-start

(const char *)

Sonde qui se dclenche lorsque l'analyse


d'une requte commence. arg0 est la requte.

query-parse-done

(const char *)

Sonde qui se dclenche lorsque l'analyse


d'une requte se termine. arg0 est la requte.

query-rewrite-start

(const char *)

Sonde qui se dclenche lorsque la rcriture d'une requte commence. arg0 est
la requte.

query-rewrite-done

(const char *)

Sonde qui se dclenche lorsque la rcriture d'une requte se termine. arg0 est
la requte.

query-plan-start

()

Sonde qui se dclenche lorsque la planification d'une requte commence.

query-plan-done

()

Sonde qui se dclenche lorsque la planification d'une requte se termine.

query-execute-start

()

Sonde qui se dclenche lorsque


l'excution d'une requte commence.

query-execute-done

()

Sonde qui se dclenche lorsque


l'excution d'une requte se termine.

statement-status

(const char *)

Sonde qui se dclenche chaque fois que


le processus serveur met jour son statut
dans pg_stat_activity.current_query.
arg0 est la nouvelle chane de statut.

checkpoint-start

(int)

Sonde qui se dclenche quand un point de


retournement commence son excution.
arg0 dtient les drapeaux bit bit utiliss
pour distingurer les diffrents types de
points de retournement, comme un point
suite un arrt, un point immdiat ou un
point forc.

checkpoint-done

(int, int, int, int, int)

Sonde qui se dclenche quand un point de


retournement a termin son excution (les
sondes listes aprs se dclenchent en squence lors du traitement d'un point de retournement). arg0 est le nombre de tampons mmoires crits. arg1 est le nombre
total de tampons mmoires. arg2, arg3 et
arg4 contiennent respectivement le
nombre de journaux de transactions ajouts, supprims et recycls.

clog-checkpoint-start

(bool)

Sonde qui se dclenche quand la portion


CLOG d'un point de retournement commence. arg0 est true pour un point de retournement normal, false pour un point de
retournement suite un arrt.

clog-checkpoint-done

(bool)

Sonde qui se dclenche quand la portion


CLOG d'un point de retournement commence. arg0 a la mme signification que
441

Surveiller l'activit de la base de donnes

Nom

Paramtres

Aperu
pour clog-checkpoint-start.

subtrans-checkpoint-start

(bool)

Sonde qui se dclenche quand la portion


SUBTRANS d'un point de retournement
commence. arg0 est true pour un point de
retournement normal, false pour un point
de retournement suite un arrt.

subtrans-checkpoint-done

(bool)

Sonde qui se dclenche quand la portion


SUBTRANS d'un point de retournement
se termine. arg0 a la mme signification
que pour subtrans-checkpoint-start.

multixact-checkpoint-start

(bool)

Sonde qui se dclenche quand la portion


MultiXact d'un point de retournement
commence. arg0 est true pour un point de
retournement normal, false pour un point
de retournement suite un arrt.

multixact-checkpoint-done

(bool)

Sonde qui se dclenche quand la portion


MultiXact d'un point de retournement se
termine. arg0 a la mme signification que
pour multixact-checkpoint-start.

buffer-checkpoint-start

(int)

Sonde qui se dclenche quand la portion


d'criture de tampons d'un point de retournement commence. arg0 contient les drapeaux bit bit pour distinguer diffrents
types de point de retournement comme le
point aprs arrt, un point immdiat, un
point forc.

buffer-sync-start

(int, int)

Sonde qui se dclenche quand nous commenons d'crire les tampons modifis
pendant un point de retournement (aprs
identification des tampons qui doivent
tre crits). arg0 est le nombre total de
tampons. arg1 est le nombre de tampons
qui sont modifis et n'ont pas besoin d'tre
crits.

buffer-sync-written

(int)

Sonde qui se dclenche aprs chaque criture d'un tampon lors d'un point de retournement. arg0 est le numro d'identifiant
du tampon.

buffer-sync-done

(int, int, int)

Sonde qui se dclenche quand tous les


tampons modifis ont t crits. arg0 est
le nombre total de tampons. arg1 est le
nombre de tampons rellement crits par
le processus de point de retournement.
arg2 est le nombre attendu de tampons
crire (arg1 de buffer-sync-start) ; toute
diffrence reflte d'autres processus crivant des tampons lors du point de retournement.

buffer-checkpoint-sync-start

()

Sonde qui se dclenche une fois les tampons modifis crits par le noyau et avant
de commencer lancer des requtes
fsync.

buffer-checkpoint-done

()

Sonde qui se dclenche aprs la fin de la


synchronisation des tampons sur le
disque.

twophase-checkpoint-start

()

Sonde qui se dclenche quand la portion


deux-phases d'un point de retournement
442

Surveiller l'activit de la base de donnes

Nom

Paramtres

Aperu
est commence.

twophase-checkpoint-done

()

Sonde qui se dclenche quand la portion


deux-phases d'un point de retournement
est termine.

buffer-read-start

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche quand la lecture


Oid, int, bool)
d'un tampon commence. arg0 et arg1
contiennent les numros de fork et de bloc
de la page (arg1 vaudra -1 s'il s'agit de demande d'extension de la relation). arg2,
arg3 et arg4 contiennent respectivement
l'OID du tablespace, de la base de donnes et de la relation identifiant ainsi prcisment la relation. arg5 est l'identifiant
du processus moteur qui a cr la relation
temporaire pour un tampon local ou InvalidBackendId (-1) pour un tampon partag. arg6 est true pour une demande
d'extension de la relation, false pour une
lecture ordinaire.

buffer-read-done

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche quand la lecture


Oid, int, bool, bool)
d'un tampon se termine. arg0 et arg1
contiennent les numros de fork et de bloc
de la page (arg1 contient le numro de
bloc du nouveau bloc ajout s'il s'agit de
demande d'extension de la relation). arg2,
arg3 et arg4 contiennent respectivement
l'OID du tablespace, de la base de donnes et de la relation identifiant ainsi prcisment la relation. arg5 est l'identifiant
du processus moteur qui a cr la relation
temporaire pour un tampon local ou InvalidBackendId (-1) pour un tampon partag. arg6 est true pour une demande
d'extension de la relation, false pour une
lecture ordinaire. arg7 est true si la tampon tait disponible en mmoire, false sinon.

buffer-flush-start

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche avant de lancer


Oid)
une demande d'criture pour un bloc partag. arg2, arg3 et arg4 contiennent respectivement l'OID du tablespace, de la
base de donnes et de la relation identifiant ainsi prcisment la relation.

buffer-flush-done

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche quand une deOid)
mande d'criture se termine. (Notez que
ceci ne reflte que le temps pass pour
fournir la donne au noyau ; ce n'est habituellement pas encore crit sur le disque.)
Les arguments sont identiques ceux de
buffer-flush-start.

buffer-write-dirty-start

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche quand un procesOid)


sus serveur commence crire un tampon
modifi sur disque. Si cela arrive souvent,
cela implique que shared_buffers est trop
petit ou que les paramtres de contrle de
bgwriter ont besoin d'un ajustement.) arg0
et arg1 contiennent les numros de fork et
de bloc de la page. arg2, arg3 et arg4
contiennent respectivement l'OID du ta443

Surveiller l'activit de la base de donnes

Nom

Paramtres

Aperu
blespace, de la base de donnes et de la
relation identifiant ainsi prcisment la relation.

buffer-write-dirty-done

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche quand l'criture


Oid)
d'un tampon modifi est termin. Les arguments sont identiques ceux de bufferwrite-dirty-start.

wal-buffer-write-dirty-start

()

Sonde qui se dclenche quand un processus serveur commence crire un tampon


modifi d'un journal de transactions parce
qu'il n'y a plus d'espace disponible dans le
cache des journaux de transactions. (Si cela arrive souvent, cela implique que
wal_buffers est trop petit.)

wal-buffer-write-dirty-done

()

Sonde qui se dclenche quand l'criture


d'un tampon modifi d'un journal de transactions est termin.

xlog-insert

(unsigned char, unsigned char)

Sonde qui se dclenche quand un enregistrement est insr dans un journal de transactions. arg0 est le gestionnaire de ressource (rmid) pour l'enregistrement. arg1
contient des informations supplmentaires.

xlog-switch

()

Sonde qui se dclenche quand une bascule


du journal de transactions est demande.

smgr-md-read-start

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche au dbut de la lecOid, int)
ture d'un bloc d'une relation. arg0 et arg1
contiennent les numros de fork et de bloc
de la page. arg2, arg3 et arg4 contiennent
respectivement l'OID du tablespace, de la
base de donnes et de la relation identifiant ainsi prcisment la relation. arg5 est
l'identifiant du processus moteur qui a
cr la relation temporaire pour un tampon local ou InvalidBackendId (-1) pour
un tampon partag.

smgr-md-read-done

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche la fin de la lecOid, int, int, int)
ture d'un bloc. arg0 et arg1 contiennent les
numros de fork et de bloc de la page.
arg2, arg3 et arg4 contiennent respectivement l'OID du tablespace, de la base de
donnes et de la relation identifiant ainsi
prcisment la relation. arg5 est
l'identifiant du processus moteur qui a
cr la relation temporaire pour un tampon local ou InvalidBackendId (-1) pour
un tampon partag. arg6 est le nombre
d'octets rellement lus alors que arg7 est
le nombre d'octets demands (s'il y a une
diffrence, il y a un problme).

smgr-md-write-start

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche au dbut de


Oid, int)
l'criture d'un bloc dans une relation. arg0
et arg1 contiennent les numros de fork et
de bloc de la page. arg2, arg3 et arg4
contiennent respectivement l'OID du tablespace, de la base de donnes et de la
relation identifiant ainsi prcisment la relation. arg5 est l'identifiant du processus
444

Surveiller l'activit de la base de donnes

Nom

Paramtres

Aperu
moteur qui a cr la relation temporaire
pour un tampon local ou InvalidBackendId (-1) pour un tampon partag.

smgr-md-write-done

(ForkNumber, BlockNumber, Oid, Oid, Sonde qui se dclenche la fin de


Oid, int, int, int)
l'criture d'un bloc. arg0 et arg1
contiennent les numros de fork et de bloc
de la page. arg2, arg3 et arg4 contiennent
respectivement l'OID du tablespace, de la
base de donnes et de la relation identifiant ainsi prcisment la relation. arg5 est
l'identifiant du processus moteur qui a
cr la relation temporaire pour un tampon local ou InvalidBackendId (-1) pour
un tampon partag. arg6 est le nombre
d'octets rellement crits alors que arg7
est le nombre d'octets demands (si ces
nombres sont diffrents, cela indique un
problme).

sort-start

(int, bool, int, int, bool)

Sonde qui se dclenche quand une opration de tri est dmarr. arg0 indique un tri
de la table, de l'index ou d'un datum. arg1
est true si on force les valeurs uniques.
arg2 est le nombre de colonnes cls. arg3
est le nombre de Ko de mmoire autoris
pour ce travail. arg4 est true si un accs
alatoire au rsultat du tri est requis.

sort-done

(bool, long)

Sonde qui se dclenche quand un tri est


termin. arg0 est true pour un tri externe,
false pour un tri interne. arg1 est le
nombre de blocs disque utiliss pour un tri
externe, ou le nombre de Ko de mmoire
utiliss pour un tri interne.

lwlock-acquire

(LWLockId, LWLockMode)

Sonde qui se dclenche quand un LWLock a t acquis. arg0 est l'identifiant du


LWLock. arg1 est le mode de verrou demand, soit exclusif soit partag.

lwlock-release

(LWLockId)

Sonde qui se dclenche quand un LWLock a t relch (mais notez que tout
processus en attente n'a pas encore t rveill). arg0 est l'identifiant du LWLock.

lwlock-wait-start

(LWLockId, LWLockMode)

Sonde qui se dclenche quand un LWLock n'tait pas immdiatement disponible et qu'un processus serveur a commenc attendre la disponibilit du verrou. arg0 est l'identifiant du LWLock.
arg1 est le mode de verrou demand, soit
exclusif soit partag.

lwlock-wait-done

(LWLockId, LWLockMode)

Sonde qui se dclenche quand un processus serveur n'est plus en attente d'un LWLock (il n'a pas encore le verrou). arg0 est
l'identifiant du LWLock. arg1 est le mode
de verrou demand, soit exclusif soit partag.

lwlock-condacquire

(LWLockId, LWLockMode)

Sonde qui se dclenche quand un LWLock a t acquis avec succs malgr le


fait que l'appelant ait demand de ne pas
attendre. arg0 est l'identifiant du LWLock.
arg1 est le mode de verrou demand, soit

445

Surveiller l'activit de la base de donnes

Nom

Paramtres

Aperu
exclusif soit partag.

lwlock-condacquire-fail

(LWLockId, LWLockMode)

Sonde qui se dclenche quand un LWLock, demand sans attente, n'est pas accept. arg0 est l'identifiant du LWLock.
arg1 est le mode de verrou demand, soit
exclusif soit partag.

lock-wait-start

(unsigned int, unsigned int, unsigned int, Sonde qui se dclenche quand une deunsigned int, unsigned int, LOCKMODE) mande d'un gros verrou (lmgr lock) a
commenc l'attente parce que le verrou
n'tait pas disponible. arg0 arg3 sont les
chmps identifiant l'objet en cours de verrouillage. arg4 indique le type d'objet
verrouiller. arg5 indique le type du verrou
demand.

lock-wait-done

(unsigned int, unsigned int, unsigned int, Sonde qui se dclenche quand une deunsigned int, unsigned int, LOCKMODE) mande d'un gros verrou (lmgr lock) a fini
d'attendre (c'est--dire que le verrou a t
accept). Les arguments sont identiques
ceux de lock-wait-start.

deadlock-found

()

Sonde qui se dclenche quand un verrou


mortel est trouv par le dtecteur.

Tableau 27.4. Types dfinis utiliss comme paramtres de sonde

Type

Definition

LocalTransactionId

unsigned int

LWLockId

int

LWLockMode

int

LOCKMODE

int

BlockNumber

unsigned int

Oid

unsigned int

ForkNumber

int

bool

char

27.4.3. Utiliser les sondes


L'exemple ci-dessous montre un script DTrace pour l'analyse du nombre de transactions sur le systme, comme alternative
l'interrogation rgulire de pg_stat_database avant et aprs un test de performance :
#!/usr/sbin/dtrace -qs
postgresql$1:::transaction-start
{
@start["Start"] = count();
self->ts = timestamp;
}
postgresql$1:::transaction-abort
{
@abort["Abort"] = count();
}
postgresql$1:::transaction-commit
/self->ts/
{
@commit["Commit"] = count();
@time["Total time (ns)"] = sum(timestamp - self->ts);
446

Surveiller l'activit de la base de donnes

self->ts=0;
}
son excution, le script de l'exemple D donne une sortie comme :
# ./txn_count.d `pgrep -n postgres` or ./txn_count.d <PID>
^C
Start
Commit
Total time (ns)

71
70
2312105013

Note
SystemTap utilise une notation diffrente de DTrace pour les scripts de trace, mme si les points de trace sont compatibles. Il est intressant de noter que, lorsque nous avons crit ce texte, les scripts SystemTap doivent rfrencer
les noms des sondes en utilisant des tirets bas doubles la place des tirets simples. Il est prvu que les prochaines
versions de SystemTap corrigent ce problme.
Vous devez vous rappeler que les programmes DTrace doivent tre crits soigneusement, sinon les informations rcoltes pourraient ne rien valoir. Dans la plupart des cas o des problmes sont dcouverts, c'est l'instrumentation qui est errone, pas le systme sous-jacent. En discutant des informations rcupres en utilisant un tel systme, il est essentiel de s'assurer que le script utilis est lui-aussi vrifi et discuter.
D'autres exemples de scripts sont disponibles dans le projet dtrace de PgFoundry.

27.4.4. Dfinir de nouvelles sondes


De nouvelles sondes peuvent tre dfinies dans le code partout o le dveloppeur le souhaite bien que cela ncessite une nouvelle
compilation. Voici les tapes ncessaires pour insrer de nouvelles sondes :
1.

Dcider du nom de la sonde et des donnes ncessaires pour la sonde

2.

Ajoutez les dfinitions de sonde dans src/backend/utils/probes.d

3.

Inclure pg_trace.h s'il n'est pas dj prsent dans le module contenant les points de sonde, et insrer les macros
TRACE_POSTGRESQL aux emplacements souhaits dans le code source

4.

Recompiler et vrifier que les nouvelles sondes sont disponibles

Exemple : Voici un exemple d'ajout d'une sonde pour tracer toutes les nouvelles transactions par identifiant de transaction.
1.

La sonde sera nomme transaction-start et ncessite un paramtre de type LocalTransactionId

2.

Ajout de la dfinition de la sonde dans src/backend/utils/probes.d :


probe transaction__start(LocalTransactionId);
Notez l'utilisation du double tiret bas dans le nom de la sonde. Dans un script DTrace utilisant la sonde, le double tiret bas
doit tre remplac par un tiret, donc transaction-start est le nom documenter pour les utilisateurs.

3.

Au moment de la compilation, transaction__start est converti en une macro appele


TRACE_POSTGRESQL_TRANSACTION_START (notez que les tirets bas ne sont plus doubles ici), qui est disponible en incluant le fichier pg_trace.h. Il faut ajouter l'appel la macro aux bons emplacements dans le code source. Dans ce cas,
cela ressemble :
TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);

4.

Aprs une nouvelle compilation et l'excution du nouveau binaire, il faut vrifier que la nouvelle sonde est disponible en excutant la commande DTrace suivante. Vous deviez avoir cette sortie :
# dtrace -ln transaction-start
447

Surveiller l'activit de la base de donnes

ID
18705
18755
18805
18855
18986

PROVIDER
postgresql49878
postgresql49877
postgresql49876
postgresql49875
postgresql49873

MODULE
postgres
postgres
postgres
postgres
postgres

FUNCTION NAME
StartTransactionCommand
StartTransactionCommand
StartTransactionCommand
StartTransactionCommand
StartTransactionCommand

transaction-start
transaction-start
transaction-start
transaction-start
transaction-start

Il faut faire attention d'autres choses lors de l'ajout de macros de trace dans le code C :

Vous devez faire attention au fait que les types de donnes indiqus pour les paramtres d'une sonde correspondent aux types
de donnes des variables utilises dans la macro. Dans le cas contraire, vous obtiendrez des erreurs de compilation.

Sur la plupart des platformes, si PostgreSQL est construit avec --enable-dtrace, les arguments pour une macro de
trace seront valus chaque fois que le contrle passe dans la macro, mme si aucun traage n'est rellement en cours. Cela a
gnralement peu d'importance si vous rapportez seulement les valeurs de quelques variables locales mais faites bien attention
l'utilisation de fonctions coteuses. Si vous devez le faire, pensez protger la macro avec une vrification pour vous assurer
que la trace est bien active :
if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED())
TRACE_POSTGRESQL_TRANSACTION_START(some_function(...));
Chaque macro de trace a une macro ENABLED correspondante.

448

Chapitre 28. Surveiller l'utilisation des disques


Ce chapitre explique comment surveiller l'utilisation que fait PostgreSQL des disques.

28.1. Dterminer l'utilisation des disques


Chaque table possde un fichier principal dans lequel la majorit des donnes sont stockes. Si la table contient des colonnes
pouvant recevoir des valeurs tendues, il pourrait aussi y avoir un fichier TOAST associ la table. Ce fichier permet de stocker
les valeurs trop larges pour tenir dans la table principale (voir la Section 55.2, TOAST ). Si la table TOAST existe, un index
lui est associ. Des index peuvent galement tre associs la table de base. Chaque table ou index est stock dans un fichier
distinct -- ou plusieurs si la taille du fichier dpasse 1 Go. Les conventions de nommage de ces fichiers sont dcrites dans la Section 55.1, Emplacement des fichiers de la base de donnes .
L'espace disque peut tre surveill de trois faons diffrentes : en utilisant les fonctions SQL listes dans Tableau 9.59,
Fonctions de calcul de la taille des objets de la base de donnes , en utilisant le module oid2name ou en inspectant manuellement les catalogues systme. Les fonctions SQL sont les plus simples utiliser et sont gnralement recommandes. Le reste de
cette section montre comment le faire en inspectant les catalogues systme.
L'utilisation de psql sur une base de donnes rcemment nettoye (VACUUM) ou analyse (ANALYZE) permet de
lancer des requtes pour connatre l'occupation disque d'une table :
SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer';
pg_relation_filepath | relpages
----------------------+---------base/16384/16806
|
60
(1 row)
Chaque page a une taille de 8 Ko, typiquement. (Rappelez-vous que relpages est seulement mis jour par VACUUM, ANALYZE et quelques commandes DDL telles que CREATE INDEX.) Le chemin du fichier n'a d'intrt que si vous voulez examiner directement le fichier de la table.
Pour connatre l'espace disque utilis par les tables TOAST, on utilise une requte similaire la suivante :
SELECT relname, relpages
FROM pg_class,
(SELECT reltoastrelid
FROM pg_class
WHERE relname = 'customer') AS ss
WHERE oid = ss.reltoastrelid OR
oid = (SELECT reltoastidxid
FROM pg_class
WHERE oid = ss.reltoastrelid)
ORDER BY relname;
relname
| relpages
----------------------+---------pg_toast_16806
|
0
pg_toast_16806_index |
1
On peut aussi facilement afficher la taille des index :
SELECT c2.relname, c2.relpages
FROM pg_class c, pg_class c2, pg_index i
WHERE c.relname = 'customer' AND
c.oid = i.indrelid AND
c2.oid = i.indexrelid
ORDER BY c2.relname;
relname
| relpages
----------------------+---------customer_id_indexdex |
26
Les tables et les index les plus volumineux sont reprs l'aide de la requte suivante :
SELECT relname, relpages
FROM pg_class
ORDER BY relpages DESC;
449

Surveiller l'utilisation des disques

relname
| relpages
----------------------+---------bigtable
|
3290
customer
|
3144

28.2. Panne pour disque satur


La tche la plus importante d'un administrateur de base de donnes, en ce qui concerne la surveillance des disques, est de s'assurer
que les disques n'arrivent pas saturation. Un disque de donnes plein ne corrompt pas les donnes mais peut empcher toute activit. S'il s'agit du disque contenant les fichier WAL, une alerte PANIC et un arrt du serveur peuvent survenir.
S'il n'est pas possible de librer de la place sur le disque, il faut envisager le dplacement de quelques fichiers vers d'autres systmes de fichiers l'aide des tablespaces. Voir la Section 21.6, Tablespaces pour plus d'informations.

Astuce
Certains systmes de fichiers ragissent mal proximit des limites de remplissage. Il est donc prfrable de ne pas
attendre ce moment pour ragir.
Si le systme supporte les quotas disque par utilisateur, la base de donnes est alors soumise au quota de l'utilisateur qui excute le
serveur de base de donnes. Dpasser ce quota a les mmes consquences nfastes qu'un disque plein.

450

Chapitre 29. Fiabilit et journaux de transaction


Ce chapitre explique comment les journaux de transaction sont utiliss pour obtenir des traitements efficaces et fiables.

29.1. Fiabilit
La fiabilit est une proprit importante de tout systme de base de donnes srieux. PostgreSQL fait tout ce qui est en son
pouvoir pour garantir une fiabilit toute preuve. Un des aspects de cette fiabilit est que toutes les donnes enregistres par
une transaction valide doivent tre stockes dans un espace non volatile, un espace non sensible aux coupures de courant, aux
bogues du systme d'exploitation et aux problmes matriels (sauf en cas de problme sur l'espace non volatile, bien sr). crire
avec succs les donnes sur le stockage permanent de l'ordinateur (disque dur ou un quivalent) est habituellement suffisant
pour cela. En fait, mme si un ordinateur est vraiment endommag, si le disque dur survit, il peut tre plac dans un autre ordinateur avec un matriel similaire et toutes les transactions valides resteront intactes.
Bien que forcer l'enregistrement des donnes priodiquement sur le disque semble tre une opration simple, ce n'est pas le cas.
Comme les disques durs sont beaucoup plus lents que la mmoire principale et les processeurs, plusieurs niveaux de cache
existent entre la mmoire principale de l'ordinateur et les disques. Tout d'abord, il existe le tampon cache du systme
d'exploitation, qui met en cache les blocs disque frquemment utiliss et combine les critures sur le disque. Heureusement, tous
les systmes d'exploitation donne un moyen de forcer les critures du cache disque vers le disque et PostgreSQL utilise ces
fonctions (voir le paramtre wal_sync_method pour voir comment cela se fait).
Ensuite, il pourrait y avoir un cache dans le contrleur du disque dur ; ceci est assez commun sur les cartes contrleur RAID.
Certains de ces caches sont write-through, signifiant que les critures sont envoyes au lecteur ds qu'elles arrivent. D'autres
sont write-back, signifiant que les donnes sont envoyes au lecteur un peu aprs. De tels caches peuvent apporter une faille
dans la fiabilit car la mmoire du cache du disque contrleur est volatile et qu'elle perdra son contenu la prochaine coupure de
courant. Des cartes contrleur de meilleure qualit ont des caches avec batterie (BBU), signifiant que la carte dispose d'une batterie qui maintient le courant dans le cache en cas de perte de courant. Une fois le courant revenu, les donnes seront crites sur
les disques durs.
Et enfin, la plupart des disques durs ont des caches. Certains sont write-through alors que d'autres sont write-back . Les
mmes soucis sur la perte de donnes existent pour ces deux types de cache. Les lecteurs IDE ont principalement des caches
write-back qui ne survivront pas une perte de courantMany solid-state drives (SSD) also have volatile write-back caches.
Ces caches peuvent typiquement tre dsactivs. Nanmoins, la mthode pour le faire dpend du systme d'exploitation et du
type de disque :

Sur Linux, les disques IDE peuvent tre vrifis avec la commande hdparm -I ; le cache en criture est activ si une
toile (*) se trouve derrire le texte Write cache. hdparm -W peut tre utilis pour dsactiver le cache en criture. Les
disques SCSI peuvent tre vrifis en utilisant sdparm. Utilisez sdparm --get=WCE pour vrifier si le cache en criture est
activ et sdparm --clear=WCE pour le dsactiver.

Sur FreeBSD, les disques IDE peuvent tre vrifis avec atacontrol et le cache en criture dsactiv avec
hw.ata.wc=0 dans le fichier de configuration /boot/loader.conf ; les disques SCSI peuvent tre vrifis en utilisant camcontrol identify, et le cache en criture peut tre vrifi et modifi en utilisant sdparm quand cette commande est
disponible.

Sur Solaris, le cache disque en criture est contrl par format -e. (Le systme de fichiers Solaris ZFS est sr, y compris quand le cache disque en criture est activ car il excute ses propres commandes de vidage du cache.)

Sur Windows, si wal_sync_method vaut open_datasync (la valeur par dfaut), le cache en criture peut tre
dsactiv en dcochant My Computer\Open\disk
drive\Properties\Hardware\Properties\Policies\Enable write caching on the disk. Sinon
configurez wal_sync_method fsync ou fsync_writethrough pour dsactiver le cache en criture.

Sur Mac OS X, le cache en criture peut tre vit en configurant wal_sync_method fsync_writethrough.

Les disques SATA rcents (ceux compatibles ATAPI-6 ou suprieurs) proposent une commande pour vider le cache sur le
disque (FLUSH CACHE EXT) alors que les disques SCSI proposent depuis longtemps une commande similaire, SYNCHRONIZE CACHE. Ces commandes ne sont pas directement accessibles PostgreSQL, mais certains systmes de fichiers
(comme ZFS, ext4) peuvent les utiliser pour vider les donnes sur disque pour les disques dont le cache en criture est activ.
Malheureusement, ces systmes de fichiers se comportent de faon non optimale avec des contrleurs disque quips de batterie
(BBU, acronyme de Battery-Backed Unit). Dans ce type de configuration, la commande de synchronisation force l'criture de
toutes les donnes comprises dans le cache sur les disques, liminant ainsi tout l'intrt d'un cache protg par une batterie. Vous
pouvez lancer l'outil pg_test_fsync, disponible dans le code source de PostgreSQL, pour vrifier si vous tes affect. Si vous
l'tes, les amliorations de performance du cache BBU peuvent tre de nouveaux obtenues en dsactivant les barrires d'criture
451

Fiabilit et journaux de transaction

dans la configuration du systme de fichiers ou en reconfigurant le contrleur de disque, si cela est possible. Si les barrires
d'criture sont dsactives, assurez-vous que la batterie reste active. Une batterie dfectueuse peut tre une cause de perte de donnes. Il reste esprer que les concepteurs de systmes de fichiers et de contrleurs disque finissent par s'attaquer ce comportement gnant.
Quand le systme d'exploitation envoie une demande d'criture au systme de stockage, il ne peut pas faire grand chose pour
s'assurer que les donnes sont arrives dans un espace de stockage non volatile. Ce travail incombe l'administrateur : ce dernier
doit s'assurer que tous les composants de stockage assurent l'intgrit des donnes. vitez les contrleurs disques ne disposant pas
de caches protgs par batterie. Au niveau du disque, dsactivez le cache write-back si le disque ne garantit pas que les donnes seront crites avant un arrt. Si vous utilisez des disques SSD, sachez que beaucoup n'honorent pas les commandes de vidage
de cache par dfaut. Vous pouvez tester la fiabilit du comportement du systme disque en utilisant diskchecker.pl.
Un autre risque concernant la perte des donnes est d aux oprations d'criture sur les plateaux du disque. Les plateaux sont diviss en secteur de 512 octets gnralement. Chaque opration de lecture ou criture physique traite un secteur entier. Quand la demande d'criture arrive au lecteur, elle pourrait contenir des multiples de 512 octets (PostgreSQL crit gnralement 8192 octets, soit 16 secteurs, la fois) et le processus d'criture pourrait chouer cause d'une perte de courant tout moment signifiant
que certains octets pourraient tre crits et les autres perdus. Pour se prvenir contre ce type d'chec, PostgreSQL crit priodiquement des images de page complte sur le stockage permanent des journaux de transactions avant de modifier la page relle sur
disque. En effectuant ceci, lors d'une rcupration aprs un arrt brutal, PostgreSQL peut restaurer des pages crites partiellement partir des journaux de transactions. Si vous avez un systme de fichiers qui vous protge contre les critures de pages incompltes (par exemple ZFS), vous pouvez dsactiver la cration des images de page en utilisant le paramtre full_page_writes.
Les contrleurs disques disposant d'une batterie (BBU pour Battery-Backed Unit) n'empchent pas les critures de pages partielles
sauf s'ils garantissent que les donnes sont crites par pages compltes de 8 Ko.

29.2. Write-Ahead Logging (WAL)


Write-Ahead Logging (WAL) est une mthode conventionnelle pour s'assurer de l'intgrit des donnes. Une description dtaille
peut tre trouve dans la plupart des livres sur le traitement transactionnel. Brivement, le concept central du WAL est d'effectuer
les changements des fichiers de donnes (donc les tables et les index) uniquement aprs que ces changements ont t crits de
faon sr dans un journal, appel journal des transactions. Si nous suivons cette procdure, nous n'avons pas besoin d'crire les
pages de donnes vers le disque chaque validation de transaction car nous savons que, dans l'ventualit d'une dfaillance, nous
serons capables de rcuprer la base de donnes en utilisant le journal : chaque changement qui n'a pas t appliqu aux pages de
donnes peut tre r-excut depuis les enregistrements du journal (ceci est une rcupration roll-forward, aussi connue sous le
nom de REDO).

Astuce
Comme les journaux de transaction permettent de restaurer le contenu des fichiers de base de donnes aprs un arrt brutal, les systmes de fichiers journaliss ne sont pas ncessaires pour stocker avec fiabilit les fichiers de donnes ou les journaux de transactions. En fait, la surcharge cause par la journalisation peut rduire les performances, tout spcialement si la journalisation fait que les donnes du systme de fichiers sont envoyes sur disque.
Heureusement, l'envoi des donnes lors de la journalisation peut souvent tre dsactiv avec une option de montage
du systme de fichiers, par exemple data=writeback sur un systme de fichiers Linux ext3. Par contre, les systmes de fichiers journaliss amliorent la rapidit au dmarrage aprs un arrt brutal.
Utiliser les journaux de transaction permet de rduire de faon significative le nombre d'critures sur le disque puisque seul le
journal a besoin d'tre crit sur le disque pour garantir qu'une transaction a t valide plutt que d'crire dans chaque fichier de
donnes modifi par la transaction. Ce journal est crit squentiellement ce qui fait que le cot de synchronisation du journal est
largement moindre que le cot d'criture des pages de donnes. Ceci est tout spcialement vrai pour les serveurs grant beaucoup
de petites transactions touchant diffrentes parties du stockage de donnes. De plus, quand le serveur traite plein de petites transactions en parallle, un fsync du journal des transactions devrait suffire pour enregistrer plusieurs transactions.
Les journaux de transaction rendent possible le support de sauvegarde en ligne et de rcupration un moment, comme dcrit
dans la Section 24.3, Archivage continu et rcupration d'un instantan (PITR) . En archivant les journaux de transaction, nous
pouvons supporter le retour tout instant couvert par les donnes disponibles dans les journaux de transaction : nous installons
simplement une ancienne sauvegarde physique de la base de donnes et nous rejouons les journaux de transaction jusqu'au moment dsir. Qui plus est, la sauvegarde physique n'a pas besoin d'tre une image instantane de l'tat de la base de donnes -- si
elle a t faite pendant une grande priode de temps, alors rejouer les journaux de transaction pour cette priode corrigera toute incohrence interne.

29.3. Validation asynchrone (Asynchronous Commit)


La validation asynchrone est une option qui permet aux transactions de se terminer plus rapidement. Le risque encouru est de
perdre les transactions les plus rcentes dans le cas o le serveur s'arrte brutalement. Dans beaucoup d'applications, le compromis
452

Fiabilit et journaux de transaction

est acceptable.
Comme le dcrit la section prcdente, la validation d'une transaction est habituellement synchrone : le serveur attend que les enregistrements des journaux de transaction soient bien sauvegards sur un disque avant de renvoyer l'information du succs de
l'opration au client. Ce dernier a donc la garantie qu'une transaction valide est stocke de faon sre, donc mme en cas d'arrt
brutal immdiatement aprs. Nanmoins, pour les petites transactions, ce dlai est une partie importante de la dure totale
d'excution de la transaction. Slectionner le mode de validation asynchrone signifie que le serveur renvoie le succs de
l'opration ds que la transaction est termine logiquement, donc avant que les enregistrements du journal de transaction que cette
transaction a gnr ne soient rellement stockes sur disque. Ceci peut apporter une acclration importante pour les petites transactions.
La validation asynchrone introduit le risque des pertes de donnes. Il existe un petit dlai entre le moment o le rapport de la fin
d'une transaction est envoy au client et celui o la transaction est rellement enregistre (c'est--dire le moment o le rsultat de
cette transaction ne pourra pas tre perdu mme en cas d'arrt brutal du serveur). Du coup, la validation asynchrone ne devrait pas
tre utilise si le client se base sur le fait que la transaction est enregistre de faon sre. Par exemple, une banque ne devra pas
utiliser la validation asynchrone pour l'enregistrement d'une transaction sur les oprations sur un compte bancaire. Dans de nombreux autres scnarios, comme la trace d'vnements, il n'y a pas de garantie forte de ce type.
Le risque pris avec l'utilisation de la validation asynchrone concerne la perte de donnes, pas la corruption de donnes. Si le serveur s'arrte brutalement, il rcuprera en rejouant les journaux de transaction jusqu'au dernier enregistrement qui a t envoy au
disque. La base de donnes sera donc dans un tat cohrent mais toutes les transactions qui n'auront pas t enregistres sur disque
n'apparatront pas. L'effet immdiat est donc la perte des dernires transactions. Comme les transactions sont rejoues dans l'ordre
de validation, aucune incohrence ne sera introduite -- par exemple, si la transaction B fait des modifications sur les effets d'une
prcdente transaction A, il n'est pas possible que les effets de A soient perdus alors que les effets de B sont prservs.
L'utilisateur peut slectionner le mode de validation de chaque transaction, donc il est possible d'avoir en mme temps des transactions valides en synchrone et en asynchrone. Une grande flexibilit est permise entre performance et durabilit de certaines transactions. Le mode de validation est contrl par le paramtre utilisateur synchronous_commit, qui peut tre modifi comme tout
autre paramtre utilisateur. Le mode utilis pour toute transaction dpend de la valeur de synchronous_commit au dbut de la
transaction.
Certaines commandes, par exemple DROP TABLE, sont forces en mode synchrone quelque soit la valeur du paramtre synchronous_commit. Ceci a pour but de s'assurer de la cohrence entre le systme de fichiers du serveur et l'tat logique de la
base de donnes. Les commandes grant la validation en deux phases, comme PREPARE TRANSACTION, sont aussi toujours
synchrones.
Si la base de donnes s'arrte brutalement lors du dlai entre une validation asynchrone et l'criture des enregistrements dans le
journal des transactions, les modifications ralises lors de cette transaction seront perdues. La dure de ce dlai est limite car un
processus en tche de fond (le wal writer ) envoie les enregistrements non crits des journaux de transaction sur le disque toutes
les wal_writer_delay millisecondes. La dure maximum actuelle de ce dlai est de trois fois wal_writer_delay car le processus d'criture des journaux de transaction est conu pour favoriser l'criture de pages compltes lors des priodes de grosses activits.

Attention
Un arrt en mode immdiat est quivalent un arrt brutal et causera du coup la perte des validations asynchrones.
La validation asynchrone fournit un comportement diffrent de la simple dsactivation de fsync. fsync est un paramtre pour le
serveur entier qui modifie le comportement de toutes les transactions. Cela dsactive toute logique de PostgreSQL qui tente de
synchroniser les critures aux diffrentes parties de la base de donnes (c'est--dire l'arrt brutal du matriel ou du systme
d'exploitation, par un chec de PostgreSQL lui-mme) pourrait rsulter en une corruption arbitraire de l'tat de la base de donnes. Dans de nombreux scnarios, la validation asynchrone fournit la majorit des amliorations de performances obtenues par la
dsactivation de fsync, mais sans le risque de la corruption de donnes.
commit_delay semble aussi trs similaire la validation asynchrone mais il s'agit en fait d'une mthode de validation synchrone
(en fait, commit_delay est ignor lors d'une validation asynchrone). commit_delay a pour effet l'application d'un dlai juste
avant qu'une validation synchrone tente d'enregistrement les journaux de transaction sur disque, dans l'espoir que la demande de
synchronisation occasionne par les critures puissent aussi servir d'autres transactions valides peu prs en mme temps.
Configurer commit_delay sert seulement quand beaucoup de transactions sont valides en parallle et il est difficile de configurer correctement ce paramtre avec une valeur qui aide plus qu'elle ne dessert.

29.4. Configuration des journaux de transaction


Il y a plusieurs paramtres de configuration associs aux journaux de transaction qui affectent les performances de la base de donnes. Cette section explique leur utilisation. Consultez le Chapitre 18, Configuration du serveur pour des dtails sur la mise en
place de ces paramtres de configuration.
453

Fiabilit et journaux de transaction

Dans la squence des transactions, les points de contrles (appels checkpoints) sont des points qui garantissent que les fichiers de
donnes table et index ont t mis jour avec toutes les informations enregistres dans le journal avant le point de contrle. Au
moment du point de contrle, toutes les pages de donnes non propres sont crites sur le disque et une entre spciale, pour le
point de contrle, est crite dans le journal. (Les modifications taient dj envoyes dans les journaux de transactions.) En cas de
dfaillance, la procdure de rcupration recherche le dernier enregistrement d'un point de vrification dans les traces
(enregistrement connus sous le nom de redo log ) partir duquel il devra lancer l'opration REDO. Toute modification effectue sur les fichiers de donnes avant ce point est garantie d'avoir t enregistre sur disque. Du coup, aprs un point de vrification, tous les segments reprsentant des journaux de transaction prcdant celui contenant le redo record ne sont plus ncessaires et peuvent tre soit recycls soit supprims (quand l'archivage des journaux de transaction est activ, ces derniers doivent
tre archivs avant d'tre recycls ou supprims).
CHECKPOINT doit crire toutes les pages de donnes modifies sur disque, ce qui peut causer une charge disque importante. Du
coup, l'activit des CHECKPOINT est dilue de faon ce que les entres/sorties disque commencent au dbut du CHECKPOINT
et se termine avant le dmarrage du prochain CHECKPOINT ; ceci minimise la dgradation des performances lors des CHECKPOINT.
Le processus d'criture en tche de fond lance automatiquement un point de contrle de temps en temps : tous les checkpoint_segments journaux de transaction ou ds que checkpoint_timeout secondes se sont coules. Les paramtres par dfaut sont
respectivement de trois journaux et de 300 secondes (5 minutes). Il est galement possible de forcer la cration d'un point de
contrle en utilisant la commande SQL CHECKPOINT.
La rduction de checkpoint_segments et/ou checkpoint_timeout implique des points de contrle plus frquents. Cela
permet une rcupration plus rapide aprs dfaillance puisqu'il y a moins d'critures synchroniser. Cependant, il faut quilibrer
cela avec l'augmentation du cot d'criture des pages de donnes modifies. Si full_page_writes est configur (ce qui est la valeur
par dfaut), il reste un autre facteur considrer. Pour s'assurer de la cohrence des pages de donnes, la premire modification
d'une page de donnes aprs chaque point de vrification rsulte dans le traage du contenu entier de la page. Dans ce cas, un intervalle de points de vrification plus petit augmentera le volume en sortie des journaux de transaction, diminuant lgrement
l'intrt d'utiliser un intervalle plus petit et impliquant de toute faon plus d'entres/sorties au niveau disque.
Les points de contrle sont assez coteux, tout d'abord parce qu'ils crivent tous les tampons utiliss, et ensuite parce que cela suscite un trafic supplmentaire dans les journaux de transaction, comme indiqu ci-dessus. Du coup, il est conseill de configurer les
paramtres en relation assez haut pour que ces points de contrle ne surviennent pas trop frquemment. Pour une vrification rapide de l'adquation de vos paramtres, vous pouvez configurer le paramtre checkpoint_warning. Si les points de contrle arrivent plus rapidement que checkpoint_warning secondes, un message est affich dans les journaux applicatifs du serveur
recommandant d'accrotre checkpoint_segments. Une apparition occasionnelle d'un message ne doit pas vous alarmer mais,
s'il apparat souvent, alors les paramtres de contrle devraient tre augments. Les oprations en masse, comme les transferts importants de donnes via COPY, pourraient tre la cause de l'apparition d'un tel nombre de messages d'avertissements si vous
n'avez pas configur checkpoint_segments avec une valeur suffisamment haute.
Pour viter de remplir le systme disque avec de trs nombreuses critures de pages, l'criture des pages modifis pendant un point
de vrification est tale sur une priode de temps. Cette priode est contrle par checkpoint_completion_target, qui est donn
comme une fraction de l'intervalle des points de vrification. Le taux d'entres/sorties est ajust pour que le point de vrification se
termine quand la fraction donne de checkpoint_segments journaux de transaction a t consomme ou quand la fraction
donn de checkpoint_timeout secondes s'est coule (la condition que se verra vrifie la premire). Avec une valeur par
dfaut de 0,5, PostgreSQL peut s'attendre terminer chaque point de vrification en moiti moins de temps qu'il ne faudra pour
lancer le prochain point de vrification. Sur un systme trs proche du taux maximum en entre/sortie pendant des oprations normales, vous pouvez augmenter checkpoint_completion_target pour rduire le chargement en entre/sortie d aux
points de vrification. L'inconvnient de ceci est que prolonger les points de vrification affecte le temps de rcupration parce
qu'il faudra conserver plus de journaux de transaction si une rcupration est ncessaire. Bien que checkpoint_completion_target puisse valoir 1.0, il est bien mieux de la configurer une valeur plus basse que a (au maximum 0,9) car les points de vrification incluent aussi d'autres activits en dehors de l'criture des pages modifies. Une valeur de
1,0 peut avoir pour rsultat des points de vrification qui ne se terminent pas temps, ce qui aurait pour rsultat des pertes de performance cause de variation inattendue dans le nombre de journaux ncessaires.
Il y aura toujours au moins un journal de transaction et normalement pas plus de fichiers que (2 + checkpoint_completion_target) * checkpoint_segments + 1 ou checkpoint_segments + wal_keep_segments + 1.
Chaque journal fait normalement 16 Mo (bien que cette taille puisse tre modifie lors de la compilation du serveur). Vous pouvez
utiliser cela pour estimer l'espace disque ncessaire au stockage des journaux de transaction. D'habitude, quand les vieux journaux
ne sont plus ncessaires, ils sont recycls (renomms pour devenir les prochains segments dans une squence numrote). S'il y a
plus de 3 * checkpoint_segments + 1 fichiers cause d'un pic temporaire du taux d'criture des journaux, ceux inutiliss seront effacs au lieu d'tre recycls jusqu' ce que le systme soit en-dessous de cette limite.
Dans le mode de restauration d'archive et dans le mode standby, le serveur ralise priodiquement des restartpoints (points de redmarrage). C'est similaire aux checkpoints lors du fonctionnement normal : le serveur force l'criture de son tat sur disque, met
jour le fichier pg_control pour indiquer que les donnes dj traites des journaux de transactions n'ont plus besoin d'tre
454

Fiabilit et journaux de transaction

parcourues de nouveau, puis recycle les anciens journaux de transactions trouvs dans le rpertoire pg_xlog. Un restartpoint est
dclench si au moins un enregistrement checkpoint a t rejou et chaque fois que checkpoint_timeout secondes se sont
coules depuis le dernier restartpoint. Dans le mode standby, un restartpoint est aussi dclench si checkpoint_segments
journaux de transactions ont t rejous depuis le dernier restartpoint et qu'au moins un enregistrement checkpoint a t rejou.
Les restartpoints ne peuvent tre raliss plus frquemment que les checkpoints du matre car les restartpoints peuvent seulement
tre raliss aux enregistrements de checkpoint.
Il existe deux fonctions WAL internes couramment utilises : LogInsert et LogFlush. LogInsert est utilise pour placer
une nouvelle entre l'intrieur des tampons WAL en mmoire partage. S'il n'y a plus d'espace pour une nouvelle entre, LogInsert devra crire (autrement dit, dplacer dans le cache du noyau) quelques tampons WAL remplis. Ceci n'est pas dsirable
parce que LogInsert est utilise lors de chaque modification bas niveau de la base (par exemple, lors de l'insertion d'une ligne)
quand un verrou exclusif est pos sur des pages de donnes affectes. cause de ce verrou, l'opration doit tre aussi rapide que
possible. Pire encore, crire des tampons WAL peut forcer la cration d'un nouveau journal, ce qui peut prendre beaucoup plus de
temps. Normalement, les tampons WAL doivent tre crits et vids par une requte de LogFlush qui est faite, la plupart du
temps, au moment de la validation d'une transaction pour assurer que les entres de la transaction sont crites vers un stockage
permanent. Sur les systmes avec une importante criture de journaux, les requtes de LogFlush peuvent ne pas arriver assez
souvent pour empcher LogInsert d'avoir crire lui-mme sur disque. Sur de tels systmes, on devrait augmenter le nombre
de tampons WAL en modifiant le paramtre de configuration wal_buffers. Quand full_page_writes est configur et que le systme
est trs occup, configurer cette variable avec une valeur plus importante aide avoir des temps de rponse plus rguliers lors de
la priode suivant chaque point de vrification.
Le paramtre commit_delay dfinit la dure d'endormissement en micro-secondes du processus serveur aprs l'criture d'une entre de validation dans le journal avec LogInsert avant d'excuter un LogFlush. Ce dlai permet aux autres processus du serveur d'ajouter leurs entres de validation dans le journal afin de tout crire vers le disque avec une seule synchronisation du journal. Aucune mise en sommeil n'aura lieu si fsync n'est pas disponible ou si moins de commit_siblings autres sessions sont, ce
moment, dans des transactions actives ; cela vite de dormir quand il est improbable qu'une autre session fasse bientt une validation. Notez que dans la plupart des plate-formes, la rsolution d'une requte d'endormissement est de 10 millisecondes, donc un
commit_delay diffrent de zro et configur entre 1 et 10000 micro-secondes a le mme effet. Les bonnes valeurs pour ce paramtre ne sont pas encore claires ; les essais sont encourags.
Le paramtre wal_sync_method dtermine la faon dont PostgreSQL demande au noyau de forcer les mises jour des journaux
de transaction sur le disque. Toutes les options ont un mme comportement avec une exception, fsync_writethrough, qui
peut parfois forcer une criture du cache disque mme quand d'autres options ne le font pas. Nanmoins, dans la mesure o la fiabilit ne disparat pas, c'est avec des options spcifiques la plate-forme que la rapidit la plus importante sera observe ; vous
pouvez tester la performance de chaque option en utilisant l'outil pg_test_fsync disponible dans les sources de PostgreSQL. Notez
que ce paramtre est ignor si fsync a t dsactiv.
Activer le paramtre de configuration wal_debug ( supposer que PostgreSQL ait t compil avec le support de ce paramtre)
permet d'enregistrer chaque appel WAL LogInsert et LogFlush dans les journaux applicatifs du serveur. Cette option pourrait tre remplace par un mcanisme plus gnral dans le futur.

29.5. Vue interne des journaux de transaction


Le mcanisme WAL est automatiquement disponible ; aucune action n'est requise de la part de l'administrateur except de
s'assurer que l'espace disque requis par les journaux de transaction soit prsent et que tous les rglages soient faits (regardez la
Section 29.4, Configuration des journaux de transaction ).
Les journaux de transaction sont stocks dans le rpertoire pg_xlog sous le rpertoire de donnes, comme un ensemble de fichiers, chacun d'une taille de 16 Mo gnralement (cette taille pouvant tre modifie en prcisant une valeur pour l'option -with-wal-segsize de configure lors de la construction du serveur). Chaque fichier est divis en pages de gnralement
8 Ko (cette taille pouvant tre modifie en prcisant une valeur pour l'option --with-wal-blocksize de configure). Les enttes de l'entre du journal sont dcrites dans access/xlog.h ; le contenu de l'entre dpend du type de l'vnement qui est enregistr. Les fichiers sont nomms suivant un nombre qui est toujours incrment et qui commence
000000010000000000000000. Les nombres ne bouclent pas, mais cela prendra beaucoup de temps pour puiser le stock de
nombres disponibles.
Il est avantageux que les journaux soient situs sur un autre disque que celui des fichiers principaux de la base de donnes. Cela
peut se faire en dplaant le rpertoire pg_xlog vers un autre emplacement (alors que le serveur est arrt) et en crant un lien
symbolique de l'endroit d'origine dans le rpertoire principal de donnes au nouvel emplacement.
Le but de WAL est de s'assurer que le journal est crit avant l'altration des entres dans la base, mais cela peut tre mis en chec
par les disques qui rapportent une criture russie au noyau quand, en fait, ils ont seulement mis en cache les donnes et ne les ont
pas encore stocks sur le disque. Une coupure de courant dans ce genre de situation peut mener une corruption irrcuprable des
donnes. Les administrateurs devraient s'assurer que les disques contenant les journaux de transaction de PostgreSQL ne produisent pas ce genre de faux rapports. (Voir Section 29.1, Fiabilit .)

455

Fiabilit et journaux de transaction

Aprs qu'un point de contrle ait t fait et que le journal ait t crit, la position du point de contrle est sauvegarde dans le fichier pg_control. Donc, au dbut de la restauration, le serveur lit en premier pg_control et ensuite l'entre du point de
contrle ; ensuite, il excute l'opration REDO en parcourant vers l'avant partir de la position du journal indique dans l'entre
du point de contrle. Parce que l'ensemble du contenu des pages de donnes est sauvegard dans le journal la premire modification de page aprs un point de contrle (en supposant que full_page_writes n'est pas dsactiv), toutes les pages changes depuis
le point de contrle seront restaures dans un tat cohrent.
Pour grer le cas o pg_control est corrompu, nous devons permettre le parcours des segments de journaux existants en ordre
inverse -- du plus rcent au plus ancien -- pour trouver le dernier point de vrification. Ceci n'a pas encore t implment.
pg_control est assez petit (moins d'une page disque) pour ne pas tre sujet aux problmes d'criture partielle et, au moment o
ceci est crit, il n'y a eu aucun rapport d'checs de la base de donnes uniquement cause de son incapacit lire pg_control.
Donc, bien que cela soit thoriquement un point faible, pg_control ne semble pas tre un problme en pratique.

456

Chapitre 30. Tests de rgression


Les tests de rgression composent un ensemble exhaustif de tests pour l'implmentation SQL dans PostgreSQL. Ils testent les
oprations SQL standards ainsi que les fonctionnalits tendues de PostgreSQL.

30.1. Lancer les tests


Les tests de rgression peuvent tre lancs sur un serveur dj install et fonctionnel ou en utilisant une installation temporaire
l'intrieur du rpertoire de construction. De plus, ils peuvent tre lancs en mode parallle ou en mode squentiel . Le
mode squentiel lance les scripts de test en srie, alors que le mode parallle lance plusieurs processus serveurs pour parallliser
l'excution des groupes de tests. Les tests parallles permettent de s'assurer du bon fonctionnement des communications interprocessus et du verrouillage.

30.1.1. Excuter les tests sur une installation temporaire


Pour lancer les tests de rgression en parallle aprs la construction mais avant l'installation, il suffit de saisir
gmake check
dans le rpertoire de premier niveau (on peut aussi se placer dans le rpertoire src/test/regress et y lancer la commande). Au final, la sortie devrait ressembler quelque chose comme
======================
All 100 tests passed.
======================
ou une note indiquant l'chec des tests. Voir la Section 30.2, valuation des tests avant de supposer qu'un chec reprsente un problme srieux.

Avertissement
Sur les systmes ne disposant pas de sockets de domaine Unix, la mthode de tests dmarre un serveur temporaire configur pour accepter toute connexion provenant de la machine locale. Tout utilisateur local peut obtenir
les droits superutilisateur de la base de donnes en se connectant ce serveur et pourrait en principe exploiter
tous les droits de l'utilisateur du systme d'exploitation excutant les tests. De ce fait, il n'est pas recommand
d'utiliser gmake check sur un systme partag avec d'autres utilisateurs. la place, lancez les tests aprs avoir
termin l'installation, comme indiqu dans la section suivante.
Comme cette mthode de tests excute un serveur temporaire, cela ne fonctionnera pas si vous avez construit le serveur en tant
que root, tant donn que le serveur ne dmarre pas en tant que root. La procdure recommande est de ne pas construire en tant
que root ou de raliser les tests aprs avoir termin l'installation.
Si vous avez configur PostgreSQL pour qu'il s'installe dans un emplacement o existe dj une ancienne installation de PostgreSQL et que vous lancez gmake check avant d'installer la nouvelle version, vous pourriez trouver que les tests chouent
parce que les nouveaux programmes essaient d'utiliser les bibliothques partages dj installes (les symptmes typiques sont
des plaintes concernant des symboles non dfinis). Si vous souhaitez lancer les tests avant d'craser l'ancienne installation, vous
devrez construire avec configure --disable-rpath. Nanmoins, il n'est pas recommand d'utiliser cette option pour
l'installation finale.
Les tests de rgression en parallle lancent quelques processus avec votre utilisateur. Actuellement, le nombre maximum est de
vingt scripts de tests en parallle, ce qui signifie 40 processus : il existe un processus serveur, un psql et habituellement un processus parent pour le psql de chaque script de tests. Si votre systme force une limite par utilisateur sur le nombre de processus,
assurez-vous que cette limite est d'au moins 50, sinon vous pourriez obtenir des checs hasardeux dans les tests en parallle. Si
vous ne pouvez pas augmenter cette limite, vous pouvez diminuer le degr de paralllisme en initialisant le paramtre
MAX_CONNECTIONS. Par exemple,
gmake MAX_CONNECTIONS=10 check
ne lance pas plus de dix tests en mme temps.

30.1.2. Excuter les tests sur une installation existante


Pour lancer les tests aprs l'installation (voir le Chapitre 15, Procdure d'installation de PostgreSQL du code source), initialisez un espace de donnes et lancez le serveur comme expliqu dans le Chapitre 17, Configuration du serveur et mise en place,
puis lancez
457

Tests de rgression

gmake installcheck
ou pour un test parallle
gmake installcheck-parallel
Les tests s'attendront contacter le serveur sur l'hte local et avec le numro de port par dfaut, sauf en cas d'indication contraire
avec les variables d'environnement PGHOST et PGPORT. Les tests seront excutes dans une base de donnes nomme regression ; toute base de donnes existante de mme nom sera supprime. Les tests crent aussi de faon temporaire des objets globaux, comme des utilisateurs tels que regressuserN.

30.1.3. Additional Test Suites


The gmake check and gmake installcheck commands run only the core regression tests, which test built-in functionality of the PostgreSQL server. The source distribution also contains additional test suites, most of them having to do with addon functionality such as optional procedural languages.
To run all test suites applicable to the modules that have been selected to be built, including the core tests, type one of these commands at the top of the build tree:
gmake check-world
gmake installcheck-world
These commands run the tests using temporary servers or an already-installed server, respectively, just as previously explained for
gmake check and gmake installcheck. Other considerations are the same as previously explained for each method. Note
that gmake check-world builds a separate temporary installation tree for each tested module, so it requires a great deal more
time and disk space than gmake installcheck-world.
Alternatively, you can run individual test suites by typing gmake check or gmake installcheck in the appropriate subdirectory of the build tree. Keep in mind that gmake installcheck assumes you've installed the relevant module(s), not only
the core server.
The additional tests that can be invoked this way include:

Regression tests for optional procedural languages (other than PL/pgSQL, which is tested by the core tests). These are located
under src/pl.

Regression tests for contrib modules, located under contrib. Not all contrib modules have tests.

Regression tests for the ECPG interface library, located in src/interfaces/ecpg/test.

Tests stressing behavior of concurrent sessions, located in src/test/isolation.

When using installcheck mode, these tests will destroy any existing databases named pl_regression,
contrib_regression, isolationtest, regress1, or connectdb, as well as regression.

30.1.4. Locale et encodage


Par dfaut, les tests sur une installation temporaire utilise la locale dfinie dans l'environnement et l'encodage de la base de donnes correspondante est dtermine par initdb. Il peut tre utile de tester diffrentes locales en configurant les variables
d'environnement appropries. Par exemple :
gmake check LANG=C
gmake check LC_COLLATE=en_US.utf8 LC_CTYPE=fr_CA.utf8
Pour des raisons d'implmentation, configurer LC_ALL ne fonctionne pas dans ce cas. Toutes les autres variables d'environnement
lies la locale fonctionnent.
Lors d'un test sur une installation existante, la locale est dtermine par l'instance existante et ne peut pas tre configure sparment pour un test.
Vous pouvez aussi choisir l'encodage de la base explicitement en configurant la variable ENCODING. Par exemple :
gmake check LANG=C ENCODING=EUC_JP
Configurer l'encodage de la base de cette faon n'a un sens que si la locale est C. Dans les autres cas, l'encodage est choisi automatiquement partir de la locale. Spcifier un encodage qui ne correspond pas la locale donnera une erreur.
458

Tests de rgression

L'encodage de la base de donnes peut tre configur pour des tests sur une installation temporaire ou existante, bien que, dans ce
dernier cas, il doit tre compatible avec la locale d'installation.

30.1.5. Tests supplmentaires


La suite interne de tests de rgression contient quelques fichiers de tests qui ne sont pas excuts par dfaut car ils pourraient dpendre de la plateforme ou prendre trop de temps pour s'excuter. Vous pouvez les excuter ou en excuter d'autres en configurant
la variable EXTRA_TESTS. Par exemple, pour excuter le test numeric_big :
gmake check EXTRA_TESTS=numeric_big
Pour excuter les tests sur le collationnement :
gmake check EXTRA_TESTS=collate.linux.utf8 LANG=en_US.utf8
Le test collate.linux.utf8 fonctionne seulement sur les plateformes Linux/glibc et seulementquand il est excut sur une
base de donnes dont l'encodage est UTF-8.

30.1.6. Tests du Hot Standby


La distribution des sources contient aussi des tests de rgression du comportement statique du Hot Standby. Ces tests requirent un
serveur primaire et un serveur en attente, les deux en cours d'excution, le dernier acceptant les modifications des journaux de
transactions du primaire en utilisant soit l'envoi des fichiers soit la rplication en flux. Ces serveurs ne sont pas automatiquement
crs pour vous, pas plus que la configuration n'est documente ici. Merci de vrifier les diffrentes sections de la documentation
qui sont dj dvolues aux commandes requises et aux problmes associs.
Pour excuter les tests Hot Standby, crez une base de donnes appele regression sur le primaire.
psql -h primary -c "CREATE DATABASE regression"
Ensuite, excutez le script prparatoire src/test/regress/sql/hs_primary_setup.sql sur le primaire dans la base
de donnes de rgression. Par exemple :
psql -h primary -f src/test/regress/sql/hs_primary_setup.sql regression
Attendez la propagation des modifications vers le serveur en standby.
Maintenant, arrangez-vous pour que la connexion par dfaut la base de donnes soit sur le serveur en standby sous test (par
exemple en configurant les variables d'environnement PGHOST et PGPORT). Enfin, lancez l'action standbycheck partir du
rpertoire de la suite de tests de rgression.
cd src/test/regress
gmake standbycheck
Certains comportements extrmes peuvent aussi tre crs sur le primaire en utilisant le script
test/regress/sql/hs_primary_extremes.sql pour permettre le test du comportement du serveur en attente.

src/

30.2. valuation des tests


Quelques installations de PostgreSQL proprement installes et totalement fonctionnelles peuvent chouer sur certains des
tests de rgression cause de certains points spcifiques la plateforme comme une reprsentation de nombres virgules flottantes ou message wording . Les tests sont actuellement valus en utilisant une simple comparaison diff avec les sorties gnres sur un systme de rfrence, donc les rsultats sont sensibles aux petites diffrences systme. Quand un test est rapport
comme chou , toujours examiner les diffrences entre les rsultats attendus et ceux obtenus ; vous pourriez trs bien trouver
que les diffrences ne sont pas significatives. Nanmoins, nous nous battons toujours pour maintenir des fichiers de rfrences
prcis et jour pour toutes les plateformes supports de faon ce que tous les tests puissent russir.
Les sorties actuelles des tests de rgression sont dans les fichiers du rpertoire src/test/regress/results. Le script de
test utilise diff pour comparer chaque fichier de sortie avec les sorties de rfrence stockes dans le rpertoire src/
test/regress/expected. Toutes les diffrences sont conserves pour que vous puissiez les regarder dans src/
test/regress/regression.diffs. (Lors de l'excution d'une suite de tests en dehors des tests internes, ces fichiers
doivent apparatre dans le sous-rpertoire adquat, mais pas src/test/regress.)
Si, pour certaines raisons, une plateforme particulire gnre un chec pour un test donn mais qu'une revue de la sortie vous
convaint que le rsultat est valide, vous pouvez ajouter un nouveau fichier de comparaison pour annuler le rapport d'chec pour les
prochains lancements du test. Voir la Section 30.3, Fichiers de comparaison de variants pour les dtails.
459

Tests de rgression

30.2.1. Diffrences dans les messages d'erreurs


Certains des tests de rgression impliquent des valeurs en entre intentionnellement invalides. Les messages d'erreur peuvent provenir soit du code de PostgreSQL soit des routines systme de la plateforme hte. Dans ce dernier cas, les messages pourraient
varier entre plateformes mais devraient toujours reflter des informations similaires. Ces diffrences dans les messages rsulteront
en un chec du test de rgression qui pourrait tre valid aprs vrification.

30.2.2. Diffrences au niveau des locales


Si vous lancez des tests sur un serveur initialis avec une locale autre que C, alors il pourrait y avoir des diffrences dans les
ordres de tris. La suite de tests de rgression est initialise pour grer ce problme en fournissant des fichiers de rsultats alternatifs qui grent ensemble un grand nombre de locales.
Pour excuter les tests dans une locale diffrente lors de l'utilisation de la mthode d'installation temporaire, passez les variables
d'environnement relatives la locale sur la ligne de commande de gmake, par exemple :
gmake check LANG=de_DE.utf8
(Le pilote de tests des rgressions dconfigure LC_ALL, donc choisir la locale par cette variable ne fonctionne pas.) Pour ne pas
utiliser de locale, vous devez soit dconfigurer toutes les variables d'environnement relatives aux locales (ou les configurer C) ou
utiliser une option spciale :
gmake check NO_LOCALE=1
Lors de l'excution des tests sur une installation existante, la configuration de la locale est dtermine d'aprs l'installation existante. Pour la modifier, initialiser le cluster avec une locale diffrente en passant les options appropries initdb.
En gnral, il est conseill d'essayer l'excution des tests de rgression dans la configuration de locale souhaite pour l'utilisation
en production, car cela testera aussi les portions de code relatives l'encodage et la locale qui pourront tre utilises en production. Suivant l'environnement du systme d'exploitation, vous pourrez obtenir des checs, mais vous saurez au moins le comportement attendre sur la locale lorsque vous utiliserez vos vraies applications.

30.2.3. Diffrences au niveau des dates/heures


La plupart des rsultats date/heure sont dpendants de l'environnement de zone horaire. Les fichiers de rfrence sont gnrs pour
la zone horaire PST8PDT (Berkeley, Californie), et il y aura des checs apparents si les tests ne sont pas lancs avec ce paramtrage de fuseau horaire. Le pilote des tests de rgression initialise la variable d'environnement PGTZ PST8PDT ce qui nous assure normalement de bons rsultats.

30.2.4. Diffrences sur les nombres virgules flottantes


Quelques tests impliquent des calculs sur des nombres flottants 64 bits (double precision) partir de colonnes de tables. Des diffrences dans les rsultats appliquant des fonctions mathmatiques des colonnes double precision ont t observes. Les tests de
float8 et geometry sont particulirement sensibles aux diffrences entre plateformes, voire aux diffrentes options
d'optimisation des compilateurs. L'il humain est ncessaire pour dterminer la vritable signification de ces diffrences, habituellement situes aprs la dixime dcimale.
Certains systmes affichent moins zro comme -0 alors que d'autres affichent seulement 0.
Certains systmes signalent des erreurs avec pow() et exp() diffremment suivant le mcanisme attendu du code de PostgreSQL.

30.2.5. Diffrences dans l'ordre des lignes


Vous pourriez voir des diffrences dans lesquelles les mmes lignes sont affiches dans un ordre diffrent de celui qui apparat
dans le fichier de rfrence. Dans la plupart des cas, ce n'est pas strictement parl un bogue. La plupart des scripts de tests de rgression ne sont pas assez stricts pour utiliser un ORDER BY sur chaque SELECT et, du coup, l'ordre des lignes pourrait ne pas
tre correctement dfini suivant la spcification SQL. En pratique, comme nous sommes avec les mmes requtes sur les mmes
donnes avec le mme logiciel, nous obtenons habituellement le mme rsultat sur toutes les plateformes et le manque d'ORDER
BY n'est pas un problme. Quelques requtes affichent des diffrences d'ordre entre plateformes. Lors de tests avec un serveur dj
install, les diffrences dans l'ordre des lignes peuvent aussi tre causes par un paramtrage des locales une valeur diffrente de
C ou par un paramtrage personnalis, comme des valeurs personnalises de work_mem ou du cot du planificateur.
Du coup, si vous voyez une diffrence dans l'ordre, vous n'avez pas vous inquiter sauf si la requte possde un ORDER BY que
votre rsultat ne respecte pas. Nanmoins, rapportez tout de mme ce problme que nous ajoutions un ORDER BY cette requte
pour liminer les faux checs dans les versions suivantes.
460

Tests de rgression

Vous pourriez vous demander pourquoi nous n'ordonnons pas toutes les requtes des tests de rgression explicitement pour supprimer ce problme une fois pour toutes. La raison est que cela rendrait les tests de rgression moins utiles car ils tendraient exercer
des types de plans de requtes produisant des rsultats ordonns l'exclusion de celles qui ne le font pas.

30.2.6. Profondeur insuffisante de la pile


Si les tests d'erreurs se terminent avec un arrt brutal du serveur pendant la commande select infinite_recurse(),
cela signifie que la limite de la plateforme pour la taille de pile du processus est plus petite que le paramtre max_stack_depth ne
l'indique. Ceci est corrigeable en excutant le postmaster avec une limite pour la taille de pile plus importante (4 Mo est recommand avec la valeur par dfaut de max_stack_depth). Si vous n'tes pas capables de le faire, une alternative est de rduire la
valeur de max_stack_depth.
Sur les plateformes supportant getrlimit(), le serveur devrait choisir automatiquement une valeur sre pour
max_stack_depth ; donc, moins de surcharger manuellement ce paramtre, un chec de ce type est un bug reporter.

30.2.7. Test random


Le script de tests random a pour but de produire des rsultats alatoires. Dans de trs rares cas, ceci fait chouer random aux tests
de rgression. Saisir :
diff results/random.out expected/random.out
ne devrait produire au plus que quelques lignes diffrentes. Cela est normal et ne devient proccupant que si les tests random
chouent en permanence lors de tests rpts

30.2.8. Paramtres de configuration


Lors de l'excution de tests contre une installation existante, certains paramtres configurs des valeurs spcifiques pourraient
causer l'chec des tests. Par exemple, modifier des paramtres comme enable_seqscan ou enable_indexscan pourrait
tre la cause de changements de plan affectant le rsultat des tests qui utilisent EXPLAIN.

30.3. Fichiers de comparaison de variants


Comme certains de ces tests produisent de faon inhrente des rsultats dpendants de l'environnement, nous avons fourni des
moyens de spcifier des fichiers rsultats alternatifs attendus . Chaque test de rgression peut voir plusieurs fichiers de comparaison affichant les rsultats possibles sur diffrentes plateformes. Il existe deux mcanismes indpendants pour dterminer quel
fichier de comparaison est utilis pour chaque test.
Le premier mcanisme permet de slectionner les fichiers de comparaison suivant des plateformes spcifiques. Le fichier de correspondance src/test/regress/resultmap dfinit le fichier de comparaison utiliser pour chaque plateforme. Pour liminer les tests chous par erreur pour une plateforme particulire, vous choisissez ou vous crez un fichier variant de rsultat,
puis vous ajoutez une ligne au fichier resultmap.
Chaque ligne du fichier de correspondance est de la forme
nomtest:sortie:modeleplateform=fichiercomparaison
Le nom de tests est juste le nom du module de tests de rgression particulier. La valeur en sortie indique le fichier vrifier. Pour
les tests de rgression standards, c'est toujours out. La valeur correspond l'extension de fichier du fichier en sortie. Le modle
de plateforme est un modle dans le style des outils Unix expr (c'est--dire une expression rationnelle avec une ancre implicite ^
au dbut). Il est test avec le nom de plateforme affiche par config.guess. Le nom du fichier de comparaison est le nom de base du
fichier de comparaison substitu.
Par exemple : certains systmes interprtent les trs petites valeurs en virgule flottante comme zro, plutt que de rapporter une erreur. Ceci fait quelques petites diffrences dans le test de rgression float8. Du coup, nous fournissons un fichier de comparaison variable, float8-small-is-zero.out, qui inclut les rsultats attendus sur ces systmes. Pour faire taire les messages
d' chec errons sur les plateformes OpenBSD, resultmap inclut
float8:out:i.86-.*-openbsd=float8-small-is-zero.out
qui se dclenche sur toute machine o la sortie de config.guess correspond i.86-.*-openbsd. D'autres lignes dans resultmap slectionnent le fichier de comparaison variable pour les autres plateformes si c'est appropri.
Le second mcanisme de slection des fichiers de comapraison variants est bien plus automatique : il utilise simplement la
meilleure correspondance parmi les diffrents fichiers de comparaison fournis. Le script pilote des tests de rgression considre le fichier de comparaison standard pour un test, nomtest.out, et les fichiers variants nomms nomtest_chiffre.out
(o chiffre est un seul chiffre compris entre 0 et 9). Si un tel fichier tablit une correspondance exacte, le test est considr
russi ; sinon, celui qui gnre la plus petite diffrence est utilis pour crer le rapport d'chec. (Si resultmap inclut une entre
461

Tests de rgression

pour le test particulier, alors le nomtest de base est le nom de substitut donn dans resultmap.)
Par exemple, pour le test char, le fichier de comparaison char.out contient des rsultats qui sont attendus dans les locales C et
POSIX, alors que le fichier char_1.out contient des rsultats tris comme ils apparaissent dans plusieurs autres locales.
Le mcanisme de meilleure correspondance a t conu pour se dbrouiller avec les rsultats dpendant de la locale mais il peut
tre utilis dans toute situation o les rsultats des tests ne peuvent pas tre prdits facilement partir de la plateforme seule. Une
limitation de ce mcanisme est que le pilote test ne peut dire quelle variante est en fait correcte dans l'environnement en cours ;
il rcuprera la variante qui semble le mieux fonctionner. Du coup, il est plus sr d'utiliser ce mcanisme seulement pour les rsultats variants que vous voulez considrer comme identiquement valides dans tous les contextes.

30.4. Examen de la couverture du test


Le code source de PostgreSQL peut tre compil avec des informations supplmentaire sur la couverture des tests, pour qu'il devienne possible d'examiner les parties du code couvertes par les tests de rgression ou par toute suite de tests excute avec le
code. Cette fonctionnalit est supporte en compilant avec GCC et ncessite les programmes gcov et lcov.
La suite typique de commandes ressemble ceci :
./configure --enable-coverage ... OTHER OPTIONS ...
gmake
gmake check # or other test suite
gmake coverage-html
Puis pointez votre navigateur HTML vers coverage/index.html. Les commandes gmake travaillent aussi dans les sousrpertoires.
Pour rinitialiser le compteur des excutions entre chaque test, excutez :
gmake coverage-clean

462

Partie IV. Interfaces client


Cette partie dcrit les interfaces de programmation client distribues avec PostgreSQL. Chacun de ces chapitres peut tre lu indpendamment. On trouve beaucoup d'autres interfaces de programmation de clients, chacune distribue sparment avec sa
propre documentation. Les lecteurs de cette partie doivent tre familiers de l'utilisation des requtes SQL de manipulation et
d'interrogation d'une base (voir la Partie II, Langage SQL ) et surtout du langage de programmation utilis par l'interface.

Chapitre 31. libpq - Bibliothque C


libpq est l'interface de programmation pour les applications C avec PostgreSQL. libpq est un ensemble de fonctions permettant aux programmes clients d'envoyer des requtes au serveur PostgreSQL et de recevoir les rsultats de ces requtes.
libpq est aussi le moteur sous-jacent de plusieurs autres interfaces de programmation de PostgreSQL, comme ceux crits pour
C++, Perl, Python, Tcl et ECPG. Donc, certains aspects du comportement de libpq seront importants pour vous si vous utilisez
un de ces paquetages. En particulier, la Section 31.13, Variables d'environnement , la Section 31.14, Fichier de mots de
passe et la Section 31.17, Support de SSL dcrivent le comportement que verra l'utilisateur de toute application utilisant
libpq.
Quelques petits programmes sont inclus la fin de ce chapitre (Section 31.20, Exemples de programmes ) pour montrer comment crire des programmes utilisant libpq. Il existe aussi quelques exemples complets d'applications libpq dans le rpertoire
src/test/examples venant avec la distribution des sources.
Les programmes clients utilisant libpq doivent inclure le fichier d'en-tte libpq-fe.h et doivent tre li avec la bibliothque
libpq.

31.1. Fonctions de contrle de connexion la base de donnes


Les fonctions suivantes concernent la ralisation d'une connexion avec un serveur PostgreSQL. Un programme peut avoir
plusieurs connexions ouvertes sur des serveurs un mme moment (une raison de la faire est d'accder plusieurs bases de donnes). Chaque connexion est reprsente par un objet PGconn, obtenu avec la fonction PQconnectdb, PQconnectdbParams, ou PQsetdbLogin. Notez que ces fonctions renverront toujours un pointeur d'objet non nul, sauf peut-tre dans un cas
de manque de mmoire pour l'allocation de l'objet PGconn. La fonction PQstatus doit tre appele pour vrifier le code retour
pour une connexion russie avant de lancer des requtes via l'objet de connexion.

Avertissement
Sur Unix, la cration d'un processus via l'appel systme fork() avec des connexions libpq ouvertes peut amener
des rsultats imprvisibles car les processus parent et enfants partagent les mme sockets et les mmes ressources
du systme d'exploitation. Pour cette raison, un tel usage n'est pas recommand, alors qu'excuter un exec partir du processus enfant pour charger un nouvel excutable est sr.

Note
Sur Windows, il existe un moyen pour amliorer les performances si une connexion seule la base de donnes
est ouverte puis ferme de faon rpte. En interne, libpq appelle WSAStartup() et WSACleanup() respectivement pour le dbut et la fin de la transaction. WSAStartup() incrmente un compteur de rfrence interne
la bibliothque Windows. Ce compteur est dcrment par WSACleanup(). Quand le compteur arrive un,
appeler WSACleanup() libre toutes les ressources et toutes les DLL associes. C'est une opration coteuse.
Pour viter cela, une application peut appeler manuellement WSAStartup() afin que les ressources ne soient
pas libres quand la dernire connexion est ferme.
PQconnectdbParams
tablit une nouvelle connexion au serveur de base de donnes.
PGconn *PQconnectdbParams(const char **keywords, const char **values, int
expand_dbname);
Cette fonction ouvre une nouvelle connexion la base de donnes en utilisant les paramtres partir des deux tableaux termins par un NULL. Le premier, keywords, est dfini comme un tableau de chanes, chacune tant un mot-cl. Le second, values, donne la valeur pour chaque mot-cl. Contrairement PQsetdbLogin ci-dessous, l'ensemble des paramtres peut tre tendu sans changer la signature de la fonction donc son utilisation (ou ses versions non bloquantes, savoir PQconnectStartParams et PQconnectPoll) est recommende pour les nouvelles applications.
Quand expand_dbname est diffrent de zro, la valeur du mot-cl dbname peut tre reconnue comme une chane
conninfo. Voir ci-dessous pour les dtails.
Les tableaux fournis peuvent tre vides pour utiliser tous les paramtres par dfaut ou peuvent contenir un ou plusieurs paramtres. Ils doivent avoir la mme longueur. Le traitement stoppera au premier lment NULL dcouvert dans le tableau
464

libpq - Bibliothque C

keywords.
Les mots cls actuellement reconnus sont :
host
Nom de l'hte sur lequel se connecter. S'il commence avec un slash, il spcifie une communication par domaine Unix plutt
qu'une communication TCP/IP ; la valeur est le nom du rpertoire o le fichier socket est stock. Par dfaut, quand host
n'est pas spcifi, il s'agit d'une communication par socket de domaine Unix dans /tmp (ou tout autre rpertoire de socket
spcifi lors de la construction de PostgreSQL). Sur les machines sans sockets de domaine Unix, la valeur par dfaut est de
se connecter localhost.
hostaddr
Adresse IP numrique de l'hte de connexion. Elle devrait tre au format d'adresse standard IPv4, c'est--dire
172.28.40.9. Si votre machine supporte IPv6, vous pouvez aussi utiliser ces adresses. La communication TCP/IP est toujours utilise lorsqu'une chane non vide est spcifie pour ce paramtre.
Utiliser hostaddr au lieu de host permet l'application d'viter une recherche de nom d'hte, qui pourrait tre importante
pour les applications ayant des contraintes de temps. Un nom d'hte est requis pour les mthodes d'authentification Kerberos,
GSSAPI ou SSPI, ainsi que pour la vrification de certificat SSL en verify-full. Les rgles suivantes sont observes :

Si host est indiqu sans hostaddr, une recherche du nom de l'hte est lance.

Si hostaddr est indiqu sans host, la valeur de hostaddr donne l'adresse rseau de l'hte. La tentative de connexion
chouera si la mthode d'authentification ncessite un nom d'hte.

Si host et hostaddr sont indiqus, la valeur de hostaddr donne l'adresse rseau de l'hte. La valeur de host est
ignore sauf si la mthode d'authentification la rclame, auquel cas elle sera utilise comme nom d'hte.

Notez que l'authentification a de grandes chances d'chouer si host n'est pas identique au nom du serveur pour l'adresse rseau hostaddr. De mme, host plutt que hostaddr est utilis pour identifier la connexion dans ~/.pgpass (voir la
Section 31.14, Fichier de mots de passe ).
Sans un nom ou une adresse d'hte, libpq se connectera en utilisant un socket local de domaine Unix. Sur des machines sans
sockets de domaine Unix, il tentera une connexion sur localhost.
port
Numro de port pour la connexion au serveur ou extension du nom de fichier pour des connexions de domaine Unix.
dbname
Nom de la base de donnes. Par dfaut, la mme que le nom utilisateur.
user
Nom de l'utilisateur PostgreSQL qui se connecte. Par dfaut, il s'agit du nom de l'utilisateur ayant lanc l'application.
password
Mot de passe utiliser si le serveur demande une authentification par mot de passe.
connect_timeout
Attente maximum pour une connexion, en secondes (saisie comme une chane d'entier dcimaux). Zro ou non spcifi signifie une attente indfinie. Utiliser un dcompte de moins de deux secondes n'est pas recommand.
client_encoding
Ceci configure le paramtre client_encoding pour cette connexion. En plus des valeurs acceptes par l'option serveur
correspondante, vous pouvez utiliser auto pour dterminer le bon encodage partir de la locale courante du client (variable
d'environnement LC_CTYPE sur les systmes Unix).
options
Ajout d'options en ligne de commande envoyer au serveur l'excution. Par exemple, en le configurant -c geqo=off,
cela configure la valeur de la session pour le paramtre geqo off. Pour une discussion dtaille des options disponibles,
voir Chapitre 18, Configuration du serveur.
application_name
Prcise une valeur pour le paramtre de configuration application_name.
fallback_application_name
Indique une valeur de secours pour le paramtre de configuration application_name. Cette valeur sera utilise si aucune valeur
n'est donne application_name via un paramtre de connexion ou la variable d'environnement. L'indication d'un nom
de secours est utile pour les programmes outils gnriques qui souhaitent configurer un nom d'application par dfaut mais permettrait sa surcharge par l'utilisateur.
keepalives
465

libpq - Bibliothque C

Contrle si les paramtres TCP keepalives ct client sont utiliss. La valeur par dfaut est de 1, signifiant ainsi qu'ils sont
utiliss. Vous pouvez le configurer 0, ce qui aura pour effet de les dsactiver si vous n'en voulez pas. Ce paramtre est ignor pour les connexions ralises via un socket de domaine Unix.
keepalives_idle
Contrle le nombre de secondes d'inactivit aprs lequel TCP doit envoyer un message keepalive au server. Une valeur de zro utilise la valeur par dfaut du systme. Ce paramtre est ignor pour les connexions ralises via un socket de domaine
Unix ou si les paramtres keepalives sont dsactivs. Ce paramtre est uniquement support sur les systmes o les options
TCP_KEEPIDLE ou TCP_KEEPALIVE sont disponibles et sur Windows ; pour les autres systmes, ce paramtre n'a pas
d'effet.
keepalives_interval
Contrle le nombre de secondes aprs lequel un message TCP keepalive doit tre retransmis si le serveur ne l'a pas acquitt.
Une valeur de zro utilise la valeur par dfaut du systme. Ce paramtre est uniquement support sur les systmes o l'option
TCP_KEEPINTVL est disponible et sur Windows ; pour les autres systmes, ce paramtre n'a pas d'effet.
keepalives_count
Contrle le nombre de messages TCP keepalives pouvant tre perdus avant que la connexion du client au serveur ne soit
considre comme perdue. Une valeur de zro utilise la valeur par dfaut du systme. Ce paramtre est uniquement support
sur les systmes o l'option TCP_KEEPCNT est disponible et sur Windows ; pour les autres systmes, ce paramtre n'a pas
d'effet.
tty
Ignor (auparavant, ceci indiquait o envoyer les traces de dbogage du serveur).
sslmode
Cette option dtermine si ou avec quelle priorit une connexion TCP/IP SSL scurise sera ngocie avec le serveur. Il existe
six modes :
disable
essaie seulement une connexion non SSL
allow
essaie en premier lieu une connexion non SSL ; si cette tentative choue, essaie une connexion SSL
prefer (default)
essaie en premier lieu une connexion SSL ; si cette tentative choue, essaie une connexion non SSL
require
essaie seulement une connexion SSL. Si un certificat racine d'autorit est prsent, vrifie le certificat de la mme faon que si
verify-ca tait spcifi
verify-ca
essaie seulement une connexion SSL et vrifie que le certificat client est cr par une autorit de certificats (CA) de confiance
verify-full
essaie seulement une connexion SSL, vrifie que le certificat client est cr par un CA de confiance et que le nom du serveur
correspond bien celui du certificat
Voir Section 31.17, Support de SSL pour une description dtaille de comment ces options fonctionnent.
sslmode est ignor pour la communication par socket de domaine Unix. Si PostgreSQL est compil sans le support de
SSL, l'utilisation des options require, verify-ca et verify-full causera une erreur alors que les options allow et
prefer seront acceptes mais libpq ne sera pas capable de ngocier une connexion SSL.
Cette option est obsolte et remplace par l'option sslmode.
Si initialise 1, une connexion SSL au serveur est requise (ce qui est quivalent un sslmode require). libpq refusera
alors de se connecter si le serveur n'accepte pas une connexion SSL. Si initialise 0 (la valeur par dfaut), libpq ngociera le
type de connexion avec le serveur (quivalent un sslmode prefer). Cette option est seulement disponible si
PostgreSQL est compil avec le support SSL.
sslcert
Ce paramtre indique le nom du fichier du certificat SSL client, remplaant le
~/.postgresql/postgresql.crt. Ce paramtre est ignor si la connexion n'utilise pas SSL.

fichier

par

dfaut,

sslkey
Ce paramtre indique l'emplacement de la cl secrte utilise pour le certificat client. Il peut soit indiquer un nom de fichier
qui sera utilis la place du fichier ~/.postgresql/postgresql.key par dfaut, soit indiquer un cl obtenue par un
moteur externe (les moteurs sont des modules chargeables d'OpenSSL). La spcification d'un moteur externe devrait
consister en un nom de moteur et un identifiant de cl spcifique au moteur, les deux spars par une virgule. Ce paramtre
466

libpq - Bibliothque C

est ignor si la connexion n'utilise pas SSL.


sslrootcert
Ce paramtre indique le nom d'un fichier contenant le ou les certificats de l'autorit de certificats SSL (CA). Si le fichier
existe, le certificat du serveur sera vrifi. La signature devra appartenir une de ces autorits. La valeur par dfaut de ce paramtre est ~/.postgresql/root.crt.
sslcrl
Ce paramtre indique le nom du fichier de la liste de rvocation du certificat SSL. Les certificats lists dans ce fichier, s'il
existe bien, seront rejets lors d'une tentative d'authentification avec le certificat du serveur. La valeur par dfaut de ce paramtre est ~/.postgresql/root.crl.
requirepeer
Ce paramtre indique le nom d'utilisateur du serveur au niveau du systme d'exploitation, par exemple requirepeer=postgres. Lors d'une connexion par socket de domaine Unix, si ce paramtre est configur, le client vrifie au dbut de la connexion si le processus serveur est excut par le nom d'utilisateur indiqu ; dans le cas contraire, la connexion est
annule avec une erreur. Ce paramtre peut tre utilis pour fournir une authentification serveur similaire celle disponible
pour les certificats SSL avec les connexions TCP/IP. (Notez que, si la socket de domaine Unix est dans /tmp ou tout espace
autoris en criture pour tout le monde, n'importe quel utilisateur peut mettre un serveur en coute cet emplacement. Utilisez
ce paramtre pour vous assurer que le serveur est excut par un utilisateur de confiance.) Cette option est seulement supporte par les plateformes sur lesquelles la mthode d'authentification peer est disponible ; voir Section 19.3.7, Peer Authentication .
krbsrvname
Nom du service Kerberos utiliser lors de l'authentification avec Kerberos 5 et GSSAPI. Il doit correspondre avec le nom du
service spcifi dans la configuration du serveur pour que l'authentification Kerberos puisse russir (voir aussi la Section 19.3.5, Authentification Kerberos et Section 19.3.3, Authentification GSSAPI .)
gsslib
Bibliothque GSS utiliser pour l'authentification GSSAPI. Utilise seulement sur Windows. Configurer gssapi pour forcer libpq utiliser la bibliothque GSSAPI pour l'authentification au lieu de SSPI par dfaut.
service
Nom du service utiliser pour des paramtres supplmentaires. Il spcifie un nom de service dans pg_service.conf
contenant des paramtres de connexion supplmentaires. Ceci permet aux applications de spcifier uniquement un nom de
service, donc les paramtres de connexion peuvent tre maintenus de faon centrale. Voir Section 31.15, Fichier des
connexions de service .
Si un paramtre manque, alors la variable d'environnement correspondante est vrifie (voir la Section 31.13, Variables
d'environnement ). Si elle n'est pas disponible, alors la valeur par dfaut indique est utilise.
Si expand_dbname est diffrent de zro et que dbname contient un signe =, il est pris en tant que chane conninfo
exactement de la mme faon qu'il a t pass PQconnectdb (voir ci-dessous). Les mots-cls traits prcdemment seront
surchargs par les mots-cls de la chane conninfo.
En gnral, les mots-cls sont traits partir du dbut de ces tableaux dans l'ordre de l'index. L'effet qui en dcoule est que,
quand les mots-cls sont rpts, la valeur correspondant au dernier traitement est conserve. Du coup, via un placement attentionn du mot-cl dbname, il est possible de dterminer ce qui pourrait tre surcharg par une chane conninfo et ce qui
ne le sera pas.
PQconnectdb
tablit une nouvelle connexion un serveur de bases de donnes.
PGconn *PQconnectdb(const char *conninfo);
Cette fonction ouvre une nouvelle connexion la base de donnes en utilisant les paramtres pris partir de la chane
conninfo.
La chane passe peut tre vide pour utiliser tous les paramtres par dfaut ou elle peut contenir un ou plusieurs paramtres,
spars par des espaces blancs. Chaque configuration est de la forme motcl = valeur. Les espaces autour du signe gal
sont optionnels. Pour crire une valeur vide ou une valeur contenant des espaces, il est ncessaire de la placer entre guillemets
simples, par exemple motcl = 'une valeur'. Les guillemets simples et les antislashs dans la valeur doivent tre
chapps avec un antislash, donc \' et \\.
Les mots-cls actuellement reconnus sont identiques ceux indiqus ci-dessus.
PQsetdbLogin
Cre une nouvelle connexion sur le serveur de bases de donnes.
467

libpq - Bibliothque C

PGconn *PQsetdbLogin(const
const
const
const
const
const
const

char
char
char
char
char
char
char

*pghost,
*pgport,
*pgoptions,
*pgtty,
*dbName,
*login,
*pwd);

C'est le prdcesseur de PQconnectdb avec un ensemble fixe de paramtres. Cette fonction a les mmes fonctionnalits
sauf que les paramtres manquants seront toujours initialiss avec leur valeurs par dfaut. crire NULL ou une chane vide
pour un de ces paramtres fixes dont vous souhaitez utiliser la valeur par dfaut.
Si dbName contient un signe =, il est pris pour une chane conninfo exactement de la mme faon que si elle tait passe
PQconnectdb, et le reste des paramtres est ensuite appliqu comme ci-dessus.
PQsetdb
Cre une nouvelle connexion sur le serveur de bases de donnes.
PGconn *PQsetdb(char
char
char
char
char

*pghost,
*pgport,
*pgoptions,
*pgtty,
*dbName);

C'est une macro faisant appel PQsetdbLogin avec des pointeurs nuls pour les paramtres login et pwd. Elle est fournie
pour une compatibilit ascendante des trs vieux programmes.
PQconnectStartParams, PQconnectStart, PQconnectPoll
Cre une connexion au serveur de bases de donnes d'une faon non bloquante.
PGconn *PQconnectStartParams(const char **keywords, const char **values, int
expand_dbname);
PGconn *PQconnectStart(const char *conninfo);
PostgresPollingStatusType PQconnectPoll(PGconn *conn);
Ces trois fonctions sont utilises pour ouvrir une connexion au serveur de bases de donnes d'une faon telle que le thread de
votre application n'est pas bloqu sur les entres/sorties distantes en demandant la connexion. Le but de cette approche est que
l'attente de la fin des entres/sorties peut se faire dans la boucle principale de l'application plutt qu' l'intrieur de PQconnectdbParams ou PQconnectdb, et donc l'application peut grer des oprations en parallle d'autres activits.
Avec PQconnectStartParams, la connexion la base de donnes est faite en utilisant les paramtres partir des tableaux keywords et values, et contrle par expand_dbname, comme dcrit ci-dessus pour PQconnectdbParams.
Avec PQconnectStart, la connexion la base de donnes est faite en utilisant les paramtres provenant de la chane
conninfo comme dcrit ci-dessus pour PQconnectdb.
Ni PQconnectStartParams ni PQconnectStart ni PQconnectPoll ne bloqueront, aussi longtemps qu'un certain
nombre de restrictions est respect :

Les paramtres hostaddr et host sont utiliss de faon approprie pour vous assurer que la requte de nom et la requte inverse ne soient pas lances. Voir la documentation de ces paramtres avec PQconnectdbParams ci-dessus
pour les dtails.

Si vous appelez PQtrace, assurez-vous que l'objet de flux dans lequel vous enregistrez les traces ne bloquera pas.

Assurez-vous que le socket soit dans l'tat appropri avant d'appeler PQconnectPoll, comme dcrit ci-dessous.

Note : l'utilisation de PQconnectStartParams est analogue PQconnectStart affiche ci-dessous.


Pour commencer une demande de connexion non bloquante, appelez conn = PQconnectStart("connection_info_string"). Si conn est nul, alors libpq a t incapable d'allouer une nouvelle structure PGconn. Sinon, un
pointeur valide vers une structure PGconn est renvoy (bien qu'il ne reprsente pas encore une connexion valide vers la base
de donnes). Au retour de PQconnectStart, appelez status = PQstatus(conn). Si status vaut CONNECTION_BAD, PQconnectStart a chou.
Si PQconnectStart russit, la prochaine tape est d'appeler souvent libpq de faon ce qu'il continue la squence de
connexion. Utilisez PQsocket(conn) pour obtenir le descripteur de socket sous la connexion la base de donnes. Du
468

libpq - Bibliothque C

coup, une boucle : si le dernier retour de PQconnectPoll(conn) est PGRES_POLLING_READING, attendez que la socket soit prte pour lire (comme indiqu par select(), poll() ou une fonction systme similaire). Puis, appelez de nouveau PQconnectPoll(conn). En revanche, si le dernier retour de PQconnectPoll(conn) est
PGRES_POLLING_WRITING, attendez que la socket soit prte pour crire, puis appelez de nouveau PQconnectPoll(conn). Si vous devez encore appeler PQconnectPoll, c'est--dire juste aprs l'appel de PQconnectStart,
continuez comme s'il avait renvoy PGRES_POLLING_WRITING. Continuez cette boucle jusqu' ce que PQconnectPoll(conn) renvoie PGRES_POLLING_FAILED, indiquant que la procdure de connexion a chou ou
PGRES_POLLING_OK, indiquant le succs de la procdure de connexion.
tout moment pendant la connexion, le statut de cette connexion pourrait tre vrifi en appelant PQstatus. Si le rsultat
est CONNECTION_BAD, alors la procdure de connexion a chou ; si, au contraire, elle renvoie CONNECTION_OK, alors
la connexion est prte. Ces deux tats sont dtectables partir de la valeur de retour de PQconnectPoll, dcrite ci-dessus.
D'autres tats pourraient survenir lors (et seulement dans ce cas) d'une procdure de connexion asynchrone. Ils indiquent l'tat
actuel de la procdure de connexion et pourraient tre utile pour fournir un retour l'utilisateur. Ces statuts sont :
CONNECTION_STARTED
Attente de la connexion raliser.
CONNECTION_MADE
Connexion OK ; attente d'un envoi.
CONNECTION_AWAITING_RESPONSE
Attente d'une rponse du serveur.
CONNECTION_AUTH_OK
Authentification reue ; attente de la fin du lancement du moteur.
CONNECTION_SSL_STARTUP
Ngociation du cryptage SSL.
CONNECTION_SETENV
Ngociation des paramtrages de l'environnement.
Notez que, bien que ces constantes resteront (pour maintenir une compatibilit), une application ne devrait jamais se baser sur
un ordre pour celles-ci ou sur tout ou sur le fait que le statut fait partie de ces valeurs documents. Une application pourrait
faire quelque chose comme a :
switch(PQstatus(conn))
{
case CONNECTION_STARTED:
feedback = "Connexion en cours...";
break;
case CONNECTION_MADE:
feedback = "Connect au serveur...";
break;
.
.
.
default:
feedback = "Connexion...";
}
Le paramtre de connexion connect_timeout est ignor lors de l'utilisation PQconnectPoll ; c'est de la responsabilit
de l'application de dcider quand une priode de temps excessive s'est coule. Sinon, PQconnectStart suivi par une
boucle PQconnectPoll est quivalent PQconnectdb.
Notez que si PQconnectStart renvoie un pointeur non nul, vous devez appeler PQfinish lorsque vous en avez termin
avec lui, pour supprimer la structure et tous les blocs mmoires qui lui sont associs. Ceci doit tre fait mme si la tentative de
connexion choue ou est abandonne.
PQpingParams
PQpingParams renvoie le statut du serveur. Elle accepte les mmes paramtres de connexions que PQconnectdbParams, dcrite ci-dessus. Nanmoins, il n'est pas ncessaire de fournir un nom d'utilisateur, un mot de passe ou un nom de
base de donnes correct pour obtenir le statut du serveur.
PGPing PQpingParams(const char **keywords, const char **values, int expand_dbname);
La fonction renvoie une des valeurs suivantes :
469

libpq - Bibliothque C

PQPING_OK
Le serveur est en cours d'excution et semble accepter les connexions.
PQPING_REJECT
Le serveur est en cours d'excution mais est dans un tat qui lui interdit les connexions (dmarrage, arrt ou restauration aprs
un arrt brutal).
PQPING_NO_RESPONSE
Le serveur ne peut pas tre contact. Cela peut indiquer que le serveur n'est pas en cours d'excution ou qu'il y a une erreur
dans les paramtres de connexion fournis (par exemple un mauvais numro de port), ou encore qu'il y ait un problme rseau
(par exemple, un pare-feu qui bloque la demande de connexion).
PQPING_NO_ATTEMPT
Aucune tentative n'a t faite pour contacter le serveur car les paramtres fournis sont l'vidence mauvais ou parce qu'il y a
un problme du ct client (par exemple, un manque de mmoire).
PQping
PQping renvoie le statut du serveur. Elle accepte les mmes paramtres de connexions que PQconnectdb, dcrite cidessus. Nanmoins, il n'est pas ncessaire de fournir un nom d'utilisateur, un mot de passe ou un nom de base de donnes correct pour obtenir le statut du serveur.
PGPing PQping(const char *conninfo);
Les valeurs renvoyes sont identiques celles de PQpingParams.

31.2. Fonctions de statut de connexion


Ces fonctions sont utilises pour interroger le statut d'un objet de connexion existant.

Astuce
Les dveloppeurs d'application libpq devraient tre attentif au maintien de leur abstraction PGconn. Utilisez les
fonctions d'accs dcrites ci-dessous pour obtenir le contenu de PGconn. Rfrence les champs internes de PGconn
en utilisant libpq-int.h n'est pas recommand parce qu'ils sont sujets modification dans le futur.
Les fonctions suivantes renvoient les valeurs des paramtres utiliss pour la connexion. Ces valeurs sont fixes pour la dure de vie
de l'objet PGconn.
PQdb
Renvoie le nom de la base de donnes de la connexion.
char *PQdb(const PGconn *conn);
PQuser
Renvoie le nom d'utilisateur utilis pour la connexion.
char *PQuser(const PGconn *conn);
PQpass
Renvoie le mot de passe utilis pour la connexion.
char *PQpass(const PGconn *conn);
PQhost
Renvoie le nom d'hte du serveur utilis pour la connexion.
char *PQhost(const PGconn *conn);
PQport
Renvoie le numro de port utilis pour la connexion.
char *PQport(const PGconn *conn);
PQtty
Renvoie le TTY de dbogage pour la connexion (ceci est obsolte car le serveur ne fait plus attention au paramtrage du TTY
470

libpq - Bibliothque C

mais les fonctions restent pour des raisons de compatibilit ascendante).


char *PQtty(const PGconn *conn);
PQoptions
Renvoie les options en ligne de commande passes lors de la demande de connexion.
char *PQoptions(const PGconn *conn);
Les fonctions suivantes renvoient le statut car il peut changer suite l'excution d'oprations sur l'objet PGconn.
PQstatus
Renvoie l'tat de la connexion.
ConnStatusType PQstatus(const PGconn *conn);
Le statut peut faire partie d'un certain nombre de valeurs. Nanmoins, seules deux ne concernent pas les procdures de
connexion asynchrone : CONNECTION_OK et CONNECTION_BAD. Une bonne connexion de la base de donnes a l'tat
CONNECTION_OK. Une tentative choue de connexion est signale par le statut CONNECTION_BAD. D'habitude, un tat
OK restera ainsi jusqu' PQfinish mais un chec de communications pourrait rsulter en un statut changeant prmaturment CONNECTION_BAD. Dans ce cas, l'application pourrait essayer de rcuprer en appelant PQreset.
Voir l'entre de PQconnectStartParams, PQconnectStart et de PQconnectPoll en regard aux autres codes de
statut, qui pourraient tre renvoys.
PQtransactionStatus
Renvoie l'tat actuel de la transaction du serveur.
PGTransactionStatusType PQtransactionStatus(const PGconn *conn);
Le statut peut tre PQTRANS_IDLE (actuellement inactif), PQTRANS_ACTIVE (une commande est en cours), PQTRANS_INTRANS (inactif, dans un bloc valide de transaction) ou PQTRANS_INERROR (inactif, dans un bloc de transaction
chou). PQTRANS_UNKNOWN est report si la connexion est mauvaise. PQTRANS_ACTIVE est report seulement quand
une requte a t envoye au serveur mais qu'elle n'est pas termine.

Attention
PQtransactionStatus donnera des rsultats incorrects lors de l'utilisation d'un serveur PostgreSQL
7.3 qui a dsactiv le paramtre autocommit. La fonctionnalit autocommit, ct serveur, est obsolte et
n'existe pas dans les versions serveur ultrieures.
PQparameterStatus
Recherche un paramtrage actuel du serveur.
const char *PQparameterStatus(const PGconn *conn, const char *paramName);
Certaines valeurs de paramtres sont reportes par le serveur automatiquement ou lorsque leur valeurs changent. PQparameterStatus peut tre utilis pour interroger ces paramtrages. Il renvoie la valeur actuelle d'un paramtre s'il est connu et
NULL si le paramtre est inconnu.
Les paramtres reports pour la version actuelle incluent server_version, server_encoding, client_encoding,
application_name, is_superuser, session_authorization, datestyle, IntervalStyle, TimeZone,
integer_datetimes et standard_conforming_strings. (server_encoding, TimeZone et integer_datetimes n'taient pas rapports dans les versions antrieures la 8.0 ; standard_conforming_strings
n'tait pas rapport dans les versions antrieures la 8.1; IntervalStyle n'tait pas rapport dans les versions antrieures
la 8.4; application_name n'tait pas rapport dans les versions antrieures la 9.0). Notez que server_version,
server_encoding et integer_datetimes ne peuvent pas changer aprs le lancement du serveur.
Les serveurs utilisant un protocole antrieur la 3.0 ne reportent pas la configuration des paramtres mais libpq inclut la logique pour obtenir des valeurs pour server_version et client_encoding. Les applications sont encourages utiliser PQparameterStatus plutt qu'un code ad-hoc modifiant ces valeurs (nanmoins, attention, les connexions pr-3.0,
changeant client_encoding via SET aprs le lancement de la connexion, ne seront pas refltes par PQparameterStatus). Pour server_version, voir aussi PQserverVersion, qui renvoie l'information dans un format numrique
qui est plus facile comparer.
Si aucune valeur n'est indique pour standard_conforming_strings, les applications pourraient supposer qu'elle
vaut off, c'est--dire que les antislashs sont traits comme des chappements dans les chanes littrales. De plus, la prsence
de ce paramtre pourrait tre pris comme une indication que la syntaxe d'chappement d'une chane (E'...') est accepte.
471

libpq - Bibliothque C

Bien que le pointeur renvoy est dclar const, il pointe en fait vers un stockage mutable associ avec la structure PGconn.
Il est dconseill de supposer que le pointeur restera valide pour toutes les requtes.
PQprotocolVersion
Interroge le protocole interface/moteur lors de son utilisation.
int PQprotocolVersion(const PGconn *conn);
Les applications souhaitent utiliser ceci pour dterminer si certaines fonctionnalits sont supportes. Actuellement, les seules
valeurs possible sont 2 (protocole 2.0), 3 (protocole 3.0) ou zro (mauvaise connexion). La version du protocole ne changera
pas aprs la fin du lancement de la connexion mais cela pourrait tre chang thoriquement avec une rinitialisation de la
connexion. Le protocole 3.0 sera normalement utilis lors de la communication avec les serveurs PostgreSQL 7.4 ou ultrieures ; les serveurs antrieurs la 7.4 supportent uniquement le protocole 2.0 (le protocole 1.0 est obsolte et non support
par libpq).
PQserverVersion
Renvoie un entier reprsentant la version du moteur.
int PQserverVersion(const PGconn *conn);
Les applications pourraient utiliser ceci pour dterminer la version du serveur de la base de donnes auquel ils sont connects.
Le numro est form en convertissant les nombres majeur, mineur et de rvision en un nombre deux chiffres dcimaux et en
leur assemblant. Par exemple, la version 8.1.5 sera renvoye en tant que 80105 et la version 8.2 sera renvoye en tant que
80200 (les zros au dbut ne sont pas affichs). Zro est renvoye si la connexion est mauvaise.
PQerrorMessage
Renvoie le dernier message d'erreur gnr par une opration sur la connexion.
char *PQerrorMessage(const PGconn* conn);
Pratiquement toutes les fonctions libpq initialiseront un message pour PQerrorMessage en cas d'chec. Notez que, par la
convention libpq, un rsultat non vide de PQerrorMessage peut tre sur plusieurs lignes et contiendra un retour chariot
la fin. L'appelant ne devrait pas librer directement le rsultat. Il sera libr quand la poigne PGconn associe est passe
PQfinish. Vous ne devriez pas supposer que la chane rsultante reste identique suite toutes les oprations sur la structure
PGconn.
PQsocket
Obtient le descripteur de fichier du socket de la connexion au serveur. Un descripteur valide sera plus grand ou gal 0 ; un
rsultat de -1 indique qu'aucune connexion au serveur n'est actuellement ouverte (ceci ne changera pas lors de l'opration normale mais pourra changer lors d'une configuration de l'initialisation ou lors d'une rinitialisation).
int PQsocket(const PGconn *conn);
PQbackendPID
Renvoie l'identifiant du processus (PID) du serveur grant cette connexion.
int PQbackendPID(const PGconn *conn);
Le PID du moteur est utile pour des raisons de dbogage et pour la comparaison avec les messages NOTIFY (qui incluent le
PID du processus serveur lanant la notification). Notez que le PID appartient un processus excut sur l'hte du serveur de
bases de donnes et non pas sur l'hte local !
PQconnectionNeedsPassword
Renvoie true (1) si la mthode d'authentification de la connexion ncessite un mot de passe, mais qu'aucun n'est disponible.
Renvoie false (0) sinon.
int PQconnectionNeedsPassword(const PGconn *conn);
Cette fonction peut tre utilise aprs une tentative choue de connexion pour dcider de la demande d'un utilisateur pour un
mot de passe.
PQconnectionUsedPassword
Renvoie true (1) si la mthode d'authentification de la connexion a utilis un mot de passe. Renvoie false (0) sinon.
int PQconnectionUsedPassword(const PGconn *conn);

472

libpq - Bibliothque C

Cette fonction peut tre utilise aprs une connexion, russie ou en chec, pour dtecter si le serveur demande un mot de
passe.
PQgetssl
Retourne la structure SSL utilise dans la connexion ou NULL si SSL n'est pas utilis.
SSL *PQgetssl(const PGconn *conn);
Cette structure peut tre utilise pour vrifier les niveaux de cryptage, pour vrifier les certificats du serveur, et plus. Rfrezvous la documentation d'OpenSSL pour plus d'informations sur cette structure.
Vous pouvez dfinir USE_SSL pour obtenir le bon prototype de cette fonction. Faire cela inclura automatiquement ssl.h
partir d'OpenSSL.

31.3. Fonctions de commandes d'excution


Une fois la connexion au serveur de la base de donnes tablie avec succs, les fonctions dcrites ici sont utilises pour excuter
les requtes SQL et les commandes.

31.3.1. Fonctions principales


PQexec
Soumet une commande au serveur et attend le rsultat.
PGresult *PQexec(PGconn *conn, const char *command);
Renvoie un pointeur PGresult ou peut-tre un pointeur NULL. Un pointeur non NULL sera gnralement renvoy sauf dans
des conditions particulires comme un manque de mmoire ou lors d'erreurs srieuses telles que l'incapacit envoyer la
commande au serveur. La fonction PQresultStatus devrait tre appele pour vrifier le code retour pour toute erreur
(incluant la valeur d'un pointeur nul, auquel cas il renverra PGRES_FATAL_ERROR). Utilisez PQerrorMessage pour obtenir plus d'informations sur l'erreur.
La chane de la commande peut inclure plusieurs commandes SQL (spares par des points virgules). Les requtes multiples envoyes dans un simple appel PQexec sont excutes dans une seule transaction sauf si des commandes explicites
BEGIN/COMMIT sont incluses dans la chane de requte pour la diviser dans de nombreuses transactions. Nanmoins, notez
que la structure PGresult renvoye dcrit seulement le rsultat de la dernire commande excute partir de la chane. Si une des
commandes doit chouer, l'excution de la chane s'arrte et le PGresult renvoy dcrit la condition d'erreur.
PQexecParams
Soumet une commande au serveur et attend le rsultat, avec la possibilit de passer des paramtres sparment du texte de la
commande SQL.
PGresult *PQexecParams(PGconn *conn,
const char *command,
int nParams,
const Oid *paramTypes,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
PQexecParams est identique PQexec mais offre des fonctionnalits supplmentaires : des valeurs de paramtres peuvent
tre spcifies sparment de la chane de commande et les rsultats de la requte peuvent tre demands soit au format texte
soit au format binaire. PQexecParams est support seulement dans les connexions avec le protocole 3.0 et ses versions ultrieures ; elle chouera lors de l'utilisation du protocole 2.0.
Voici les arguments de la fonction :
conn
L'objet connexion o envoyer la commande.
command
La chane SQL excuter. Si les paramtres sont utiliss, ils sont rfrencs dans la chane avec $1, $2, etc.
nParams
473

libpq - Bibliothque C

Le nombre de paramtres fournis ; il s'agit de la longueur des tableaux paramTypes[], paramValues[], paramLengths[] et paramFormats[]. (Les pointeurs de tableau peuvent tre NULL quand nParams vaut zro.)
paramTypes[]
Spcifie, par OID, les types de donnes affecter aux symboles de paramtres. Si paramTypes est NULL ou si tout lment
spcifique du tableau est zro, le serveur infre un type de donne pour le symbole de paramtre de la mme faon qu'il le ferait pour une chane litrale sans type.
paramValues[]
Spcifie les vraies valeurs des paramtres. Un pointeur nul dans ce tableau signifie que le paramtre correspondant est
NULL ; sinon, le pointeur pointe vers une chane texte termine par un octet nul (pour le format texte) ou vers des donnes binaires dans le format attendu par le serveur (pour le format binaire).
paramLengths[]
Spcifie les longueurs des donnes relles des paramtres du format binaire. Il est ignor pour les paramtres NULL et les paramtres de format texte. Le pointeur du tableau peut tre NULL quand il n'y a pas de paramtres binaires.
paramFormats[]
Spcifie si les paramtres sont du texte (placez un zro dans la ligne du tableau pour le paramtre correspondant) ou binaire
(placez un un dans la ligne du tableau pour le paramtre correspondant). Si le pointeur du tableau est nul, alors tous les paramtres sont prsums tre des chanes de texte.
Les valeurs passes dans le format binaire ncessitent de connatre la reprsentation interne attendue par le moteur. Par
exemple, les entiers doivent tre passs dans l'ordre rseau pour les octets. Passer des valeurs numeric requiert de connatre le
format
de
stockage
du
serveur,
comme
implment
dans
src/backend/utils/adt/numeric.c::numeric_send()
et
src/backend/utils/adt/numeric.c::numeric_recv().
resultFormat
Indiquez zro pour obtenir les rsultats dans un format texte et un pour les obtenir dans un format binaire. (Il n'est actuellement pas possible d'obtenir des formats diffrents pour des colonnes de rsultats diffrentes bien que le protocole le permette.)
Le principal avantage de PQexecParams sur PQexec est que les valeurs de paramtres pourraient tre spars partir de la
chane de commande, vitant ainsi le besoin de guillemets et d'chappements.
Contrairement PQexec, PQexecParams autorise au plus une commande SQL dans une chane donne (il peut y avoir des
points-virgules mais pas plus d'une commande non vide). C'est une limitation du protocole sous-jacent mais cela a quelque utilit
comme dfense supplmentaire contre les attaques par injection de SQL.

Astuce
Spcifier les types de paramtres via des OID est difficile, tout particulirement si vous prfrez ne pas coder en
dur les valeurs OID particulires dans vos programmes. Nanmoins, vous pouvez viter de le faire mme dans des
cas o le serveur lui-mme ne peut pas dterminer le type du paramtre ou choisit un type diffrent de celui que
vous voulez. Dans le texte de commande SQL, attachez une conversion explicite au symbole de paramtre pour
montrer le type de donnes que vous enverrez. Par exemple :
SELECT * FROM ma_table WHERE x = $1::bigint;
Ceci impose le traitement du paramtre $1 en tant que bigint alors que, par dfaut, il se serait vu affect le mme
type que x. Forcer la dcision du type de paramtre, soit de cette faon soit en spcifiant l'OID du type numrique,
est fortement recommand lors de l'envoi des valeurs des paramtres au format binaire car le format binaire a
moins de redondance que le format texte et, du coup, il y a moins de chance que le serveur dtecte une erreur de
correspondance de type pour vous.

PQprepare
Soumet une requte pour crer une instruction prpare avec les paramtres donns et attends la fin de son excution.
PGresult *PQprepare(PGconn *conn,
const char *stmtName,
const char *query,
int nParams,
const Oid *paramTypes);
PQprepare cre une instruction prpare pour une excution ultrieure avec PQexecPrepared. Cette fonction autorise
les commandes utilises de faon rpt tre analyses et planifies qu'une seule fois, plutt qu' chaque excution. PQ474

libpq - Bibliothque C

prepare est uniquement support par les connexions utilisant le protocole 3.0 et ses versions ultrieures ; elle chouera avec
le protocole 2.0.
La fonction cre une instruction prpare nomme stmtName partir de la chane query, devant contenir une seule commande SQL. stmtName pourrait tre une chane vide pour crer une instruction non nomme, auquel cas toute instruction
non nomme dj existante est automatiquement remplace par cette dernire. Une erreur sera rapporte si le nom de
l'instruction est dj dfinie dans la session en cours. Si des paramtres sont utiliss, ils sont rfrencs dans la requte avec
$1, $2, etc. nParams est le nombre de paramtres pour lesquels des types sont prdfinis dans le tableau paramTypes[]
(le pointeur du tableau pourrait tre NULL quand nParams vaut zro). paramTypes[] spcifie les types de donnes affecter aux symboles de paramtres par leur OID. Si paramTypes est NULL ou si un lment particulier du tableau vaut zro, le serveur affecte un type de donnes au symbole du paramtre de la mme faon qu'il le ferait pour une chane littrale
non type. De plus, la requte pourrait utiliser des symboles de paramtre avec des nombres plus importants que nParams ;
les types de donnes seront aussi infrs pour ces symboles. (Voir PQdescribePrepared comme un moyen de trouver les
types de donnes infrs.)
Comme avec PQexec, le rsultat est normalement un objet PGresult dont le contenu indique le succs ou l'chec ct serveur. Un rsultat NULL indique un manque de mmoire ou une incapacit envoyer la commande. Utilisez PQerrorMessage pour obtenir plus d'informations sur de telles erreurs.
Les instructions prpares avec PQexecPrepared peuvent aussi tre cres en excutant les instructions SQL PREPARE(7).
De plus, bien qu'il n'y ait aucune fonction libpq pour supprimer une instruction prpare, l'instruction SQL DEALLOCATE(7)
peut tre utilise dans ce but.
PQexecPrepared
Envoie une requte pour excuter une instruction spare avec les paramtres donns, et attend le rsultat.
PGresult *PQexecPrepared(PGconn *conn,
const char *stmtName,
int nParams,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
PQexecPrepared est identique PQexecParams mais la commande excuter est spcifie en nommant l'instruction
prpare prcdemment au lieu de donner une chane de requte. Cette fonctionnalit permet aux commandes utilises de
faon rpte d'tre analyses et planifies seulement une fois plutt que chaque fois qu'ils sont excuts. L'instruction doit
avoir t prpare prcdemment dans la session en cours. PQexecPrepared est support seulement dans les connexions
du protocole 3.0 et ses versions ultrieures ; il chouera lors de l'utilisation du protocole 2.0.
Les paramtres sont identiques PQexecParams, sauf que le nom d'une instruction prpare est donn au lieu d'une chane
de requte et le paramtre paramTypes[] n'est pas prsente (il n'est pas ncessaire car les types des paramtres de
l'instruction prpare ont t dtermins la cration).
PQdescribePrepared
Soumet une requte pour obtenir des informations sur l'instruction prpare indique et attend le retour de la requte.
PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);
PQdescribePrepared permet une application d'obtenir des informations si une instruction prpare prcdemment.
PQdescribePrepared est seulement support avec des connexions utilisant le protocole 3.0 et ultrieures ; il chouera
lors de l'utilisation du protocole 2.0.
stmtName peut tre "" ou NULL pour rfrencer l'instruction non nomme. Sinon, ce doit tre le nom d'une instruction prpare existante. En cas de succs, un PGresult est renvoy avec le code retour PGRES_COMMAND_OK. Les fonctions PQnparams et PQparamtype peuvent utiliser ce PGresult pour obtenir des informations sur les paramtres d'une instruction
prpare, et les fonctions PQnfields, PQfname, PQftype, etc fournissent des informations sur les colonnes rsultantes
(au cas o) de l'instruction.
PQdescribePortal
Soumet une requte pour obtenir des informations sur le portail indiqu et attend le retour de la requte.
PGresult *PQdescribePortal(PGconn *conn, const char *portalName);
PQdescribePortal permet une application d'obtenir des informations sur un portail prcdemment cr. (libpq ne fournit pas d'accs direct aux portails mais vous pouvez utiliser cette fonction pour inspecter les proprits d'un curseur cr avec
475

libpq - Bibliothque C

la commande SQL DECLARE CURSOR.) PQdescribePortal est seulement support dans les connexions via le protocole 3.0 et ultrieurs ; il chouera lors de l'utilisation du protocole 2.0.
portalName peut tre "" ou NULL pour rfrencer un portail sans nom. Sinon, il doit correspondre au nom d'un portail
existant. En cas de succs, un PGresult est renvoy avec le code de retour PGRES_COMMAND_OK. Les fonctions PQnfields, PQfname, PQftype, etc peuvent utiliser ce PGresult pour obtenir des informations sur les colonnes rsultats (au
cas o) du portail.
La structure PGresult encapsule le rsultat renvoy par le serveur. Les dveloppeurs d'applications libpq devraient faire attention
au maintien de l'abstraction de PGresult. Utilisez les fonctions d'accs ci-dessous pour obtenir le contenu de PGresult. vitez la rfrence aux champs de la structure PGresult car ils sont sujets des changements dans le futur.
PQresultStatus
Renvoie l'tat du rsultat d'une commande.
ExecStatusType PQresultStatus(const PGresult *res);
PQresultStatus peut renvoyer une des valeurs suivantes :
PGRES_EMPTY_QUERY
La chane envoye au serveur tait vide.
PGRES_COMMAND_OK
Fin avec succs d'une commande ne renvoyant aucune donne.
PGRES_TUPLES_OK
Fin avec succs d'une commande renvoyant des donnes (telle que SELECT ou SHOW).
PGRES_COPY_OUT
Dbut de l'envoi ( partir du serveur) d'un flux de donnes.
PGRES_COPY_IN
Dbut de la rception (sur le serveur) d'un flux de donnes.
PGRES_BAD_RESPONSE
La rponse du serveur n'a pas t comprise.
PGRES_NONFATAL_ERROR
Une erreur non fatale (une note ou un avertissement) est survenue.
PGRES_FATAL_ERROR
Une erreur fatale est survenue.
PGRES_COPY_BOTH
Lancement du transfert de donnes Copy In/Out (vers et partir du serveur). Ceci est seulement utilis par la rplication en
flux.
Si le statut du rsultat est PGRES_TUPLES_OK, alors les fonctions dcrites ci-dessous peuvent tre utilises pour rcuprer
les lignes renvoyes par la requte. Notez qu'une commande SELECT qui arrive rcuprer aucune ligne affichera toujours
PGRES_TUPLES_OK. PGRES_COMMAND_OK est pour les commandes qui ne peuvent jamais renvoyer de lignes (INSERT,
UPDATE, etc.). Une rponse PGRES_EMPTY_QUERY pourrait indiquer un bogue dans le logiciel client.
Un rsultat de statut PGRES_NONFATAL_ERROR ne sera jamais renvoy directement par PQexec ou d'autres fonctions
d'excution de requtes ; les rsultats de ce type sont passs l'excuteur de notifications (voir la Section 31.11, Traitement
des messages ).
PQresStatus
Convertit le type numr renvoy par PQresultStatus en une constante de type chane dcrivant le code d'tat.
L'appelant ne devrait pas librer le rsultat.
char *PQresStatus(ExecStatusType status);
PQresultErrorMessage
Renvoie le message d'erreur associ avec la commande ou une chane vide s'il n'y a pas eu d'erreurs.
char *PQresultErrorMessage(const PGresult *res);
S'il y a eu une erreur, la chane renvoye incluera un retour chariot en fin. L'appelant ne devrait pas librer directement le rsultat. Il sera libr quand la poigne PGresult associe est passe PQclear.
Suivant immdiatement un appel PQexec ou PQgetResult, PQerrorMessage (sur la connexion) renverra la mme
chane que PQresultErrorMessage (sur le rsultat). Nanmoins, un PGresult conservera son message d'erreur jusqu'
476

libpq - Bibliothque C

destruction alors que le message d'erreur de la connexion changera lorsque des oprations suivantes seront ralises. Utiliser
PQresultErrorMessage quand vous voulez connatre le statut associ avec un PGresult particulier ; utilisez PQerrorMessage lorsque vous souhaitez connatre le statut partir de la dernire opration sur la connexion.
PQresultErrorField
Renvoie un champ individuel d'un rapport d'erreur.
char *PQresultErrorField(const PGresult *res, int fieldcode);
fieldcode est un identifiant de champ d'erreur ; voir les symboles lists ci-dessous. NULL est renvoy si PGresult n'est
pas un rsultat d'erreur ou d'avertissement, ou n'inclut pas le champ spcifi. Les valeurs de champ n'incluront normalement
pas un retour chariot en fin. L'appelant ne devrait pas librer directement le rsultat. Il sera libr quand la poigne PGresult
associe est passe PQclear.
Les codes de champs suivants sont disponibles :
PG_DIAG_SEVERITY
La svrit ; le contenu du champ peut tre ERROR, FATAL ou PANIC dans un message d'erreur, ou WARNING, NOTICE,
DEBUG, INFO ou LOG dans un message de notification, ou une traduction localise de ceux-ci. Toujours prsent.
PG_DIAG_SQLSTATE
Le code SQLSTATE de l'erreur. Ce code identifie le type d'erreur qui est survenu ; il peut tre utilis par des interfaces qui
ralisent les oprations spcifiques (telles que la gestion des erreurs) en rponse une erreur particulire de la base de donnes. Pour une liste des codes SQLSTATE possibles, voir l'Annexe A, Codes d'erreurs de PostgreSQL. Ce champ n'est pas
localisable et est toujours prsent.
PG_DIAG_MESSAGE_PRIMARY
Le principal message d'erreur, comprhensible par un humain (typiquement sur une ligne). Toujours prsent.
PG_DIAG_MESSAGE_DETAIL
Dtail : un message d'erreur secondaire et optionnel proposant plus d'informations sur le problme. Pourrait tre compos de
plusieurs lignes.
PG_DIAG_MESSAGE_HINT
Astuce : une suggestion supplmentaire sur ce qu'il faut faire suite ce problme. Elle a pour but de diffrer du dtail car elle
offre un conseil (potentiellement inappropri) plutt que des faits tablis. Pourrait tre compos de plusieurs lignes.
PG_DIAG_STATEMENT_POSITION
Une chane contenant un entier dcimal indiquant le position du curseur d'erreur comme index dans la chane d'instruction originale. Le premier caractre se trouve l'index 1 et les positions sont mesures en caractres, et non pas en octets.
PG_DIAG_INTERNAL_POSITION
Ceci est dfini de la mme faon que le champ PG_DIAG_STATEMENT_POSITION mais c'est utilis quand la position du
curseur fait rfrence une commande gnre en interne plutt qu'une soumise par le client. Le champ
PG_DIAG_INTERNAL_QUERY apparatra toujours quand ce champ apparat.
PG_DIAG_INTERNAL_QUERY
Le texte d'une commande choue, gnre en interne. Ceci pourrait tre, par exemple, une requte SQL lance par une fonction PL/pgSQL.
PG_DIAG_CONTEXT
Une indication du contexte dans lequel l'erreur est apparue. Actuellement, cela inclut une trace de la pile d'appels des fonctions actives de langages de procdures et de requtes gnres en interne. La trace a une entre par ligne, la plus rcente se
trouvant au dbut.
PG_DIAG_SOURCE_FILE
Le nom du fichier contenant le code source o l'erreur a t rapporte.
PG_DIAG_SOURCE_LINE
Le numro de ligne dans le code source o l'erreur a t rapporte.
PG_DIAG_SOURCE_FUNCTION
Le nom de la fonction dans le code source o l'erreur a t rapporte.
Le client est responsable du formatage des informations affiches suivant ses besoins ; en particulier, il doit supprimer les
longues lignes si ncessaires. Les caractres de retour chariot apparaissant dans les champs de message d'erreur devraient tre
traits comme des changements de paragraphes, pas comme des changements de lignes.
Les erreurs gnres en interne par libpq auront une svrit et un message principal mais aucun autre champ. Les erreurs renvoyes par un serveur utilisant un protocole antrieure la 3.0 inclueront la svrit, le message principal et, quelques fois, un
message dtaill mais aucun autre champ.
477

libpq - Bibliothque C

Notez que les champs d'erreurs sont seulement disponibles pour les objets PGresult, et non pas pour les objets PGconn ; il
n'existe pas de fonction PQerrorField.
PQclear
Libre le stockage associ avec un PGresult. Chaque rsultat de commande devrait tre libr via PQclear lorsqu'il n'est
plus ncessaire.
void PQclear(PGresult *res);
Vous pouvez conserver un objet PGresult aussi longtemps que vous en avez besoin ; il ne part pas lorsque vous lancez une
nouvelle commande, mme pas si vous fermez la connexion. Pour vous en dbarrasser, vous devez appeler PQclear. En cas
d'oubli, ceci rsultera en des pertes mmoires pour votre application.

31.3.2. Rcuprer l'information provenant des rsultats des requtes


Ces fonctions sont utilises pour extraire des informations provenant d'un objet PGresult reprsentant un rsultat valide pour une
requte (statut PGRES_TUPLES_OK). Ils peuvent aussi tre utiliss pour extraire des informations partir d'une opration Describe russie : le rsultat d'un Describe a les mmes informations de colonnes qu'une excution relle de la requte aurait fournie,
mais elle ne renvoie pas de lignes. Pour les objets ayant d'autres valeurs de statut, ces fonctions agiront comme si le rsultat n'avait
aucune ligne et aucune colonne.
PQntuples
Renvoie le nombre de lignes (tuples) du rsultat de la requte. Comme elle envoie un entier, les gros ensembles de rsultat
pourraient dpasser la limite des valeurs renvoyes sur les systmes d'exploitation 32 bits.
int PQntuples(const PGresult *res);
PQnfields
Renvoie le nombre de colonnes (champs) de chaque ligne du rsultat de la requte.
int PQnfields(const PGresult *res);
PQfname
Renvoie le nom de la colonne associ avec le numro de colonne donne. Les numros de colonnes commencent zro.
L'appelant ne devrait pas librer directement le numro. Il sera libr quand la poigne PGresult associe est passe PQclear.
char *PQfname(const PGresult *res,
int column_number);
NULL est renvoy si le numro de colonne est en dehors de la plage.
PQfnumber
Renvoie le numro de colonne associ au nom de la colonne donn.
int PQfnumber(const PGresult *res,
const char *column_name);
-1 est renvoy si le nom donn ne correspond aucune colonne.
Le nom donn est trait comme un identifiant dans une commande SQL, c'est--dire qu'il est mis en minuscule sauf s'il est
entre des guillemets doubles. Par exemple, pour le rsultat de la requte suivante
SELECT 1 AS FOO, 2 AS "BAR";
nous devons obtenir les rsultats suivants :
PQfname(res, 0)
PQfname(res, 1)
PQfnumber(res, "FOO")
PQfnumber(res, "foo")
PQfnumber(res, "BAR")
PQfnumber(res, "\"BAR\"")

foo
BAR
0
0
-1
1

PQftable
Renvoie l'OID de la table partir de laquelle la colonne donne a t rcupre. Les numros de colonnes commencent zro
mais les colonnes des tables ont des numros diffrents de zro.
478

libpq - Bibliothque C

Oid PQftable(const PGresult *res,


int column_number);
InvalidOid est renvoy si le numro de colonne est en dehors de la plage ou si la colonne spcifie n'est pas une simple
rfrence une colonne de table, ou lors de l'utilisation d'un protocole antrieur la version 3.0. Vous pouvez lancer des requtes vers la table systme pg_class pour dterminer exactement quelle table est rfrence.
Le type Oid et la constante InvalidOid sera dfinie lorsque vous incluerez le fichier d'en-tte libpq. Ils auront le mme
type entier.
PQftablecol
Renvoie le numro de colonne ( l'intrieur de la table) de la colonne correspondant la colonne spcifie de rsultat de la requte. Les numros de la colonne rsultante commencent 0.
int PQftablecol(const PGresult *res,
int column_number);
Zro est renvoy si le numro de colonne est en dehors de la plage, ou si la colonne spcifie n'est pas une simple rfrence
une colonne de table, ou lors de l'utilisation d'un protocole antrieur la version 3.0.
PQfformat
Renvoie le code de format indiquant le format de la colonne donn. Les numros de colonnes commencent zro.
int PQfformat(const PGresult *res,
int column_number);
Le code de format zro indique une reprsentation textuelle des donnes alors qu'un code de format un indique une reprsentation binaire (les autres codes sont rservs pour des dfinitions futures).
PQftype
Renvoie le type de donnes associ avec le numro de colonne donn. L'entier renvoy est le numro OID interne du type.
Les numros de colonnes commencent zro.
Oid PQftype(const PGresult *res,
int column_number);
Vous pouvez lancer des requtes sur la table systme pg_type pour obtenir les noms et proprits des diffrents types de
donnes. Les OID des types de donnes intgrs sont dfinis dans le fichier src/include/catalog/pg_type.h de la
distribution des sources.
PQfmod
Renvoie le modificateur de type de la colonne associe avec le numro de colonne donn. Les numros de colonnes commencent zro.
int PQfmod(const PGresult *res,
int column_number);
L'interprtation des valeurs du modificateur est spcifique au type ; elles indiquent la prcision ou les limites de taille. La valeur -1 est utilise pour indiquer qu' aucune information n'est disponible . La plupart des types de donnes n'utilisent pas les
modificateurs, auquel cas la valeur est toujours -1.
PQfsize
Renvoie la taille en octets de la colonne associe au numro de colonne donn. Les numros de colonnes commencent zro.
int PQfsize(const PGresult *res,
int column_number);
PQfsize renvoie l'espace allou pour cette colonne dans une ligne de la base de donnes, en d'autres termes la taille de la reprsentation interne du serveur du type de donnes (de faon cohrente, ce n'est pas rellement utile pour les clients). Une valeur ngative indique que les types de donnes ont une longueur variable.
PQbinaryTuples
Renvoie 1 si PGresult contient des donnes binaires et 0 s'il contient des donnes texte.
int PQbinaryTuples(const PGresult *res);
Cette fonction est obsolte (sauf dans le cas d'une utilisation en relation avec COPY) car un seul PGresult peut contenir du
texte dans certaines colonnes et des donnes binaires dans d'autres. PQfformat est la fonction prfre. PQbinaryTuples renvoie 1 seulement si toutes les colonnes du rsultat sont dans un format binaire (format 1).
479

libpq - Bibliothque C

PQgetvalue
Renvoie la valeur d'un seul champ d'une seule ligne d'un PGresult. Les numros de lignes et de colonnes commencent zro.
L'appelant ne devrait pas librer directement le rsultat. Il sera libr quand la poigne PGresult associe est passe PQclear.
char* PQgetvalue(const PGresult *res,
int row_number,
int column_number);
Pour les donnes au format texte, la valeur renvoye par PQgetvalue est une reprsentation au format chane de caractres
termine par un octet nul de la valeur du champ. Pour les donnes au format binaire, la valeur dans la reprsentation binaire
est dtermine par le type de la donne, fonctions typsend et typreceive (la valeur est en fait suivie d'un octet zro dans
ce cas aussi mais ce n'est pas rellement utile car la valeur a des chances de contenir d'autres valeurs NULL embarques).
Une chane vide est renvoye si la valeur du champ est NULL. Voir PQgetisnull pour distinguer les valeurs NULL des
valeurs de chane vide.
Le pointeur renvoy par PQgetvalue pointe vers le stockage qui fait partie de la structure PGresult. Personne ne devrait
modifier les donnes vers lesquelles il pointe et tout le monde devrait copier explicitement les donnes dans un autre stockage
s'il n'est pas utilis aprs la dure de vie de la struture PGresult.
PQgetisnull
Teste un champ pour savoir s'il est nul. Les numros de lignes et de colonnes commencent zro.
int PQgetisnull(const PGresult *res,
int row_number,
int column_number);
Cette fonction renvoie 1 si le champ est nul et 0 s'il contient une valeur non NULL (notez que PQgetvalue renverra une
chane vide, et non pas un pointeur nul, pour un champ nul).
PQgetlength
Renvoie la longueur relle de la valeur d'un champ en octet. Les numros de lignes et de colonnes commencent zro.
int PQgetlength(const PGresult *res,
int row_number,
int column_number);
C'est la longueur relle des donnes pour la valeur particulire des donnes, c'est--dire la taille de l'objet point par PQgetvalue. Pour le format textuel, c'est identique strlen(). Pour le format binaire, c'est une information essentielle. Notez
que personne ne devrait se fier PQfsize pour obtenir la taille relle des donnes.
PQnparams
Renvoie le nombre de paramtres d'une instruction prpare.
int PQnparams(const PGresult *res);
Cette fonction est seulement utile pour inspecter le rsultat de PQdescribePrepared. Pour les autres types de requtes, il
renverra zro.
PQparamtype
Renvoie le type de donne du paramtre indiqu de l'instruction. Le numrotage des paramtres commence 0.
Oid PQparamtype(const PGresult *res, int param_number);
Cette fonction est seulement utile pour inspecyer le rsultat de PQdescribePrepared. Pour les autres types de requtes, il
renverra zro.
PQprint
Affiche toutes les lignes et, optionnellement, les noms des colonnes dans le flux de sortie spcifi.
void PQprint(FILE* fout,
/* flux de sortie */
const PGresult *res,
const PQprintOpt *po);
typedef struct
{
480

libpq - Bibliothque C

pqbool

header;

/* affiche les en-ttes des champs et le nombre de


lignes */
pqbool align;
/* aligne les champs */
pqbool standard;
/* vieux format (mort) */
pqbool html3;
/* affiche les tables en HTML */
pqbool expanded;
/* tend les tables */
pqbool pager;
/* utilise le paginateur pour la sortie si ncessaire
*/
char
*fieldSep;
/* sparateur de champ */
char
*tableOpt;
/* attributs des lments de table HTML */
char
*caption;
/* titre de la table HTML */
char
**fieldName; /* Tableau termin par un NULL des noms de remplacement
des champs */
} PQprintOpt;
Cette fonction tait auparavant utilise par psql pour afficher les rsultats des requtes mais ce n'est plus le cas. Notez qu'elle
assume que les donnes sont dans un format textuel.

31.3.3. Rcuprer d'autres informations de rsultats


Ces fonctions sont utilises pour extraire d'autres informations des objets PGresult.
PQcmdStatus
Renvoie l'tat de la commande depuis l'instruction SQL qui a gnr le PGresult. L'appelant ne devrait pas librer directement
le rsultat. Il sera libr quand la poigne PGresult associe est passe PQclear.
char * PQcmdStatus(PGresult *res);
D'habitude, c'est juste le nom de la commande mais elle pourrait inclure des donnes supplmentaires comme le nombre de
lignes traites.
PQcmdTuples
Renvoie le nombre de lignes affectes par la commande SQL.
char * PQcmdTuples(PGresult *res);
Cette fonction renvoie une chane contenant le nombre de lignes affectes par l'instruction SQL qui a gnr PGresult. Cette
fonction peut seulement tre utilise aprs l'excution d'une instruction SELECT, CREATE TABLE AS, INSERT, UPDATE, DELETE, MOVE, FETCH ou COPY, ou EXECUTE avec une instruction prpare contenant une instruction INSERT, UPDATE ou DELETE. Si la commande qui a gnr PGresult tait autre chose, PQcmdTuples renverrait directement une chane vide. L'appelant ne devrait pas librer la valeur de retour directement. Elle sera libre quand la poigne
PGresult associe est passe PQclear.
PQoidValue
Renvoie l'OID de la ligne insre, si la commande SQL tait une instruction INSERT qui a insr exactement une ligne dans
une table comprenant des OID ou un EXECUTE d'une requte prpare contenant une instruction INSERT convenable. Sinon, cette fonction renvoie InvalidOid. Cette fonction renverra aussi InvalidOid si la table touche par l'instruction
INSERT ne contient pas d'OID.
Oid PQoidValue(const PGresult *res);
PQoidStatus
Cette fonction est obsolte. Utilisez plutt PQoidValue. De plus, elle n'est pas compatible avec les threads. Elle renvoie une
chane contenant l'OID de la ligne insre alors que PQoidValue renvoie la valeur de l'OID.
char * PQoidStatus(const PGresult *res);

31.3.4. Chane d'chappement inclure dans les commandes SQL


PQescapeLiteral
char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);

481

libpq - Bibliothque C

PQescapeLiteral chappe une chane pour l'utiliser dans une commande SQL. C'est utile pour insrer des donnes
comme des constantes dans des commandes SQL. Certains caractres, comme les guillemets et les antislashs, doivent tre
traits avec des caractres d'chappement pour viter qu'ils soient traits d'aprs leur signification spciale par l'analyseur
SQL. PQescapeLiteral ralise cette opration.
PQescapeLiteral renvoie une version chappe du paramtre str dans une mmoire alloue avec malloc(). Cette
mmoire devra tre libre en utilisant PQfreemem() quand le rsultat ne sera plus utile. Un octet zro de fin n'est pas requis et ne doit pas tre compt dans length. (Si un octet zro de fin est dcouvert avant la fin du traitement des length octets, PQescapeLiteral s'arrte au zro ; ce comportement est identique celui de strncpy.) Les caractres spciaux de
la chane en retour ont t remplacs pour qu'ils puissent tre traits correctement par l'analyseur de chanes de
PostgreSQL. Un octet zro final est aussi ajout. Les guillemets simples qui doivent entourer les chanes litrales avec PostgreSQL sont inclus dans la chane rsultante.
En cas d'erreur, PQescapeLiteral renvoit NULL et un message convenable est stock dans l'objet conn.

Astuce
Il est particulirement important de faire un chappement propre lors de l'utilisation de chanes provenant d'une
source qui n'est pas forcment de confiance. Sinon, il existe un risque de scurit : vous vous exposez une attaque de type injection SQL avec des commandes SQL non voulues injectes dans votre base de donnes.
Notez qu'il n'est pas ncessaire ni correct de faire un chappement quand une valeur est pass en tant que paramtre spar
dans PQexecParams ou ce type de routine.
PQescapeIdentifier
char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length);
PQescapeIdentifier chappe une chane pour qu'elle puisse tre utilis en tant qu'identifiant SQL, par exemple pour le
nom d'une table, d'une colonne ou d'une fonction. C'est utile quand un identifiant fourni par un utilisateur pourrait contenir
des caractres spciaux qui pourraient autrement ne pas tre interprts comme faisant parti de l'identifiant par l'analyseur
SQL ou lorsque l'identifiant pourrait contenir des caractres en majuscule, auquel cas le casse doit tre prserve.
PQescapeIdentifier renvoit une version du paramtre str chappe comme doit l'tre un identifiant SQL, dans une
mmoire alloue avec malloc(). Cette mmoire doit tre libre en utilisant PQfreemem() quand le rsultat n'est plus
ncessaire. Un octet zro de fin n'est pas ncessaire et ne doit pas tre comptabilis dans length. (Si un octet zro de fin est
trouv avant le traitement des length octets, PQescapeIdentifier s'arrte au zro ; ce comportement est identique
celui de strncpy.) Les caractres spciaux de la chane en retour ont t remplacs pour que ce dernier soit trait proprement comme un identifiant SQL. Un octet zro de fin est aussi ajout. La chane de retour sera aussi entoure de guillemets
doubles.
En cas d'erreur, PQescapeIdentifier renvoit NULL et un message d'erreur convenable est stocke dans l'objet conn.

Astuce
Comme avec les chanes litrales, pour empcher les attaques d'injection SQL, les identifiants SQL doivent
tre chapps lorsqu'elles proviennent de source non sre.
PQescapeStringConn
size_t PQescapeStringConn (PGconn *conn,
char *to, const char *from, size_t length,
int *error);
PQescapeStringConn chappe les chanes litrales de la mme faon que PQescapeLiteral. Contrairement
PQescapeLiteral, l'appelant doit fournir un tampon d'une taille approprie. De plus, PQescapeStringConn n'ajoute
pas de guillemets simples autour des chanes litrales de PostgreSQL ; elles doivent tre ajoutes dans la commande SQL
o ce rsultat sera insr. Le paramtre from pointe vers le premier caractre d'une chane chapper, et le paramtre
length prcise le nombre d'octets contenus dans cette chane. Un octet zro de fin n'est pas ncessaire et ne doit pas tre
comptabilis dans length. (Si un octet zro de fin est trouv avant le traitement des length octets, PQescapeStringConn s'arrte au zro ; ce comportement est identique celui de strncpy.) to doit pointer vers un tampon qui peut contenir
au moins un octet de plus que deux fois la valeur de length, sinon le comportement de la fonction n'est pas connue. Le
482

libpq - Bibliothque C

comportement est aussi non dfini si les chanes to et from se surchargent.


Si le paramtre error est diffrent de NULL, alors *error est configur zro en cas de succs et est diffrent de zro en
cas d'erreur. Actuellement, les seuls conditions permettant une erreur impliquent des encodages multi-octets dans la chane
source. La chane en sortie est toujours gnre en cas d'erreur mais il est possible que le serveur la rejettera comme une
chane malforme. En cas d'erreur, un message convenable est stock dans l'objet conn, que error soit NULL ou non.
PQescapeStringConn renvoit le nombre d'octets crits dans to, sans inclure l'octet zro de fin.
PQescapeString
PQescapeString est une ancienne version de PQescapeStringConn.
size_t PQescapeString (char *to, const char *from, size_t length);
La seule diffrence avec PQescapeStringConn tient dans le fait que PQescapeString n'a pas de paramtres conn et
error. cause de cela, elle ne peut ajuster son comportement avec les proprits de la connexion (comme l'encodage des
caractres) et du coup, elle pourrait founir de mauvais rsultats. De plus, elle ne peut pas renvoyer de conditions d'erreur.
PQescapeString peut tre utilis proprement avec des programmes utilisant une seule connexion PostgreSQL la fois
(dans ce cas, il peut trouver ce qui l'intresse en arrire-plan ). Dans d'autres contextes, c'est un risque en terme de scurit.
Cette fonction devrait tre vite et remplace autant que possible par la fonction PQescapeStringConn.
PQescapeByteaConn
chappe des donnes binaires utiliser l'intrieur d'une commande SQL avec le type bytea. Comme avec PQescapeStringConn, c'est seulement utilis pour insrer des donnes directement dans une chane de commande SQL.
unsigned char *PQescapeByteaConn(PGconn *conn,
const unsigned char *from,
size_t from_length,
size_t *to_length);
Certaines valeurs d'octets doivent tre chappes lorsqu'elles font partie d'un littral bytea dans une instruction SQL. PQescapeByteaConn chappe les octets en utilisant soit un codage hexadcimal soit un chappement avec des antislashs. Voir
Section 8.4, Types de donnes binaires pour plus d'informations.
Le paramtre from pointe sur le premier octet de la chane chapper et le paramtre from_length donne le nombre
d'octets de cette chane binaire (un octet zro de terminaison n'est ni ncessaire ni compt). Le paramtre to_length pointe
vers une variable qui contiendra la longueur de la chane chappe rsultante. Cette longueur inclut l'octet zro de terminaison.
PQescapeByteaConn renvoie une version chappe du paramtre from dans la mmoire alloue avec malloc(). Cette
mmoire doit tre libre avec PQfreemem lorsque le rsultat n'est plus ncessaire. Tous les caractres spciaux de la chane
de retour sont remplacs de faon ce qu'ils puissent tre traits proprement par l'analyseur de chanes littrales de PostgreSQL et par l'entre bytea de la fonction. Un octet zro de terminaison est aussi ajout. Les guillemets simples qui englobent
les chanes littrales de PostgreSQL ne font pas partie de la chane rsultante.
En cas d'erreur, un pointeur NULL est renvoy et un message d'erreur adquat est stock dans l'objet conn. Actuellement, la
seule erreur possible est une mmoire insuffisante pour stocker la chane rsultante.
PQescapeBytea
PQescapeBytea est une version obsolte de PQescapeByteaConn.
unsigned char *PQescapeBytea(const unsigned char *from,
size_t from_length,
size_t *to_length);
La seule diffrence avec PQescapeByteaConn est que PQescapeBytea ne prend pas de paramtre PGconn. De ce fait,
PQescapeBytea peut seulement tre utilis correctement dans des programmes qui n'utilisent qu'une seule connexion PostgreSQL la fois (dans ce cas, il peut trouver ce dont il a besoin en arrire-plan ). Il pourrait donner de mauvais rsultats
s'il tait utilis dans des programmes qui utilisent plusieurs connexions de bases de donnes (dans ce cas, utilisez plutt
PQescapeByteaConn).
PQunescapeBytea
Convertit une reprsentation de la chane en donns binaires -- l'inverse de PQescapeBytea. Ceci est ncessaire lors de la
rcupration de donnes bytea en format texte, mais pas lors de sa rcupration au format binaire.
unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
483

libpq - Bibliothque C

Le paramtre from pointe vers une chane de telle faon qu'elle pourrait provenir de PQgetvalue lorsque la colonne est de
type bytea. PQunescapeBytea convertit cette reprsentation de la chane en sa reprsentation binaire. Elle renvoie un
pointeur vers le tampon allou avec malloc(), ou NULL en cas d'erreur, et place la taille du tampon dans to_length. Le
rsultat doit tre libr en utilisant PQfreemem lorsque celui-ci n'est plus ncessaire.
Cette conversion n'est pas l'inverse exacte de PQescapeBytea car la chane n'est pas chappe avec PQgetvalue. Cela
signifie en particulier qu'il n'y a pas besoin de rflchir la mise entre guillemets de la chane, et donc pas besoin d'un paramtre PGconn.

31.4. Traitement des commandes asynchrones


La fonction PQexec est adquate pour soumettre des commandes aux applications standards, synchrones. Nanmoins, il a
quelques dficiences pouvant tre d'importance certains utilisateurs :

PQexec attend que la commande se termine. L'application pourrait avoir d'autres travaux raliser (comme le rafraichissement de l'interface utilisateur), auquel cas il ne voudra pas tre bloqu en attente de la rponse.

Comme l'excution de l'application cliente est suspendue en attendant le rsultat, il est difficile pour l'application de dcider
qu'elle voudrait annuler la commande en cours (c'est possible avec un gestionnaire de signaux mais pas autrement).

PQexec ne peut renvoyer qu'une structure PGresult. Si la chane de commande soumise contient plusieurs commandes SQL,
toutes les structures PGresult sont annules par PQexec, sauf la dernire.

Les applications qui n'apprcient pas ces limitations peuvent utiliser la place les fonctions sous-jacentes partir desquelles
PQexec est construit : PQsendQuery et PQgetResult. Il existe aussi PQsendQueryParams, PQsendPrepare, PQsendQueryPrepared, PQsendDescribePrepared et PQsendDescribePortal, pouvant tre utilises avec PQgetResult pour dupliquer les fonctionnalits de respectivement PQexecParams, PQprepare, PQexecPrepared, PQdescribePrepared et PQdescribePortal.
PQsendQuery
Soumet une commande au serveur sans attendre le(s) rsultat(s). 1 est renvoy si la commande a t correctement envoye et
0 dans le cas contraire (auquel cas, utilisez la fonction PQerrorMessage pour obtenir plus d'informations sur l'chec).
int PQsendQuery(PGconn *conn, const char *command);
Aprs un appel russi PQsendQuery, appelez PQgetResult une ou plusieurs fois pour obtenir les rsultats. PQsendQuery ne peut pas tre appel de nouveau (sur la mme connexion) tant que PQgetResult ne renvoie pas de pointeur nul,
indiquant que la commande a termin.
PQsendQueryParams
Soumet une commande et des paramtres spars au serveur sans attendre le(s) rsultat(s).
int PQsendQueryParams(PGconn *conn,
const char *command,
int nParams,
const Oid *paramTypes,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
Ceci est quivalent PQsendQuery sauf que les paramtres de requtes peuvent tre spcifis partir de la chane de requte. Les paramtres de la fonction sont grs de faon identique PQexecParams. Comme PQexecParams, cela ne
fonctionnera pas pour les connexions utilisant le protocole 2.0 et cela ne permettra qu'une seule commande dans la chane de
requte.
PQsendPrepare
Envoie une requte pour crer une instruction prpare avec les paramtres donns et redonne la main sans attendre la fin de
son excution.
int PQsendPrepare(PGconn *conn,
const char *stmtName,
const char *query,
int nParams,
const Oid *paramTypes);

484

libpq - Bibliothque C

Ceci est la version asynchrone de PQprepare : elle renvoie 1 si elle a t capable d'envoyer la requte, 0 sinon. Aprs un
appel termin avec succs, appelez PQgetResult pour dterminer si le serveur a cr avec succs l'instruction prpare.
Les paramtres de la fonction sont grs de faon identique PQprepare. Comme PQprepare, cela ne fonctionnera pas
sur les connexions utilisant le protocole 2.0.
PQsendQueryPrepared
Envoie une requte pour excuter une instruction prpare avec des paramtres donns sans attendre le(s) rsultat(s).
int PQsendQueryPrepared(PGconn *conn,
const char *stmtName,
int nParams,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
Ceci est similaire PQsendQueryParams mais la commande excuter est spcifie en nommant une instruction prcdemment prpare au lieu de donner une chane contenant la requte. Les paramtres de la fonction sont grs de faon identique PQexecPrepared. Comme PQexecPrepared, cela ne fonctionnera pas pour les connexions utilisant le protocole
2.0.
PQsendDescribePrepared
Soumet une requte pour obtenir des informations sur l'instruction prpare indique sans attendre sa fin.
int PQsendDescribePrepared(PGconn *conn, const char *stmtName);
Ceci est la version asynchrone de PQdescribePrepared : elle renvoie 1 si elle a t capable d'envoyer la requte, 0 dans
le cas contraire. Aprs un appel russi, appelez PQgetResult pour obtenir les rsultats. Les paramtres de la fonction sont
grs de faon identique PQdescribePrepared. Comme PQdescribePrepared, cela ne fontionnera pas avec les
connexions utilisant le protocole 2.0.
PQsendDescribePortal
Soumet une requte pour obtenir des informations sur le portail indiqu sans attendre la fin de la commande.
int PQsendDescribePortal(PGconn *conn, const char *portalName);
Ceci est la version asynchrone de PQdescribePortal : elle renvoie 1 si elle a t capable d'envoyer la requte, 0 dans le
cas contraire. Aprs un appel russi, appelez PQgetResult pour obtenir les rsultats. Les paramtres de la fonction sont grs de faon identique PQdescribePortal. Comme PQdescribePortal, cela ne fontionnera pas avec les
connexions utilisant le protocole 2.0.
PQgetResult
Attend le prochain rsultat d'un appel prcdant PQsendQuery, PQsendQueryParams, PQsendPrepare ou PQsendQueryPrepared, et le renvoie. Un pointeur nul est renvoy quand la commande est termine et qu'il n'y aura plus de
rsultats.
PGresult *PQgetResult(PGconn *conn);
PQgetResult doit tre appel de faon rpt jusqu' ce qu'il retourne un pointeur nul indiquant que la commande s'est termine (si appel un moment o aucune commande n'est active, PQgetResult renverra seulement un pointeur nul la
fois). Chaque rsultat non nul provenant de PQgetResult devrait tre trait en utilisant les mmes fonctions d'accs
PGresult que celles prcdemment dcrites. N'oubliez pas de librer chaque objet rsultat avec PQclear une fois que vous
en avez termin. Notez que PQgetResult bloquera seulement si la commande est active et que les donnes ncessaires en
rponse n'ont pas encore t lues par PQconsumeInput.

Note
Mme quand PQresultStatus indique une erreur fatale, PQgetResult doit tre appel jusqu' ce qu'il
renvoie un pointeur nul pour permettre libpq de traiter l'information sur l'erreur correctement.
Utiliser PQsendQuery et PQgetResult rsout un des problmes de PQexec : si une chane de commande contient plusieurs
commandes SQL, les rsultats de ces commandes peuvent tre obtenus individuellement (ceci permet une simple forme de traitement en parallle : le client peut grer les rsultats d'une commande alors que le serveur travaille sur d'autres requtes de la mme
chane de commandes). Nanmoins, appeler PQgetResult causera toujours un blocage du client jusqu' la fin de la prochaine
commande SQL. Ceci est vitable en utilisant proprement deux fonctions supplmentaires :

485

libpq - Bibliothque C

PQconsumeInput
Si l'entre est disponible partir du serveur, consommez-la.
int PQconsumeInput(PGconn *conn);
PQconsumeInput renvoie normalement 1 indiquant aucune erreur , mais renvoie zro s'il y a eu une erreur (auquel cas
PQerrorMessage peut tre consult). Notez que le rsultat ne dit pas si des donnes ont t rcupres en entre. Aprs
avoir appel PQconsumeInput, l'application devrait vrifier PQisBusy et/ou PQnotifies pour voir si leur tat a chang.
PQconsumeInput pourrait tre appel mme si l'application n'est pas encore prpar grer un rsultat ou une notification.
La fonction lira les donnes disponibles et les sauvegardera dans un tampon indiquant ainsi qu'une lecture d'un select()
est possible. L'application peut donc utiliser PQconsumeInput pour effacer la condition select() immdiatement, puis
pour examiner les rsultats autant que possible.
PQisBusy
Renvoie 1 si une commande est occupe, c'est--dire que PQgetResult bloquerait en attendant une entre. Un zro indiquerait que PQgetResult peut tre appel avec l'assurance de ne pas tre bloqu.
int PQisBusy(PGconn *conn);
PQisBusy ne tentera pas lui-mme de lire les donnes partir du serveur ; du coup, PQconsumeInput doit tre appel
d'abord ou l'tat occup ne s'arrtera jamais.
Une application typique de l'utilisation de ces fonctions aura une boucle principale utilisant select() ou poll() pour attendre
toutes les conditions auxquelles il doit rpondre. Une des conditions sera la disponibilit des donnes partir du serveur, ce qui signifie des donnes lisibles pour select() sur le descripteur de fichier identifi par PQsocket. Lorsque la boucle principale
dtecte la disponibilit de donnes, il devrait appeler PQconsumeInput pour lire l'en-tte. Il peut ensuite appeler PQisBusy
suivi par PQgetResult si PQisBusy renvoie false (0). Il peut aussi appeler PQnotifies pour dtecter les messages NOTIFY (voir la Section 31.7, Notification asynchrone ).
Un client qui utilise PQsendQuery/PQgetResult peut aussi tenter d'annuler une commande en cours de traitement par le serveur ; voir la Section 31.5, Annuler des requtes en cours d'excution . Mais quelque soit la valeur renvoye par PQcancel,
l'application doit continuer avec la squence normale de lecture du rsultat en utilisant PQgetResult. Une annulation russie
causera simplement une fin plus rapide de la commande.
En utilisant les fonctions dcrites ci-dessus, il est possible d'viter le blocage pendant l'attente de donnes du serveur. Nanmoins,
il est toujours possible que l'application se bloque en attendant l'envoi vers le serveur. C'est relativement peu frquent mais cela
peut arriver si de trs longues commandes SQL ou donnes sont envoyes (c'est bien plus probable si l'application envoie des donnes via COPY IN). Pour empcher cette possibilit et russir des oprations de bases de donnes totalement non bloquantes, les
fonctions supplmentaires suivantes pourraient tre utilises.
PQsetnonblocking
Initialise le statut non bloquant de la connexion.
int PQsetnonblocking(PGconn *conn, int arg);
Initialise l'tat de la connexion non bloquant si arg vaut 1 et bloquant si arg vaut 0. Renvoie 0 si OK, -1 en cas d'erreur.
Dans l'tat non bloquant, les appels PQsendQuery, PQputline, PQputnbytes et PQendcopy ne bloqueront pas
mais renverront la place une erreur s'ils ont besoin d'tre de nouveau appels.
Notez que PQexec n'honore pas le mode non bloquant ; s'il est appel, il agira d'une faon bloquante malgr tout.
PQisnonblocking
Renvoie le statut bloquant de la connexion la base de donnes.
int PQisnonblocking(const PGconn *conn);
Renvoie 1 si la connexion est en mode non bloquant, 1 dans le cas contraire.
PQflush
Tente de vider les donnes des queues de sortie du serveur. Renvoie 0 en cas de succs (ou si la queue d'envoi est vide), -1 en
cas d'chec quelque soit la raison ou 1 s'il a t incapable d'envoyer encore toutes les donnes dans la queue d'envoi (ce cas
arrive seulement si la connexion est non bloquante).
int PQflush(PGconn *conn);
486

libpq - Bibliothque C

Aprs avoir envoy une commande ou des donnes dans une connexion non bloquante, appelez PQflush. S'il renvoie 1, attendez
que la socket soit disponible en criture et appelez-la de nouveau ; rptez cela jusqu' ce qu'il renvoie 0. Une fois que PQflush
renvoie 0, attendez que la socket soit disponible en lecture puis lisez la rponse comme dcrit ci-dessus.

31.5. Annuler des requtes en cours d'excution


Une application client peut demander l'annulation d'une commande qui est toujours en cours d'excution par le serveur en utilisant
les fonctions dcrites dans cette section.
PQgetCancel
Cre une structure de donnes contenant les informations ncessaires l'annulation d'une commande lance sur une
connexion particulire la base de donnes.
PGcancel *PQgetCancel(PGconn *conn);
PQgetCancel cre un objet fonction PGcancel avec un objet connexion PGconn. Il renverra NULL si le paramtre conn
donn est NULL ou est une connexion invalide. L'objet PGcancel est une structure opaque qui n'a pas pour but d'tre accd
directement par l'application ; elle peut seulement tre passe PQcancel ou PQfreeCancel.
PQfreeCancel
Libre une structure de donnes cre par PQgetCancel.
void PQfreeCancel(PGcancel *cancel);
PQfreeCancel libre un objet donn par PQgetCancel.
PQcancel
Demande que le serveur abandonne l'excution de la commande en cours.
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize);
La valeur renvoye est 1 si la demande d'annulation a t correctement envoye et 0 sinon. Si non, errbuf contient un message d'erreur expliquant pourquoi. errbuf doit tre un tableau de caractres d'une taille de errbufsize octets (la taille recommande est de 256 octets).
Un envoi russi ne garantit pas que la demande aura un quelconque effet. Si l'annulation est relle, la commande en cours terminera plus tt et renverra une erreur. Si l'annulation choue (disons, parce que le serveur a dj excut la commande), alors
il n'y aura aucun rsultat visible.
PQcancel peut tre invoqu de faon sr par le gestionnaire de signaux si errbuf est une variable locale dans le gestionnaire de signaux. L'objet PGcancel est en lecture seule pour ce qui concerne PQcancel, pour qu'il puisse aussi tre appel
partir d'un thread spar de celui manipulant l'objet PGconn.
PQrequestCancel
PQrequestCancel est une variante obsolte de PQcancel.
int PQrequestCancel(PGconn *conn);
Demande au serveur l'abandon du traitement de la commande en cours d'excution. Elle opre directement sur l'objet PGconn
et, en cas d'chec, stocke le message d'erreur dans l'objet PGconn (d'o il peut tre rcupr avec PQerrorMessage). Bien
qu'il s'agisse de la mme fonctionnalit, cette approche est hasardeuse en cas de programmes compatibles avec les threads
ainsi que pour les gestionnaires de signaux car il est possible que la surcharge du message d'erreur de PGconn gnera
l'opration en cours sur la connexion.

31.6. Interface chemin rapide


PostgreSQL fournit une interface rapide pour envoyer des appels de fonctions simples au serveur.

Astuce
Cette interface est quelque peu obsolte car vous pourriez raliser les mmes choses avec des performances similaires et plus de fonctionnalits en initialisant une instruction prpare pour dfinir l'appel de fonction. Puis, excuter l'instruction avec une transmission binaire des paramtres et des substitutions de rsultats pour un appel de fonction chemin rapide.
487

libpq - Bibliothque C

La fonction PQfn demande l'excution d'une fonction du serveur via l'interface de chemin rapide :
PGresult* PQfn(PGconn* conn,
int fnid,
int *result_buf,
int *result_len,
int result_is_int,
const PQArgBlock *args,
int nargs);
typedef struct
{
int len;
int isint;
union
{
int *ptr;
int integer;
} u;
} PQArgBlock;
L'argument fnid est l'OID de la fonction excuter. args et nargs dfinissent les paramtres passer la fonction ; ils
doivent correspondre la liste d'arguments dclars de la fonction. Quand le champ isint d'une structure est vrai, la valeur de
u.integer est envoye au serveur en tant qu'entier de la longueur indique (qui doit tre 1, 2 ou 4 octets) ; les bons changes
d'octets se passent. Quand isint est faux, le nombre d'octets indiqu sur *u.ptr est envoy au traitement ; les donnes doivent
tre dans le format attendu par le serveur pour la transmission binaire du type de donnes de l'argument de la fonction. result_buf est le tampon dans lequel placer le code de retour. L'appelant doit avoir allou suffisamment d'espace pour stocker le
code de retour (il n'y a pas de vrification !). La longueur actuelle du rsultat sera renvoy dans l'entier point par result_len.
Si un rsultat sur un entier de 1, 2 ou 4 octets est attendu, initialisez result_is_int 1, sinon initialisez-le 0. Initialiser result_is_int 1 fait que libpq change les octets de la valeur si ncessaire, de faon ce que la bonne valeur int soit dlivre
pour la machine cliente. Quand result_is_int vaut 0, la chane d'octets au format binaire envoye par le serveur est renvoye
non modifie.
PQfn renvoie toujours un pointeur PGresult valide. L'tat du rsultat devrait tre vrifi avant que le rsultat ne soit utilis. Le demandeur est responsable de la libration de la structure PGresult avec PQclear lorsque celle-ci n'est plus ncessaire.
Notez qu'il n'est pas possible de grer les arguments nuls, les rsultats nuls et les rsultats d'ensembles nuls en utilisant cette interface.

31.7. Notification asynchrone


PostgreSQL propose des notifications asynchrone via les commandes LISTEN et NOTIFY. Une session cliente enregistre son
intrt dans un canal particulier avec la commande LISTEN (et peut arrter son coute avec la commande UNLISTEN). Toutes
les sessions coutant un canal particulier seront notifies de faon asynchrone lorsqu'une commande NOTIFY avec ce nom de canal sera excute par une session. Une chane de charge peut tre renseign pour fournir des donnes supplmentaires aux processus en coute.
Les applications libpq soumettent les commandes LISTEN, UNLISTEN et NOTIFY comme des commandes SQL ordinaires.
L'arrive des messages NOTIFY peut tre dtecte ensuite en appelant PQnotifies.
La fonction PQnotifies renvoie la prochaine notification partir d'une liste de messages de notification non grs reus partir du serveur. Il renvoie un pointeur nul s'il n'existe pas de notifications en attente. Une fois qu'une notification est renvoye partir de PQnotifies, elle est considre comme tant gre et sera supprime de la liste des notifications.
PGnotify* PQnotifies(PGconn *conn);
typedef struct pgNotify
{
char *relname;
int be_pid;
char *extra;
} PGnotify;

/* nom du canal de la notification */


/* ID du processus serveur notifiant */
/* chane de charge pour la notification */

Aprs avoir trait un objet PGnotify renvoy par PQnotifies, assurez-vous de librer le pointeur PQfreemem. Il est suffisant
de librer le pointeur PGnotify ; les champs relname et extra ne reprsentent pas des allocations spares (le nom de ces
champs est historique ; en particulier, les noms des canaux n'ont pas besoin d'tre lis aux noms des relations.)
Exemple 31.2, Deuxime exemple de programme pour libpq donne un programme d'exemple illustrant l'utilisation d'une noti488

libpq - Bibliothque C

fication asynchrone.
PQnotifies ne lit pas rellement les donnes partir du serveur ; il renvoie simplement les messages prcdemment absorbs
par une autre fonction de libpq. Dans les prcdentes versions de libpq, la seule faon de s'assurer une rception temps des messages NOTIFY consistait soumettre constamment des commandes de soumission, mme vides, puis de vrifier PQnotifies
aprs chaque PQexec. Bien que ceci fonctionnait, cela a t abandonn cause de la perte de puissance.
Une meilleure faon de vrifier les messages NOTIFY lorsque vous n'avez pas de commandes utiles excuter est d'appeler PQconsumeInput puis de vrifier PQnotifies. Vous pouvez utiliser select() pour attendre l'arrive des donnes partir du
serveur, donc en utilisant aucune puissance du CPU sauf lorsqu'il y a quelque chose faire (voir PQsocket pour obtenir le numro du descripteur de fichiers utiliser avec select()). Notez que ceci fonctionnera bien que vous soumettez les commandes
avec PQsendQuery/PQgetResult ou que vous utilisez simplement PQexec. Nanmoins, vous devriez vous rappeler de vrifier PQnotifies aprs chaque PQgetResult ou PQexec pour savoir si des notifications sont arrives lors du traitement de la
commande.

31.8. Fonctions associes avec la commande COPY


Dans PostgreSQL, la commande COPY a des options pour lire ou crire partir de la connexion rseau utilise par libpq. Les
fonctions dcrites dans cette section autorisent les applications prendre avantage de cette capacit en apportant ou en consommant les donnes copies.
Le traitement complet est le suivant. L'application lance tout d'abord la commande SQL COPY via PQexec ou une des fonctions
quivalents. La rponse ceci (s'il n'y a pas d'erreur dans la commande) sera un objet PGresult avec un code de retour
PGRES_COPY_OUT ou PGRES_COPY_IN (suivant la direction spcifie pour la copie). L'application devrait alors utiliser les
fonctions de cette section pour recevoir ou transmettre des lignes de donnes. Quand le transfert de donnes est termin, un autre
objet PGresult est renvoy pour indiquer le succs ou l'chec du transfert. Son statut sera PGRES_COMMAND_OK en cas de succs
et PGRES_FATAL_ERROR si un problme a t rencontr. ce point, toute autre commande SQL pourrait tre excute via
PQexec (il n'est pas possible d'excuter d'autres commandes SQL en utilisant la mme connexion tant que l'opration COPY est
en cours).
Si une commande COPY est lance via PQexec dans une chane qui pourrait contenir d'autres commandes supplmentaires,
l'application doit continuer rcuprer les rsultats via PQgetResult aprs avoir termin la squence COPY. C'est seulement
quand PQgetResult renvoie NULL que vous pouvez tre certain que la chane de commandes PQexec est termine et qu'il est
possible de lancer d'autres commandes.
Les fonctions de cette section devraient seulement tre excutes pour obtenir un statut de rsultat PGRES_COPY_OUT ou
PGRES_COPY_IN partir de PQexec ou PQgetResult.
Un objet PGresult grant un de ces statuts comporte quelques donnes supplmentaires sur l'opration COPY qui commence. La
donnes supplmentaire est disponible en utilisant les fonctions qui sont aussi utilises en relation avec les rsultats de requtes :
PQnfields
Renvoie le nombre de colonnes (champs) copier.
PQbinaryTuples
0 indique que le format de copie complet est textuel (lignes spares par des retours chariots, colonnes spares par des caractres de sparation, etc). 1 indique que le format de copie complet est binaire. Voir COPY(7) pour plus d'informations.
PQfformat
Renvoie le code de format (0 pour le texte, 1 pour le binaire) associ avec chaque colonne de l'opration de copie. Les codes
de format par colonne seront toujours zro si le format de copie complet est textuel mais le format binaire supporte la fois
des colonnes textuelles et des colonnes binaires (nanmoins, avec l'implmentation actuelle de COPY, seules les colonnes binaires apparaissent dans une copie binaire donc les formats par colonnes correspondent toujours au format complet actuellement).

Note
Ces valeurs de donnes supplmentaires sont seulement disponibles en utilisant le protocole 3.0. Lors de
l'utilisation du protocole 2.0, toutes ces fonctions renvoient 0.

31.8.1. Fonctions d'envoi de donnes pour COPY


Ces fonctions sont utilises pour envoyer des donnes lors d'un COPY FROM STDIN. Elles choueront si elles sont appeles
alors que la connexion ne se trouve pas dans l'tat COPY_IN.

489

libpq - Bibliothque C

PQputCopyData
Envoie des donnes au serveur pendant un tat COPY_IN.
int PQputCopyData(PGconn *conn,
const char *buffer,
int nbytes);
Transmet les donnes de COPY dans le tampon spcifi (buffer), sur nbytes octets, au serveur. Le rsultat vaut 1 si les
donnes ont t envoyes, zro si elles n'ont pas t envoyes car la tentative pourrait bloquer (ce cas n'est possible que lors
d'une connexion en mode non bloquant) ou -1 si une erreur s'est produite (utilisez PQerrorMessage pour rcuprer des dtails si la valeur de retour vaut -1. Si la valeur vaut zro, attendez qu'il soit prt en criture et r-essayez).
L'application pourrait diviser le flux de donnes de COPY dans des chargements de tampon de taille convenable. Les limites
n'ont pas de signification smantique lors de l'envoi. Le contenu du flux de donnes doit correspondre au format de donnes
attendu par la commande COPY ; voir COPY(7) pour des dtails.
PQputCopyEnd
Envoie une indication de fin de transfert au serveur lors de l'tat COPY_IN.
int PQputCopyEnd(PGconn *conn,
const char *errormsg);
Termine l'opration COPY_IN avec succs si errormsg est NULL. Si errormsg n'est pas NULL alors COPY choue, la
chane pointe par errormsg tant utilise comme message d'erreur (nanmoins, vous ne devriez pas supposer que ce message d'erreur prcis reviendra du serveur car le serveur pourrait avoir dj choue sur la commande COPY pour des raisons
qui lui sont propres). Notez aussi que l'option forant l'chec ne fonctionnera pas lors de l'utilisation de connexions avec un
protocole pre-3.0.
Le rsultat est 1 si la donne de fin a t envoye, zro si elle ne l'a pas t car cette tentative serait bloquante (ce cas est uniquement possible si la connexion est dans un mode non bloquant) ou -1 si une erreur est survenue (utilisez PQerrorMessage pour rcuprer les dtails si le code de retour est -1. Si la valeur vaut zro, attendez que le serveur soit prt en criture
et r-essayez de nouveau).
Aprs un appel russi PQputCopyEnd, appelez PQgetResult pour obtenir le statut de rsultat final de la commande
COPY. Vous pouvez attendre que le rsultat soit disponible de la mme faon. Puis, retournez aux oprations normales.

31.8.2. Fonctions de rception des donnes de COPY


Ces fonctions sont utilises pour recevoir des donnes lors d'un COPY TO STDOUT. Elles choueront si elles sont appeles alors
que la connexion n'est pas dans l'tat COPY_OUT
PQgetCopyData
Reoit des donnes partir du serveur lors d'un tat COPY_OUT.
int PQgetCopyData(PGconn *conn,
char **buffer,
int async);
Tente d'obtenir une autre ligne de donnes du serveur lors d'une opration COPY. Les donnes ne sont renvoyes qu'une
ligne la fois ; si seulement une ligne partielle est disponible, elle n'est pas renvoye. Le retour d'une ligne avec succs implique l'allocation d'une portion de mmoire pour contenir les donnes. Le paramtre buffer ne doit pas tre NULL.
*buffer est initialis pour pointer vers la mmoire alloue ou vers NULL au cas o aucun tampon n'est renvoy. Un tampon rsultat non NULL devra tre libr en utilisant PQfreemem lorsqu'il ne sera plus utile.
Lorsqu'une ligne est renvoye avec succs, le code de retour est le nombre d'octets de la donne dans la ligne (et sera donc suprieur zro). La chane renvoye est toujours termine par un octet nul bien que ce ne soit utile que pour les COPY textuels. Un rsultat zro indique que la commande COPY est toujours en cours mais qu'aucune ligne n'est encore disponible
(ceci est seulement possible lorsque async est vrai). Un rsultat -1 indique que COPY a termin. Un rsultat -2 indique
qu'une erreur est survenue (consultez PQerrorMessage pour en connatre la raison).
Lorsque async est vraie (diffrent de zro), PQgetCopyData ne bloquera pas en attente d'entre ; il renverra zro si COPY est toujours en cours mais qu'aucune ligne n'est encore disponible (dans ce cas, attendez qu'il soit prt en lecture puis appelez PQconsumeInput avant d'appeler PQgetCopyData de nouveau). Quand async est faux (zro), PQgetCopyData bloquera tant que les donnes ne seront pas disponibles ou tant que l'opration n'aura pas termine.
Aprs que PQgetCopyData ait renvoy -1, appelez PQgetResult pour obtenir le statut de rsultat final de la commande
490

libpq - Bibliothque C

COPY. Vous pourriez attendre la disponibilit de ce rsultat comme d'habitude. Puis, retournez aux oprations habituelles.

31.8.3. Fonctions obsoltes pour COPY


Ces fonctions reprsentent d'anciennes mthodes de gestion de COPY. Bien qu'elles fonctionnent toujours, elles sont obsoltes
cause de leur pauvre gestion des erreurs, des mthodes non convenables de dtection d'une fin de transmission, et du manque de
support des transferts binaires et des transferts non bloquants.
PQgetline
Lit une ligne de caractres termine par un retour chariot (transmis par le serveur) dans un tampon de taille length.
int PQgetline(PGconn *conn,
char *buffer,
int length);
Cette fonction copie jusqu' length-1 caractres dans le tampon et convertit le retour chariot en un octet nul. PQgetline
renvoie EOF la fin de l'entre, 0 si la ligne entire a t lu et 1 si le tampon est complet mais que le retour chariot la fin n'a
pas encore t lu.
Notez que l'application doit vrifier si un retour chariot est constitu de deux caractres \., ce qui indique que le serveur a
termin l'envoi des rsultats de la commande COPY. Si l'application peut recevoir des lignes de plus de length-1 caractres, une attention toute particulire est ncessaire pour s'assurer qu'elle reconnaisse la ligne \. correctement (et ne la
confond pas, par exemple, avec la fin d'une longue ligne de donnes).
PQgetlineAsync
Lit une ligne de donnes COPY (transmise par le serveur) dans un tampon sans blocage.
int PQgetlineAsync(PGconn *conn,
char *buffer,
int bufsize);
Cette fonction est similaire PQgetline mais elle peut tre utilise par des applications qui doivent lire les donnes de COPY de faon asynchrone, c'est--dire sans blocage. Aprs avoir lanc la commande COPY et obtenu une rponse
PGRES_COPY_OUT, l'application devrait appeler PQconsumeInput et PQgetlineAsync jusqu' ce que le signal de fin
des donnes ne soit dtect.
Contrairement PQgetline, cette fonction prend la responsabilit de dtecter la fin de donnes.
chaque appel, PQgetlineAsync renverra des donnes si une ligne de donnes complte est disponible dans le tampon
d'entre de libpq. Sinon, aucune ligne n'est renvoye jusqu' l'arrive du reste de la ligne. La fonction renvoie -1 si le marqueur de fin de copie des donnes a t reconnu, 0 si aucune donne n'est disponible ou un nombre positif indiquant le
nombre d'octets renvoys. Si -1 est renvoy, l'appelant doit ensuite appeler PQendcopy puis retourner aux traitements habituels.
Les donnes renvoyes ne seront pas tendues au del de la limite de la ligne. Si possible, une ligne complte sera retourne
en une fois. Mais si le tampon offert par l'appelant est trop petit pour contenir une ligne envoye par le serveur, alors une ligne
de donnes partielle sera renvoye. Avec des donnes textuelles, ceci peut tre dtect en testant si le dernier octet renvoy est
\n ou non (dans un COPY binaire, l'analyse relle du format de donnes COPY sera ncessaire pour faire la dtermination
quivalente). La chane renvoye n'est pas termine par un octet nul (si vous voulez ajouter un octet nul de terminaison, assurez-vous de passer un bufsize infrieur de 1 par rapport l'espace rellement disponible).
PQputline
Envoie une chane termine par un octet nul au serveur. Renvoie 0 si tout va bien et EOF s'il est incapable d'envoyer la
chane.
int PQputline(PGconn *conn,
const char *string);
Le flux de donnes de COPY envoy par une srie d'appels PQputline a le mme format que celui renvoy par PQgetlineAsync, sauf que les applications ne sont pas obliges d'envoyer exactement une ligne de donnes par appel PQputline ; il est correct d'envoyer une ligne partielle ou plusieurs lignes par appel.

Note
Avant le protocole 3.0 de PostgreSQL, il tait ncessaire pour l'application d'envoyer explicitement les deux
caractres \. comme ligne finale pour indiquer qu'il a termin l'envoi des donnes du COPY data. Bien que
ceci fonctionne toujours, cette mthode est abandonne et la signification spciale de \. pourrait tre suppri491

libpq - Bibliothque C

me dans une prochaine version. Il est suffisant d'appeler PQendcopy aprs avoir envoy les vraies donnes.
PQputnbytes
Envoie une chane non termine par un octet nul au serveur. Renvoie 0 si tout va bien et EOF s'il n'a pas t capable d'envoyer
la chane.
int PQputnbytes(PGconn *conn,
const char *buffer,
int nbytes);
C'est exactement comme PQputline sauf que le tampon de donne n'a pas besoin d'tre termin avec un octet nul car le
nombre d'octets envoys est spcifi directement. Utilisez cette procdure pour envoyer des donnes binaires.
PQendcopy
Se synchronise avec le serveur.
int PQendcopy(PGconn *conn);
Cette fonction attend que le serveur ait termin la copie. Il devrait soit indiquer quand la dernire chane a t envoye au serveur en utilisant PQputline soit le moment o la dernire chane a t reue du serveur en utilisant PGgetline. Si ce
n'est pas fait, le serveur renverra un out of sync (perte de synchronisation) au client. Suivant le retour de cette fonction, le
serveur est prt recevoir la prochaine commande SQL. Le code de retour 0 indique un succs complet et est diffrent de zro
dans le cas contraire (utilisez PQerrorMessage pour rcuprer des dtails sur l'chec).
Lors de l'utilisation de PQgetResult, l'application devrait rpondre un rsultat PGRES_COPY_OUT en excutant PQgetline de faon rpte, suivi par un PQendcopy une fois la ligne de terminaison aperue. Il devrait ensuite retourner
la boucle PQgetResult jusqu' ce que PQgetResult renvoie un pointeur nul. De faon similaire, un rsultat
PGRES_COPY_IN est trait par une srie d'appels PQputline suivis par un PQendcopy, ensuite retour la boucle PQgetResult. Cet arrangement vous assurera qu'une commande COPY intgre dans une srie de commandes SQL sera excute correctement.
Les anciennes applications soumettent un COPY via PQexec et assument que la transaction est faite aprs un PQendcopy.
Ceci fonctionnera correctement seulement si COPY est la seule commande SQL dans la chane de commandes.

31.9. Fonctions de contrle


Ces fonctions contrlent divers dtails du comportement de libpq.
PQclientEncoding
Renvoie l'encodage client.
int PQclientEncoding(const PGconn *conn);
Notez qu'il renvoie l'identifiant d'encodage, pas une chane symbolique telle que EUC_JP. Pour convertir un identifiant
d'encodage en nom, vous pouvez utiliser :
char *pg_encoding_to_char(int encoding_id);
PQsetClientEncoding
Configure l'encodage client.
int PQsetClientEncoding(PGconn *conn, const char *encoding);
conn est la connexion au serveur, et encoding est l'encodage que vous voulez utiliser. Si la fonction initialise l'encodage
avec succs, elle renvoie 0, sinon -1. L'encodage actuel de cette connexion peut tre dtermin en utilisant PQclientEncoding.
PQsetErrorVerbosity
Dtermine la verbosit des messages renvoys par PQerrorMessage et PQresultErrorMessage.
typedef enum
{
PQERRORS_TERSE,
PQERRORS_DEFAULT,
492

libpq - Bibliothque C

PQERRORS_VERBOSE
} PGVerbosity;
PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
PQsetErrorVerbosity initialise le mode de verbosit, renvoyant le paramtrage prcdant de cette connexion. Dans le
mode terse, les messages renvoys incluent seulement la svrit, le texte principal et la position ; ceci tiendra normalement
sur une seule ligne. Le mode par dfaut produit des messages qui inclut ces champs ainsi que les champs dtail, astuce ou
contexte (ils pourraient tre sur plusieurs lignes). Le mode VERBOSE inclut tous les champs disponibles. Modifier la verbosit n'affecte pas les messages disponibles partir d'objets PGresult dj existants, seulement ceux crs aprs.
PQtrace
Active les traces de communication entre client et serveur dans un flux fichier de dbogage.
void PQtrace(PGconn *conn, FILE *stream);

Note
Sur Windows, si la bibliothque libpq et une application sont compiles avec des options diffrentes, cet appel
de fonction arrtera brutalement l'application car la reprsentation interne des pointeurs FILE diffre. Spcifiquement, les options multi-threaded/single-threaded release/debug et static/dynamic devraient tre identiques
pour la bibliothque et les applications qui l'utilisent.
PQuntrace
Dsactive les traces commences avec PQtrace.
void PQuntrace(PGconn *conn);

31.10. Fonctions diverses


Comme toujours, certains fonctions ne sont pas catgorisables.
PQfreemem
Libre la mmoire alloue par libpq.
void PQfreemem(void *ptr);
Libre la mmoire alloue par libpq, particulirement PQescapeByteaConn, PQescapeBytea, PQunescapeBytea,
et PQnotifies. Il est particulirement important que cette fonction, plutt que free(), soit utilise sur Microsoft Windows. Ceci est d l'allocation de la mmoire dans une DLL et la relcher dans l'application fonctionne seulement si les drapeaux multi-thread/mon-thread, release/debug et static/dynamic sont les mmes pour la DLL et l'application. Sur les plateformes autres que Microsoft Windows, cette fonction est identique la fonction free() de la bibliothque standard.
PQconninfoFree
Libre les structures de donnes alloues par PQconndefaults ou PQconninfoParse.
void PQconninfoFree(PQconninfoOption *connOptions);
Un simple appel PQfreemem ne suffira pas car le tableau contient des rfrences des chanes supplmentaires.
PQencryptPassword
Prpare la forme chiffre du mot de passe PostgreSQL.
char * PQencryptPassword(const char *passwd, const char *user);
Cette fonction est utilise par les applications clientes qui souhaitent envoyes des commandes comme ALTER USER joe
PASSWORD 'passe'. Une bonne pratique est de ne pas envoyer le mot de passe en clair dans une telle commande car le
mot de passe serait expos dans les journaux, les affichages d'activit, et ainsi de suite. la place, utilisez cette fonction pour
convertir le mot de passe en clair en une forme chiffre avant de l'envoyer. Les arguments sont le mot de passe en clair et le
nom SQL de l'utilisateur. La valeur renvoye est une chane alloue par malloc ou NULL s'il ne reste plus de mmoire.
L'appelant assume que la chane ne contient aucun caractre spcial qui ncessiterait un chappement. Utilisez PQfreemem
493

libpq - Bibliothque C

pour librer le rsultat une fois termin.


PQmakeEmptyPGresult
Construit un objet PGresult vide avec la statut indiqu.
PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
C'est une fonction interne de la libpq pour allouer et initialiser un objet PGresult vide. Cette fonction renvoit NULL si la mmoire n'a pas pu tre alloue. Elle est exporte car certaines applications trouveront utiles de gnrer eux-mmes des objets de
rsultat (tout particulirement ceux avec des statuts d'erreur). Si conn n'est pas NULL et que status indique une erreur, le
message d'erreur actuel de la connexion indique est copi dans PGresult. De plus, si conn n'est pas NULL, toute procdure
d'vnement enregistre dans la connexion est copie dans le PGresult. (Elles n'obtiennent pas d'appels
PGEVT_RESULTCREATE, mais jetez un il PQfireResultCreateEvents.) Notez que PQclear devra tre appel
sur l'objet, comme pour un PGresult renvoy par libpq lui-mme.
PQfireResultCreateEvents
Dclenche un vnement PGEVT_RESULTCREATE (voir Section 31.12, Systme d'vnements ) pour chaque procdure
d'vnement enregistr dans l'objet PGresult. Renvoit autre chose que zro en cas de succs, zro si la procdure d'vnement
choue.
int PQfireResultCreateEvents(PGconn *conn, PGresult *res);
L'argument conn est pass aux procdures d'vnement mais n'est pas utilis directement. Il peut tre NULL si les procdures
de l'vnement ne l'utiliseront pas.
Les procdures d'vnements qui ont dj reu un vnement PGEVT_RESULTCREATE ou PGEVT_RESULTCOPY pour cet
objet ne sont pas dclenches de nouveau.
La raison principale pour sparer cette fonction de PQmakeEmptyPGResult est qu'il est souvent appropri de crer un
PGresult et de le remplir avec des donnes avant d'appeler les procdures d'vnement.
PQcopyResult
Fait une copie de l'objet PGresult. La copie n'est lie en aucune faon au rsultat source et PQclear doit tre appele dans
que la copie n'est plus ncessaire. Si la fonction choue, NULL est renvoy.
PGresult *PQcopyResult(const PGresult *src, int flags);
Cela n'a pas pour but de faire une copie exacte. Le rsultat renvoy a toujours le statut PGRES_TUPLES_OK, et ne copie aucun message d'erreur dans la source. (Nanmoins, il copie la chane de statut de commande.) L'argument flags dtermine le
reste copier. C'est un OR bit bit de plusieurs drapeaux. PG_COPYRES_ATTRS indique la copie des attributs du rsultat
source (dfinition des colonnes). PG_COPYRES_TUPLES indique la copie des lignes du rsultat source. (Cela implique de
copier aussi les attributs.) PG_COPYRES_NOTICEHOOKS indique la copie des gestionnaires de notification du rsultat
source. PG_COPYRES_EVENTS indique la copie des vnements du rsultat source. (Mais toute instance de donnes associe avec la source n'est pas copie.)
PQsetResultAttrs
Initialise les attributs d'un objet PGresult.
int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc
*attDescs);
Les attDescs fournis sont copis dans le rsultat. Si le pointeur attDescs est NULL ou si numAttributes est infrieur 1, la requte est ignore et la fonction russit. Si res contient dj les attributs, la fonction chouera. Si la fonction
choue, la valeur de retour est zro. Si la fonction russit, la valeur de retour est diffrente de zro.
PQsetvalue
Initialise la valeur d'un champ d'une ligne d'un objet PGresult.
int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int
len);
494

libpq - Bibliothque C

La fonction fera automatiquement grossir le tableau de lignes internes des rsultats, si ncessaire. Nanmoins, l'argument
tup_num doit tre infrieur ou gal PQntuples, ceci signifiant que la fonction peut seulement faire grossir le tableau des
lignes une ligne la fois. Mais tout champ d'une ligne existante peut tre modifi dans n'importe quel ordre. Si une valeur
field_num existe dj, elle sera crase. Si len vaut 1 ou si value est NULL, la valeur du champ sera configure la valeur SQL NULL. value est copi dans le stockage priv du rsultat, donc n'est plus ncessaire au retour de la fonction. Si la
fonction choue, la valeur de retour est zro. Dans le cas contraire, elle a une valeur diffrente de zro.
PQresultAlloc
Alloue un stockage supplmentaire pour un objet PGresult.
void *PQresultAlloc(PGresult *res, size_t nBytes);
Toute mmoire alloue avec cette fonction est libre quand res est efface. Si la fonction choue, la valeur de retour vaut
NULL. Le rsultat est garanti d'tre correctement align pour tout type de donnes, comme pour un malloc.
PQlibVersion
Renvoie la version de libpq en cours d'utilisation.
int PQlibVersion(void);
Le rsultat de cette fonction peut tre utilis pour dterminer, l'excution, si certaines fonctionnalits spcifiques sont disponibles dans la version charge de libpq. Par exemple, cette fonction peut tre utilise pour dterminer les options de
connexions disponibles pour PQconnectdb ou si la sortie hex du type bytea ajoute par PostgreSQL 9.0 est supporte.
Le nombre est form par conversion des numros majeur, mineur et de rvision en nombre deux chiffres et en les concatnant les uns aux autres. Par exemple, la version 9.1 sera renvoye en tant que 90100, alors que la version 9.1.2 sera renvoye
en tant que 90102 (Les zros en dbut de chiffres ne sont pas affiches).

Note
Cette fonction apparat en version 9.1 de PostgreSQL, donc elle ne peut pas tre utilise pour dtecter des
fonctionnalits des versions prcdentes car l'dition de lien crera une dpendance sur la version 9.1.

31.11. Traitement des messages


Les messages de note et d'avertissement gnrs par le serveur ne sont pas renvoys par les fonctions d'excution des requtes car
elles n'impliquent pas d'chec dans la requte. la place, elles sont passes la fonction de gestion des messages et l'excution
continue normalement aprs le retour du gestionnaire. La fonction par dfaut de gestion des messages affiche le message sur stderr mais l'application peut surcharger ce comportement en proposant sa propre fonction de gestion.
Pour des raisons historiques, il existe deux niveaux de gestion de messages, appels la rception des messages et le traitement.
Pour la rception, le comportement par dfaut est de formater le message et de passer une chane au traitement pour affichage.
Nanmoins, une application qui choisit de fournir son propre receveur de messages ignorera typiquement la couche d'envoi de
messages et effectuera tout le travail au niveau du receveur.
La fonction PQsetNoticeReceiver initialise ou examine le receveur actuel de messages pour un objet de connexion. De la
mme faon, PQsetNoticeProcessor initialise ou examine l'metteur actuel de messages.
typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res);
PQnoticeReceiver
PQsetNoticeReceiver(PGconn *conn,
PQnoticeReceiver proc,
void *arg);
typedef void (*PQnoticeProcessor) (void *arg, const char *message);
PQnoticeProcessor
PQsetNoticeProcessor(PGconn *conn,
PQnoticeProcessor proc,
void *arg);
Chacune de ces fonctions reoit le pointeur de fonction du prcdent receveur ou metteur de messages et configure la nouvelle
valeur. Si vous fournissez un pointeur de fonction nul, aucune action n'est ralise mais le pointeur actuel est renvoy.
495

libpq - Bibliothque C

Quand un message de note ou d'avertissement est reu du serveur ou gnr de faon interne par libpq, la fonction de rception du
message est appele. Le message lui est pass sous la forme d'un PGresult PGRES_NONFATAL_ERROR (ceci permet au receveur d'extraire les champs individuels en utilisant PQresultErrorField ou le message complet prformat en utilisant PQresultErrorMessage). Le mme pointeur void pass PQsetNoticeReceiver est aussi renvoy (ce pointeur peut tre
utilis pour accder un tat spcifique de l'application si ncessaire).
Le receveur de messages par dfaut extrait simplement le message (en utilisant PQresultErrorMessage) et le passe au systme de traitement du message.
Ce dernier est responsable de la gestion du message de note ou d'avertissement donn au format texte. La chane texte du message
est passe avec un retour chariot supplmentaire, plus un pointeur sur void identique celui pass PQsetNoticeProcessor
(ce pointeur est utilis pour accder un tat spcifique de l'application si ncessaire).
Le traitement des messages par dfaut est simplement
static void
defaultNoticeProcessor(void * arg, const char * message)
{
fprintf(stderr, "%s", message);
}
Une fois que vous avez initialis un receveur ou une fonction de traitement des messages, vous devez vous attendre ce que la
fonction soit appele aussi longtemps que l'objet PGconn ou qu'un objet PGresult ralis partir de celle-ci existent. la cration
d'un PGresult, les pointeurs de gestion actuels de PGconn sont copis dans PGresult pour une utilisation possible par des fonctions
comme PQgetvalue.

31.12. Systme d'vnements


Le systme d'vnements de libpq est conu pour notifier les gestionnaires d'vnements enregistrs de l'arrive d'vnements intressants de la libpq, comme par exemple la cration ou la destruction d'objets PGconn et PGresult. Un cas d'utilisation principal
est de permettre aux applications d'associer leur propres donnes avec un PGconn ou un PGresult et de s'assurer que les donnes
soient libres au bon moment.
Chaque gestionnaire d'vnement enregistr est associ avec deux types de donnes, connus par libpq comme des pointeurs
opaques, c'est--dire void *. Il existe un pointeur passthrough fournie par l'application quand le gestionnaire d'vnements est
enregistr avec un PGconn. Le pointeur passthrough ne change jamais pendant toute la dure du PGconn et des PGresult gnrs
grce lui ; donc s'il est utilis, il doit pointer vers des donnes vivantes. De plus, il existe une pointeur de donnes instancies,
qui commence NULL dans chaque objet PGconn et PGresult. Ce pointeur peut tre manipul en utilisant les fonctions PQinstanceData, PQsetInstanceData, PQresultInstanceData et PQsetResultInstanceData. Notez que, contrairement au pointeur passthrough, les PGresult n'hritent pas automatiquement des donnes instancies d'un PGconn. libpq ne sait
pas vers quoi pointent les pointeurs passthrough et de donnes instancies, et n'essaiera hamais de les librer -- cela tient de la responsabilit du gestionnaire d'vnements.

31.12.1. Types d'vnements


La variable PGEventId de type enum prcise tous les types d'vnements grs par le systme d'vnements. Toutes ces valeurs
ont des noms commenant avec PGEVT. Pour chaque type d'vnement, il existe une structure d'informations sur l'vnement,
prcisant les paramtres passs aux gestionnaires d'vnement. Les types d'vnements sont :
PGEVT_REGISTER
L'vnement d'enregistrement survient quand PQregisterEventProc est appel.; C'est le moment idal pour initialiser
toute structure instanceData qu'une procdure d'vnement pourrait avoir besoin. Seul un vnement d'enregistrement sera dclench par gestionnaire d'vvenement sur une connexion. Si la procdure choue, l'enregistrement est annul.
typedef struct
{
PGconn *conn;
} PGEventRegister;
Quand un vnement PGEVT_REGISTER est reu, le pointeur evtInfo doit tre converti en un PGEventRegister *. Cette
structure contient un PGconn qui doit tre dans le statut CONNECTION_OK ; garanti si PQregisterEventProc est appel juste aprs avoir obtenu un bon PGconn. Lorsqu'elle renvoit un code d'erreur, le nettoyage doit tre ralis car aucun vnement PGEVT_CONNDESTROY ne sera envoy.
PGEVT_CONNRESET
496

libpq - Bibliothque C

L'vnement de rinitialisation de connexion est dclench aprs un PQreset ou un PQresetPoll. Dans les deux cas,
l'vnement est seulement dclench si la r-initialisation est russie. Si la procdure choue, la rinitialisation de connexion
chouera ; la structure PGconn est place dans le statut CONNECTION_BAD et PQresetPoll renverra
PGRES_POLLING_FAILED.
typedef struct
{
PGconn *conn;
} PGEventConnReset;
Quand un vnement PGEVT_CONNRESET est reu, le pointeur evtInfo doit tre converti en un PGEventConnReset *.
Bien que le PGconn a t rinitialis, toutes les donnes de l'vnement restent inchanges. Cet vnement doit tre utilis
pour r-initialiser/recharger/re-requter tout instanceData associ. Notez que mme si la procdure d'vnement choue
traiter PGEVT_CONNRESET, elle recevra toujours un vnement PGEVT_CONNDESTROY la fermeture de la connexion.
PGEVT_CONNDESTROY
L'vnement de destruction de la connexion est dclenche en rponse PQfinish. Il est de la responsabilit de la procdure de l'vnement de nettoyer proprement ses donnes car libpq n'a pas les moyens de grer cette mmoire. Un chec du
nettoyage amnera des pertes mmoire.
typedef struct
{
PGconn *conn;
} PGEventConnDestroy;
Quand un vnement PGEVT_CONNDESTROY est reu, le pointeur evtInfo doit tre converti en un PGEventConnDestroy
*. Cet vnement est dclench avant que PQfinish ne ralise d'autres nettoyages. La valeur de retour de la procdure est
ignore car il n'y a aucun moyen d'indiquer un chec de PQfinish. De plus, un chec de la procdure ne doit pas annuler le
nettoyage de la mmoire non dsire.
PGEVT_RESULTCREATE
L'vnement de cration de rsultat est dclench en rponse l'utilisation d'une fonction d'excution d'une requte, par
exemple PQgetResult. Cet vnement sera dclench seulement aprs la cration russie du rsultat.
typedef struct
{
PGconn *conn;
PGresult *result;
} PGEventResultCreate;
Quand un vnement PGEVT_RESULTCREATE est reu, le pointeur evtInfo doit tre converti en un PGEventResultCreate *. Le paramtre conn est la connexion utilise pour gnrer le rsultat. C'est le moment idal pour initialiser tout
instanceData qui doit tre associ avec le rsultat. Si la procdure choue, le rsultat sera effac et l'chec sera propag.
Le procdure d'vnement ne doit pas tenter un PQclear sur l'objet rsultat lui-mme. Lors du renvoi d'un code d'chec, tout
le nettoyage doit tre fait car aucun vnement PGEVT_RESULTDESTROY ne sera envoy.
PGEVT_RESULTCOPY
L'vnement de copie du rsultat est dclench en rponse un PQcopyResult. Cet vnement se dclenchera seulement
une fois la copie termine. Seules les procdures qui ont gres avec succs l'vnement PGEVT_RESULTCREATE ou
PGEVT_RESULTCOPY pour le rsultat source recevront les vnements PGEVT_RESULTCOPY.
typedef struct
{
const PGresult *src;
PGresult *dest;
} PGEventResultCopy;
Quand un vnement PGEVT_RESULTCOPY est reu, le pointeur evtInfo doit tre converti en un PGEventResultCopy *.
Le rsultat rsultat src correspond ce qui a t copi alors que le rsultat dest correspond la destination. Cet vnement
peut tre utilis pour fournir une copie complte de instanceData, ce que PQcopyResult ne peut pas faire. Si la procdure choue, l'opration complte de copie chouera et le rsultat dest sera effac. Au renvoi d'un code d'chec, tout le nettoyage doit tre ralis car aucun vnement PGEVT_RESULTDESTROY ne sera envoy pour le rsultat de destination.
497

libpq - Bibliothque C

PGEVT_RESULTDESTROY
L'vnement de destruction de rsultat est dclench en rponse la fonction PQclear. C'est de la responsabilit de
l'vnement de nettoyer proprement les donnes de l'vnement car libpq n'a pas cette capacit en matire de gestion de mmoire. Si le nettoyage choue, cela sera la cause de pertes mmoire.
typedef struct
{
PGresult *result;
} PGEventResultDestroy;
Quand un vnement PGEVT_RESULTDESTROY est reu, le pointeur evtInfo doit tre converti en un PGEventResultDestroy *. Cet vnement est dclench avant que PQclear ne puisse faire de nettoyage. La valeur de retour de la procdure est
ignore car il n'existe aucun moyen d'indiquer un chec partir de PQclear. De plus, un chec de la procdure ne doit pas
annuler le nettoyage de la mmoire non dsire.

31.12.2. Procdure de rappel de l'vnement


PGEventProc
PGEventProc est une dfinition de type pour un pointeur vers une procdure d'vnement, c'est--dire la fonction utilisateur appele pour les vnements de la libpq. La signature d'une telle fonction doit tre :
int eventproc(PGEventId evtId, void *evtInfo, void *passThrough)
Le paramtre evtId indique l'vnement PGEVT qui est survenu. Le pointeur evtInfo doit tre converti vers le type de
structure appropri pour obtenir plus d'informations sur l'vnement. Le paramtre passThrough est le pointeur fourni
PQregisterEventProc quand la procdure de l'vnement a t enregistre. La fonction doit renvoyer une valeur diffrente de zro en cas de succs et zro en cas d'chec.
Une procdure d'vnement particulire peut tre enregistre une fois seulement pour un PGconn. Ceci est d au fait que
l'adresse de la procdure est utilise comme cl de recherche pour identifier les donnes instancies associes.

Attention
Sur Windows, les fonctions peuvent avoir deux adresses diffrentes : une visible de l'extrieur de la DLL et
une visible de l'intrieur. Il faut faire attention que seule une de ces adresses est utilise avec les fonctions
d'vnement de la libpq, sinon une confusion en rsultera. La rgle la plus simple pour crire du code qui fonctionnera est de s'assurer que les procdures d'vnements sont dclares static. Si l'adresse de la procdure
doit tre disponible en dehors de son propre fichier source, il faut exposer une fonction spare pour renvoyer
l'adresse.

31.12.3. Fonctions de support des vnements


PQregisterEventProc
Enregistre une procdure de rappel pour les vnements avec libpq.
int PQregisterEventProc(PGconn *conn, PGEventProc proc,
const char *name, void *passThrough);
Une procdure d'venement doit tre enregistr une fois pour chaque PGconn pour lequel vous souhaitez recevoir des vnements. Il n'existe pas de limites, autre que la mmoire, sur le nombre de procdures d'vnements qui peuvent tre enregistres avec une connexion. La fonction renvoie une valeur diffrente de zro en cas de succs, et zro en cas d'chec.
L'argument proc sera appel quand se dclenchera un vnement libpq. Son adresse mmoire est aussi utilise pour rechercher instanceData. L'argument name est utilis pour faire rfrence la procdure d'venement dans les messages
d'erreur. Cette valeur ne peut pas tre NULL ou une chane de longueur nulle. La chane du nom est copie dans PGconn,
donc ce qui est pass n'a pas besoin de durer longtemps. Le pointeur passThrough est pass proc chaque arrive d'un
vnement. Cet argument peut tre NULL.
PQsetInstanceData
498

libpq - Bibliothque C

Initialise instanceData de la connexion pour la procdure proc avec data. Cette fonction renvoit zro en cas d'chec et
autre chose en cas de russite. (L'chec est seulement possible si proc n'a pas t correctement enregistr dans le rsultat.)
int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data);
PQinstanceData
Renvoie le instanceData de la connexion associe avec connproc ou NULL s'il n'y en a pas.
void *PQinstanceData(const PGconn *conn, PGEventProc proc);
PQresultSetInstanceData
Initialise le instanceData du rsultat pour la procdure proc avec data. Cette fonction renvoit zro en cas d'chec et
autre chose en cas de russite. (L'chec est seulement possible si proc n'a pas t correctement enregistr dans le rsultat.)
int PQresultSetInstanceData(PGresult *res, PGEventProc proc, void *data);
PQresultInstanceData
Renvoie le instanceData du rsultat associ avec proc ou NULL s'il n'y en a pas.
void *PQresultInstanceData(const PGresult *res, PGEventProc proc);

31.12.4. Exemple d'un vnement


Voici un exemple d'une gestion de donnes prives associe aux connexions et aux rsultats de la libpq.

/* en-tte ncssaire pour les vnements de la libpq (note : inclut libpq-fe.h) */


#include <libpq-events.h>
/* la donne instancie : instanceData */
typedef struct
{
int n;
char *str;
} mydata;
/* PGEventProc */
static int myEventProc(PGEventId evtId, void *evtInfo, void *passThrough);
int
main(void)
{
mydata *data;
PGresult *res;
PGconn *conn = PQconnectdb("dbname = postgres");
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
PQfinish(conn);
return 1;
}
/* appele une fois pour toute connexion qui doit recevoir des vnements.
* Envoit un PGEVT_REGISTER myEventProc.
*/
if (!PQregisterEventProc(conn, myEventProc, "mydata_proc", NULL))
{
fprintf(stderr, "Cannot register PGEventProc\n");
499

libpq - Bibliothque C

PQfinish(conn);
return 1;
}
/* la connexion instanceData est disponible */
data = PQinstanceData(conn, myEventProc);
/* Envoit un PGEVT_RESULTCREATE myEventProc */
res = PQexec(conn, "SELECT 1 + 1");
/* le rsultat instanceData est disponible */
data = PQresultInstanceData(res, myEventProc);
/* Si PG_COPYRES_EVENTS est utilis, envoit un PGEVT_RESULTCOPY myEventProc */
res_copy = PQcopyResult(res, PG_COPYRES_TUPLES | PG_COPYRES_EVENTS);
/* le rsultat instanceData est disponible si PG_COPYRES_EVENTS a t
* utilis lors de l'appel PQcopyResult.
*/
data = PQresultInstanceData(res_copy, myEventProc);
/* Les deux fonctions de nettoyage envoient PGEVT_RESULTDESTROY myEventProc */
PQclear(res);
PQclear(res_copy);
/* Envoit un PGEVT_CONNDESTROY myEventProc */
PQfinish(conn);
return 0;
}
static int
myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
{
switch (evtId)
{
case PGEVT_REGISTER:
{
PGEventRegister *e = (PGEventRegister *)evtInfo;
mydata *data = get_mydata(e->conn);
/* associe des donnes spcifiques de l'application avec la connexion */
PQsetInstanceData(e->conn, myEventProc, data);
break;
}
case PGEVT_CONNRESET:
{
PGEventConnReset *e = (PGEventConnReset *)evtInfo;
mydata *data = PQinstanceData(e->conn, myEventProc);
if (data)
memset(data, 0, sizeof(mydata));
break;
}
case PGEVT_CONNDESTROY:
{
PGEventConnDestroy *e = (PGEventConnDestroy *)evtInfo;
mydata *data = PQinstanceData(e->conn, myEventProc);
/* libre les donnes instancies car la connexion est en cours de
destruction */
if (data)
free_mydata(data);
break;
}
case PGEVT_RESULTCREATE:
500

libpq - Bibliothque C

{
PGEventResultCreate *e = (PGEventResultCreate *)evtInfo;
mydata *conn_data = PQinstanceData(e->conn, myEventProc);
mydata *res_data = dup_mydata(conn_data);
/* associe des donnes spcifiques l'application avec les rsultats
(copi de la connexion) */
PQsetResultInstanceData(e->result, myEventProc, res_data);
break;
}
case PGEVT_RESULTCOPY:
{
PGEventResultCopy *e = (PGEventResultCopy *)evtInfo;
mydata *src_data = PQresultInstanceData(e->src, myEventProc);
mydata *dest_data = dup_mydata(src_data);
/* associe des donnes spcifiques l'application avec les rsultats
(copi d'un rsultat) */
PQsetResultInstanceData(e->dest, myEventProc, dest_data);
break;
}
case PGEVT_RESULTDESTROY:
{
PGEventResultDestroy *e = (PGEventResultDestroy *)evtInfo;
mydata *data = PQresultInstanceData(e->result, myEventProc);
/* libre les donnes instancies car le rsultat est en cours de
destruction */
if (data)
free_mydata(data);
break;
}
/* unknown event id, just return TRUE. */
default:
break;
}
return TRUE; /* event processing succeeded */
}

31.13. Variables d'environnement


Les variables d'environnement suivantes peuvent tre utilises pour slectionner des valeurs par dfaut pour les paramtres de
connexion, valeurs qui seront utilises par PQconnectdb, PQsetdbLogin et PQsetdb si aucune valeur n'est directement
prcise par le code d'appel. Elles sont utiles pour viter de coder en dur les informations de connexion la base de donnes dans
les applications clients, par exemple.

PGHOST se comporte de la mme faon que le paramtre de configuration host.

PGHOSTADDR se comporte de la mme faon que le paramtre de configuration hostaddr. Elle peut tre initialise avec
PGHOST pour viter la surcharge des recherches DNS.

PGPORT se comporte de la mme faon que le paramtre de configuration port.

PGDATABASE se comporte de la mme faon que le paramtre de configuration dbname.

PGUSER se comporte de la mme faon que le paramtre de configuration user.

PGPASSWORD se comporte de la mme faon que le paramtre de configuration password. L'utilisation de cette variable
d'environnement n'est pas recommande pour des raisons de scurit (certains systmes d'exploitation autorisent les utilisateurs autres que root voir les variables d'environnement du processus via ps) ; la place, considrez l'utilisation du fichier
~/.pgpass (voir la Section 31.14, Fichier de mots de passe ).

PGPASSFILE spcifie le nom du fichier de mot de passe utiliser pour les recherches. Sa valeur par dfaut est ~/.pgpass
(voir la Section 31.14, Fichier de mots de passe ).
501

libpq - Bibliothque C

PGSERVICE se comporte de la mme faon que le paramtre de configuration service.

PGSERVICEFILE indique le nom du fichier service de connexion par utilisateur. S'il n'est pas configur, sa valeur par dfaut
est ~/.pg_service.conf (voir Section 31.15, Fichier des connexions de service ).

PGREALM initialise le domaine Kerberos utiliser avec PostgreSQL s'il est diffrent du domaine local. Si PGREALM est initialis, les applications libpq tenteront une authentification avec les serveurs de ce domaine et utiliseront les fichiers tickets spars pour viter les conflits avec les fichiers tickets locaux. Cette variable d'environnement est seulement utilise si
l'authentification Kerberos est slectionne par le serveur.

PGOPTIONS se comporte de la mme faon que le paramtre de configuration options.

PGAPPNAME se comporte de la mme faon que le paramtre de connexion application_name.

PGSSLMODE se comporte de la mme faon que le paramtre de configuration sslmode.

PGREQUIRESSL se comporte de la mme faon que le paramtre de configuration requiressl.

PGSSLKEY spcifie le jeton matriel qui stocke la cl secrte pour le certificat client. La valeur de cette variable doit consister
d'un nom de moteur spar par une virgule (les moteurs sont les modules chargeables d'OpenSSL) et un identifiant de cl
spcifique au moteur. Si elle n'est pas configure, la cl secrte doit tre conserve dans un fichier.

PGSSLCERT se comporte de la mme faon que le paramtre de configuration sslcert.

PGSSLKEY se comporte de la mme faon que le paramtre de configuration sslkey.

PGSSLROOTCERT se comporte de la mme faon que le paramtre de configuration sslrootcert.

PGSSLCRL se comporte de la mme faon que le paramtre de configuration sslcrl.

PGREQUIREPEER se comporte de la mme faon que le paramtre de connexion requirepeer.

PGKRBSRVNAME se comporte de la mme faon que le paramtre de configuration krbsrvname.

PGGSSLIB se comporte de la mme faon que le paramtre de configuration gsslib.

PGCONNECT_TIMEOUT se comporte de la mme faon que le paramtre de configuration connect_timeout.

PGCLIENTENCODING se comporte de la mme faon que le paramtre de connexion client_encoding.

Les variables d'environnement par dfaut peuvent tre utilises pour spcifier le comportement par dfaut de chaque session PostgreSQL (voir aussi les commandes ALTER ROLE(7) et ALTER DATABASE(7) pour des moyens d'initialiser le comportement par dfaut sur des bases par utilisateur ou par bases de donnes).

PGDATESTYLE initialise le style par dfaut de la reprsentation de la date et de l'heure (quivalent SET datestyle TO
...).

PGTZ initialise le fuseau horaire par dfaut (quivalent SET timezone TO ...).

PGGEQO initialise le mode par dfaut pour l'optimiseur gnrique de requtes (quivalent SET geqo TO ...).

Rfrez-vous la commande SQL SET(7) pour plus d'informations sur des valeurs correctes pour ces variables d'environnement.
Les variables d'environnement suivantes dterminent le comportement interne de libpq ; elles surchargent les valeurs internes par
dfaut.

PGSYSCONFDIR configure le rpertoire contenant le fichier pg_service.conf et dans une future version d'autres fichiers
de configuration globaux au systme.

PGLOCALEDIR configure le rpertoire contenant les fichiers locale pour l'internationalisation des messages.

31.14. Fichier de mots de passe


Le fichier .pgpass, situ dans le rpertoire personnel de l'utilisateur, ou le fichier rfrenc par PGPASSFILE est un fichier
contenant les mots de passe utiliser si la connexion requiert un mot de passe (et si aucun mot de passe n'a t spcifi). Sur Microsoft Windows, le fichier est nomm %APPDATA%\postgresql\pgpass.conf (o %APPDATA% fait rfrence au sousrpertoire Application Data du profile de l'utilisateur).
Ce fichier devra tre compos de lignes au format suivant (une ligne par connexion) :
nom_hote:port:database:nomutilisateur:motdepasse

502

libpq - Bibliothque C

(Vous pouvez ajouter en commentaire dans le fichier cette ligne que vous prcdez d'un dise (#).) Chacun des quatre premiers
champs pourraient tre une valeur littrale ou * (qui correspond tout). La premire ligne ralisant une correspondance pour les
paramtres de connexion sera utilise (du coup, placez les entres plus spcifiques en premier lorsque vous utilisez des jokers). Si
une entre a besoin de contenir : ou \, chappez ce caractre avec \. Un nom d'hte localhost correspond la fois une
connexion TCP (nom d'hte localhost) et une connexion par socket de domaine Unix (pghost vide ou le rpertoire par dfaut du socket) provenant de la machine locale. Dans un serveur en standby, le nom de la base de donnes replication correspond aux connexions ralises par le serveur matre pour la rplication en flux. Le champ database est d'une utilit limite car
les utilisateurs ont le mme mot de passe pour toutes les bases de donnes de la mme instance.
Sur les systmes Unix, les droits sur .pgpass doivent interdire l'accs au groupe et au reste du monde ; faites-le par cette commande : chmod 0600 ~/.pgpass. Si les droits sont moins stricts que cela, le fichier sera ignor. Sur Microsoft Windows, il est suppos que le fichier est stock dans un rpertoire qui est scuris, donc aucune vrification des droits n'est effectue.

31.15. Fichier des connexions de service


Le fichier des connexions de service autorise l'association des paramtres de connexions avec un seul nom de service. Ce nom de
service peut ensuite tre spcifi par une connexion libpq et les paramtrages associs seront utiliss. Ceci permet de modifier les
paramtres de connexion sans avoir recompiler l'application libpq. Le nom de service peut aussi tre spcifi en utilisant la variable d'environnement PGSERVICE.
Le fichier de service pour la connexion peut tre un fichier par utilisateur sur ~/.pg_service.conf ou l'emplacement indiqu par la variable d'environnement PGSERVICEFILE. Il peut aussi tre un fichier global au systme dans le rpertoire etc/
pg_service.conf ou dans le rpertoire indiqu par la variable d'environnement PGSYSCONFDIR. Si les dfinitions de service de mme nom existent dans le fichier utilisateur et systme, le fichier utilisateur est utilis.
Le fichier utiliser le format des fichiers INI o le nom de la section et les paramtres sont des paramtres de connexion ; voir
Section 31.1, Fonctions de contrle de connexion la base de donnes pour une liste. Par exemple :
# comment
[mabase]
host=unhote
port=5433
user=admin
Un fichier exemple est fourni sur share/pg_service.conf.sample.

31.16. Recherches LDAP des paramtres de connexion


Si libpq a t compil avec le support de LDAP (option --with-ldap du script configure), il est possible de rcuprer les options de connexion comme host ou dbname via LDAP partir d'un serveur central. L'avantage en est que, si les paramtres de
connexion d'une base volue, l'information de connexion n'a pas tre modifie sur toutes les machines clientes.
La recherche LDAP des paramtres de connexion utilise le fichier service pg_service.conf (voir Section 31.15, Fichier des
connexions de service ). Une ligne dans pg_service.conf commenant par ldap:// sera reconnue comme une URL
LDAP et une requte LDAP sera excute. Le rsultat doit tre une liste de paires motcl = valeur qui sera utilise pour
configurer les options de connexion. L'URL doit tre conforme la RFC 1959 et tre de la forme :
ldap://[hte[:port]]/base_recherche?attribut?tendue_recherche?filtre
o hte vaut par dfaut localhost et port vaut par dfaut 389.
Le traitement de pg_service.conf se termine aprs une recherche russie dans LDAP, mais continu si le serveur LDAP ne
peut pas tre contact. Cela fournit un moyen de prciser d'autres URL LDAP pointant vers d'autres serveurs LDAP, des paires
classiques motcl = valeur ou les options de connexion par dfaut. Si vous obtenez la place un message d'erreur, ajoutez
une ligne syntaxiquement incorrecte aprs l'URL LDAP.
Un exemple d'une entre LDAP qui a t cre partir d'un fichier LDIF
version: 1
dn: cn=mabase,dc=masocit,dc=com
changetype: add
objectclass: top
objectclass: groupOfUniqueNames
cn: mabase
uniqueMember: host=monserveur.masocit.com
uniqueMember: port=5439
503

libpq - Bibliothque C

uniqueMember: dbname=mabase
uniqueMember: user=monutilisateur_base
uniqueMember: sslmode=require
amnera l'excution de l'URL LDAP suivante :
ldap://ldap.masocit.com/dc=masocit,dc=com?uniqueMember?one?(cn=mabase)
Vous pouvez mlanger des entres d'un fichier de service standard avec des recherches par LDAP. Voici un exemple complet dans
pg_service.conf :
# seuls l'hte et le port sont stocks dans LDAP,
# spcifiez explicitement le nom de la base et celui de l'utilisateur
[customerdb]
dbname=clients
user=utilisateurappl
ldap://ldap.acme.com/cn=serveur,cn=hosts?pgconnectinfo?base?(objectclass=*)

31.17. Support de SSL


PostgreSQL dispose d'un support natif des connexions SSL pour crypter les connexions client/serveur et amliorer ainsi la scurit. Voir la Section 17.9, Connexions tcp/ip scurises avec ssl pour des dtails sur la fonctionnalit SSL ct serveur.
libpq lit le fichier de configuration systme d'OpenSSL. Par dfaut, ce fichier est nomm openssl.cnf et est plac dans le
rpertoire indiqu par openssl version -d. Cette valeur par dfaut peut tre surcharg en configurant la variable
d'environnement OPENSSL_CONF avec le nom du fichier de configuration souhait.

31.17.1. Vrification par le client du certificat serveur


Par dfaut, PostgreSQL ne vrifie pas le certificat du serveur. Cela signifie qu'il est possible de se faire passer pour le serveur final (par exemple en modifiant un enregistrement DNS ou en prenant l'adresse IP du serveur) sans que le client ne le sache. Pour
empcher ceci, la vrification du certificat SSL doit tre active.
Si le paramtre sslmode est configur verify-ca, libpq vrifiera que le serveur est de confiance en vrifiant que le certificat
a bien t gnr par une autorit de certificats (CA) de confiance. Si sslmode est configur verify-full, libpq vrifiera
aussi que le nom du serveur correspond son certificat. La connexion SSL chouera si le certificat du serveur n'tablit pas ces correspondances. La connexion SSL chouera si le certificat du serveur ne peut pas tre vrifi. verify-full est recommand
pour les environnements les plus sensibles la scurit.
Dans le mode verify-full, l'attribut cn (Common Name) du certificat est test par rapport au nom du serveur . Si l'attribut cn
commence avec un astrisque(*), il sera trait comme un joker, et correspondra tous les caractres sauf un point (.). Cela signifie que le certificat ne pourra pas tre utilis pour des sous-domaines complets. Si la connexion se fait en utilisant une adresse IP
au lieu d'un nom d'hte, l'adresse IP sera vrifie (sans faire de recherche DNS).
Pour permettre la vrification du certificat du serveur, le certificat d'un ou plusieurs CA de confiance doit tre plac dans le fichier
~/.postgresql/root.crt dans le rpertoire personnel de l'utilisateur. Su Microsoft Windows, le fichier est nomm
%APPDATA%\postgresql\root.crt.
Les entres de la liste de rvocation des certificats (CRL) sont aussi vrifies si le fichier ~/.postgresql/root.crl existe
(%APPDATA%\postgresql\root.crl sur Microsoft Windows).
L'emplacement du certificat racine et du CRL peuvent tre changs avec les paramtres de connexion sslrootcert et
sslcrl, ou les variables d'environnement PGSSLROOTCERT et PGSSLCRL.

Note
Pour une compatibilit ascendantes avec les anciennes versions de PostgreSQL, si un certificat racine d'autorit
existe, le comportement de sslmode=require sera identique celui de verify-ca. Cela signifie que le certificat du serveur est valid par l'autorit de certificat. Il ne faut pas se baser sur ce comportement. Les applications
qui ont besoin d'une validation du certificat doivent toujours utiliser verify-ca ou verify-full.

31.17.2. Certificats des clients


504

libpq - Bibliothque C

Si le serveur rclame un certificat de confiance du client, libpq enverra le certificat stock dans le fichier
~/.postgresql/postgresql.crt du rpertoire personnel de l'utilisateur. Le certificat doit tre sign par une des autorits
(CA) de confiance du serveur. Un fichier de cl priv correspondant ~/.postgresql/postgresql.key doit aussi tre prsent. Le fichier de cl prive ne doit pas permettre son accs pour le groupe ou pour le reste du monde ; cela se fait avec la commande chmod 0600 ~/.postgresql/postgresql.key. Sur Microsoft Windows, ces fichiers sont nomms
%APPDATA%\postgresql\postgresql.crt et %APPDATA%\postgresql\postgresql.key, et il n'existe pas de
vrification de droits car ce rpertoire est prsum scuris. L'emplacement des fichiers certificat et cl peut tre surcharg par les
paramtres de connexion sslcert et sslkey, ou les variables d'environnement PGSSLCERT et PGSSLKEY.
Dans certains cas, le certificat du client peut tre sign par une autorit de certificat intermdiaire , plutt que par un qui est directement accept par le serveur. Pour utiliser un tel certificat, ajoutez le certificat de l'autorit signataire du fichier postgresql.crt, alors son certificat de l'autorit parente, et ainsi de suite jusqu' arriver l'autorit racine qui est accept par le serveur. Le certificat racine doit tre inclus dans chaque cas o postgresql.crt contient plus d'un certificat.
Notez que root.crt liste les autorits de certificat de haut-niveau qui sont considres de confiance pour les certificats serveur
signataires. En principe, il n'a pas besoin de lister l'autorit de certificats qui a sign le certificat du client, bien que dans la plupart
des cas, l'autorit du certificat sera aussi de confiance pour les certificats serveur.

31.17.3. Protection fournie dans les diffrents modes


Les diffrentes valeurs du paramtre sslmode fournissent diffrents niveaux de protection. SSL peut fournir une protection
contre trois types d'attaques diffrentes :
L'coute
Si une troisime partie peut examiner le trafic rseau entre le client et le serveur, il peut lire la fois les informations de
connexion (ceci incluant le nom de l'utilisateur et son mot de passe) ainsi que les donnes qui y passent. SSL utilise le chiffrement pour empcher cela.
Man in the middle (MITM)
Si une troisime partie peut modifier les donnes passant entre le client et le serveur, il peut prtendre tre le serveur et, du
coup, voir et modifier les donnes y compris si elles sont chiffres. La troisime partie peut ensuite renvoyer les informations
de connexion et les donnes au serveur d'origine, rendant ce dernier impossible la dtection de cette attaque. Les vecteurs
communs pour parvenir ce type d'attaque sont l'empoisonnement des DNS et la rcupration des adresses IP o le client est
dirig vers un autre serveur que celui attendu. Il existe aussi plusieurs autres mthodes d'attaque pour accomplir ceci. SSL utilise la vrification des certificats pour empcher ceci, en authentifiant le serveur auprs du client.
Impersonnification
Si une troisime partie peut prtendre tre un client autoris, il peut tout simplement accder aux donnes auquel il n'a pas
droit. Typiquement, cela peut arrier avec une gestion incorrecte des mots de passe. SSL utilise les certificats clients pour empcher ceci, en s'assurant que seuls les propritaires de certificats valides peuvent accder au serveur.
Pour qu'une connexion soit sre, l'utilisation de SSL doit tre configure sur le client et sur le serveur avant que la connexion ne
soit effective. Si c'est seulement configur sur le serveur, le client pourrait envoyer des informations sensibles (comme les mots de
passe) avant qu'il ne sache que le serveur rclame une scurit importante. Dans libpq, les connexions scurises peuvent tre garanties en configurant le paramtre sslmode verify-full ou verify-ca, et en fournissant au systme un certificat racine
vrifier. Ceci est analogue l'utilisation des URL https pour la navigation web chiffre.
Une fois que le serveur est authentifi, le client peut envoyer des donnes sensibles. Cela signifie que jusqu' ce point, le client n'a
pas besoin de savoir si les certificats seront utiliss pour l'authentification, rendant particulirement sr de ne spcifier que ceci
dans la configuration du serveur.
Toutes les options SSL ont une surcharge du type chiffrement et change de cls. Il y a donc une balance entre performance et scurit. Tableau 31.1, Description des modes SSL illustre les risques que les diffrentes valeurs de sslmode cherchent protger, et ce que cela apporte en scurit et fait perdre en performances.
Tableau 31.1. Description des modes SSL

sslmode

Protection contre l'coute

Protection contre l'attaque Remarques


MITM

disable

Non

Non

Peu m'importe la scurit, je ne


veux pas la surcharge apporte
par le chiffrement.

allow

Peut-tre

Non

Peu m'importe la scurit, mais


je vais accepter la surcharge du

505

libpq - Bibliothque C

sslmode

Protection contre l'coute

Protection contre l'attaque Remarques


MITM
chiffrement si le serveur insiste
l-dessus.

prefer

Peut-tre

Non

Peu m'importe la scurit, mais


j'accepte la surcharge du chiffrement si le serveur le supporte.

require

Oui

Non

Je veux chiffrer mes donnes,


et j'accepte la surcharge. Je fais
confiance au rsreau pour me
connecter toujours au serveur
que je veux.

verify-ca

Oui

Depends on CA-policy

Je veux chiffrer mes donnes,


et j'accepte la surcharge. Je
veux aussi tre sr que je me
connecte un serveur en qui
j'ai confiance.

verify-full

Oui

Oui

Je veux chiffrer mes donnes,


et j'accepte la surcharge. Je
veux tre sr que je me
connecte un serveur en qui
j'ai confiance et que c'est bien
celui que j'indique.

La diffrence entre verify-ca et verify-full dpend de la politique du CA racine. Si un CA publique est utilis, verify-ca permet les connexions un serveur que quelqu'un d'autre a pu enregistrer avec un CA accept. Dans ce cas, verifyfull devrait toujours tre utilis. Si un CA local est utilis, voire mme un certificat sign soi-mme, utiliser verify-ca fournit souvent suffisamment de protection.
La valeur par dfaut pour sslmode est prefer. Comme l'indique la table ci-dessus, cela n'a pas de sens d'un point de vue de la
scurit, et cela ne promet qu'une surcharge en terme de performance si possible. C'est uniquement fourni comme valeur par dfaut pour la compatibilit ascendante, et n'est pas recommand pour les dploiements de serveurs ncessitant de la scurit.

31.17.4. Utilisation des fichiers SSL


Tableau 31.2, Utilisation des fichiers SSL libpq/client rsume les fichiers lis la configuration de SSL sur le client.
Tableau 31.2. Utilisation des fichiers SSL libpq/client

Fichier

Contenu

Effet

~/.postgresql/postgresql.crt certificat client

requis par le serveur

~/.postgresql/postgresql.key cl prive du client

prouve le certificat client envoy par


l'utilisateur ; n'indique pas que le propritaire du certificat est de confiance

~/.postgresql/root.crt

autorit de confiance du certificat

vrifie que le certificat du serveur est sign par une autorit de confiance

~/.postgresql/root.crl

certificats rvoqus par les autorits

le certificat du serveur ne doit pas tre sur


cette liste

31.17.5. Initialisation de la bibliothque SSL


Si votre application initialise les bibliothques libssl et/ou libcrypto et que libpq est construit avec le support de SSL, vous
devez appeler la fonction PQinitOpenSSL pour indiquer libpq que les bibliothques libssl et/ou libcrypto ont t initialises par votre application, de faon ce que libpq n'initialise pas elle-aussi ces bibliothques. Voir
http://h71000.www7.hp.com/doc/83final/BA554_90007/ch04.html pour plus de dtails sur l'API SSL.

506

libpq - Bibliothque C

PQinitOpenSSL
Permet aux applications de slectionner les bibliothques de scurit initialiser.
void PQinitOpenSSL(int do_ssl, int do_crypto);
Quand do_ssl est diffrent de zro, libpq initialisera la bibliothque OpenSSL avant d'ouvrir une connexion la base de
donnes. Quand do_crypto est diffrent de zro, la bibliothque libcrypto sera initialise. Par dfaut (si PQinitOpenSSL n'est pas appel), les deux bibliothques sont initialises. Quand le support de SSL n'est pas intgr, cette fonction
est prsente mais ne fait rien.
Si votre application utilise et initialise soit OpenSSL soit libcrypto, vous devez appeler cette fonction avec des zros pour
les paramtres appropris avant d'ouvrir la premire connexion la base de donnes. De plus, assurez-vous que vous avez fait
cette initialisation avant d'ouvrir une connexion la base de donnes.
PQinitSSL
Permet aux applications de slectionner les bibliothques de scurit initialiser.
void PQinitSSL(int do_ssl);
Cette fonction est quivalent PQinitOpenSSL(do_ssl, do_ssl). C'est suffisant pour les applications qui initialisent
la fois OpenSSL etlibcrypto ou aucune des deux.
PQinitSSL est prsente depuis PostgreSQL 8.0, alors que PQinitOpenSSL a t ajoute dans PostgreSQL 8.4, donc
PQinitSSL peut tre prfre pour les applications qui ont besoin de fonctionner avec les anciennes versions de libpq.

31.18. Comportement des programmes threads


libpq est rentrante et sre avec les threads par dfaut. Vous pourriez avoir besoin d'utiliser des options de compilation supplmentaires en ligne lorsque vous compiler le code de votre application. Rfrez-vous aux documentations de votre systme pour savoir comment construire des applications actives au niveau thread ou recherchez PTHREAD_CFLAGS et PTHREAD_LIBS dans
src/Makefile.global. Cette fonction permet d'excuter des requtes sur le statut de libpq concernant les threads :
PQisthreadsafe
Renvoie le statut de sret des threads pour libpq library.
int PQisthreadsafe();
Renvoie 1 si libpq supporte les threads, 0 dans le cas contraire.
Une restriction : il ne doit pas y avoir deux tentatives de threads manipulant le mme objet PGconn la fois. En particulier, vous
ne pouvez pas lancer des commandes concurrentes partir de threads diffrents travers le mme objet de connexion (si vous
avez besoin de lancer des commandes concurrentes, utilisez plusieurs connexions).
Les objets PGresult sont en lecture seule aprs leur cration et, du coup, ils peuvent tre passs librement entre les threads. Les objets PGresult sont en lecture seule aprs leur cration et, du coup, ils peuvent tre passs librement entre les threads. Nanmoins, si
vous utilisez une des fonctions de modification d'un PGresult dcrites dans Section 31.10, Fonctions diverses ou Section 31.12, Systme d'vnements , vous devez aussi viter toute opration concurrente sur le mme PGresult.
Les fonctions obsoltes PQrequestCancel et PQoidStatus ne grent pas les threads et ne devraient pas tre utilises dans
des programmes multithread. PQrequestCancel peut tre remplac par PQcancel. PQoidStatus peut tre remplac par
PQoidValue.
Si vous utilisez Kerberos avec votre application (ainsi que dans libpq), vous aurez besoin de verrouiller les appels Kerberos car les
fonctions Kerberos ne sont pas sres lorsqu'elles sont utilises avec des threads. Voir la fonction PQregisterThreadLock
dans le code source de libpq pour rcuprer un moyen de faire un verrouillage coopratif entre libpq et votre application.
Si vous exprimentez des problmes avec les applications utilisant des threads, lancez le programme dans src/tools/thread
pour voir si votre plateforme des fonctions non compatibles avec les threads. Ce programme est lanc par configure mais,
dans le cas des distributions binaires, votre bibliothque pourrait ne pas correspondre la bibliothque utilise pour construire les
binaires.

507

libpq - Bibliothque C

31.19. Construire des applications avec libpq


Pour construire (c'est--dire compiler et lier) un programme utilisant libpq, vous avez besoin de faire tout ce qui suit :

Incluez le fichier d'en-tte libpq-fe.h :


#include <libpq-fe.h>
Si vous ne le faites pas, alors vous obtiendrez normalement les messages d'erreurs similaires ceci
foo.c: In
foo.c:34:
foo.c:35:
foo.c:54:
foo.c:68:
foo.c:95:

function `main':
`PGconn' undeclared (first use in this function)
`PGresult' undeclared (first use in this function)
`CONNECTION_BAD' undeclared (first use in this function)
`PGRES_COMMAND_OK' undeclared (first use in this function)
`PGRES_TUPLES_OK' undeclared (first use in this function)

Pointez votre compilateur sur le rpertoire o les fichiers d'en-tte de PostgreSQL ont t installs en fournissant l'option
-Irpertoire votre compilateur (dans certains cas, le compilateur cherchera dans le rpertoire en question par dfaut,
donc vous pouvez omettre cette option). Par exemple, votre ligne de commande de compilation devrait ressembler ceci :
cc -c -I/usr/local/pgsql/include testprog.c
Si vous utilisez des makefiles, alors ajoutez cette option la variable CPPFLAGS :
CPPFLAGS += -I/usr/local/pgsql/include
S'il existe une chance pour que votre programme soit compil par d'autres utilisateurs, alors vous ne devriez pas coder en dur
l'emplacement du rpertoire. la place, vous pouvez excuter l'outil pg_config pour trouver o sont placs les fichiers
d'en-tte sur le systme local :
$ pg_config --includedir
/usr/local/include
Un chec sur la spcification de la bonne option au compilateur rsultera en un message d'erreur tel que
testlibpq.c:8:22: libpq-fe.h: No such file or directory

Lors de l'dition des liens du programme final, spcifiez l'option -lpq de faon ce que les bibliothques libpq soient intgres, ainsi que l'option -Lrpertoire pour pointer le compilateur vers le rpertoire o les bibliothques libpq rsident (de
nouveau, le compilateur cherchera certains rpertoires par dfaut). Pour une portabilit maximale, placez l'option -L avant
l'option -lpq. Par exemple :
cc -o testprog testprog1.o testprog2.o -L/usr/local/pgsql/lib -lpq
Vous pouvez aussi rcuprer le rpertoire des bibliothques en utilisant pg_config :
$ pg_config --libdir
/usr/local/pgsql/lib
Les messages d'erreurs, pointant vers des problmes de ce style, pourraient ressembler ce qui suit.
testlibpq.o: In function
testlibpq.o(.text+0x60):
testlibpq.o(.text+0x71):
testlibpq.o(.text+0xa4):

`main':
undefined reference to `PQsetdbLogin'
undefined reference to `PQstatus'
undefined reference to `PQerrorMessage'

Ceci signifie que vous avez oubli -lpq.


/usr/bin/ld: cannot find -lpq
Ceci signifie que vous avez oubli l'option -L ou que vous n'avez pas indiqu le bon rpertoire.

31.20. Exemples de programmes


Ces exemples (et d'autres) sont disponibles dans le rpertoire src/test/examples de la distribution des sources.
Exemple 31.1. Premier exemple de programme pour libpq

508

libpq - Bibliothque C

/*
* testlibpq.c
*
*
Test the C version of libpq, the PostgreSQL frontend library.
*/
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
static void
exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int
main(int argc,
{
const char
PGconn
PGresult
int
int

char **argv)
*conninfo;
*conn;
*res;
nFields;
i,
j;

/*
* If the user supplies a parameter on the command line, use it as the
* conninfo string; otherwise default to setting dbname=postgres and using
* environment variables or defaults for all other connection parameters.
*/
if (argc > 1)
conninfo = argv[1];
else
conninfo = "dbname = postgres";
/* Make a connection to the database */
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
exit_nicely(conn);
}
/*
* Our test case here involves using a cursor, for which we must be inside
* a transaction block. We could do the whole thing with a single
* PQexec() of "select * from pg_database", but that's too trivial to make
* a good example.
*/
/* Start a transaction block */
res = PQexec(conn, "BEGIN");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
/*
* Should PQclear PGresult whenever it is no longer needed to avoid memory
* leaks
*/
PQclear(res);

509

libpq - Bibliothque C

/*
* Fetch rows from pg_database, the system catalog of databases
*/
res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
res = PQexec(conn, "FETCH ALL in myportal");
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
/* first, print out the attribute names */
nFields = PQnfields(res);
for (i = 0; i < nFields; i++)
printf("%-15s", PQfname(res, i));
printf("\n\n");
/* next, print out the rows */
for (i = 0; i < PQntuples(res); i++)
{
for (j = 0; j < nFields; j++)
printf("%-15s", PQgetvalue(res, i, j));
printf("\n");
}
PQclear(res);
/* close the portal ... we don't bother to check for errors ... */
res = PQexec(conn, "CLOSE myportal");
PQclear(res);
/* end the transaction */
res = PQexec(conn, "END");
PQclear(res);
/* close the connection to the database and cleanup */
PQfinish(conn);
return 0;
}

Exemple 31.2. Deuxime exemple de programme pour libpq

/*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

testlibpq2.c
Test of the asynchronous notification interface
Start this program, then from psql in another window do
NOTIFY TBL2;
Repeat four times to get this program to exit.
Or, if you want to get fancy, try this:
populate a database with the following commands
(provided in src/test/examples/testlibpq2.sql):
CREATE TABLE TBL1 (i int4);
CREATE TABLE TBL2 (i int4);
510

libpq - Bibliothque C

*
*
CREATE RULE r1 AS ON INSERT TO TBL1 DO
*
(INSERT INTO TBL2 VALUES (new.i); NOTIFY TBL2);
*
* and do this four times:
*
*
INSERT INTO TBL1 VALUES (10);
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <libpq-fe.h>
static void
exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int
main(int argc,
{
const char
PGconn
PGresult
PGnotify
int

char **argv)
*conninfo;
*conn;
*res;
*notify;
nnotifies;

/*
* If the user supplies a parameter on the command line, use it as the
* conninfo string; otherwise default to setting dbname=postgres and using
* environment variables or defaults for all other connection parameters.
*/
if (argc > 1)
conninfo = argv[1];
else
conninfo = "dbname = postgres";
/* Make a connection to the database */
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
exit_nicely(conn);
}
/*
* Issue LISTEN command to enable notifications from the rule's NOTIFY.
*/
res = PQexec(conn, "LISTEN TBL2");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
/*
* should PQclear PGresult whenever it is no longer needed to avoid memory
* leaks
*/
PQclear(res);

511

libpq - Bibliothque C

/* Quit after four notifies are received. */


nnotifies = 0;
while (nnotifies < 4)
{
/*
* Sleep until something happens on the connection. We use select(2)
* to wait for input, but you could also use poll() or similar
* facilities.
*/
int
sock;
fd_set
input_mask;
sock = PQsocket(conn);
if (sock < 0)
break;

/* shouldn't happen */

FD_ZERO(&input_mask);
FD_SET(sock, &input_mask);
if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0)
{
fprintf(stderr, "select() failed: %s\n", strerror(errno));
exit_nicely(conn);
}
/* Now check for input */
PQconsumeInput(conn);
while ((notify = PQnotifies(conn)) != NULL)
{
fprintf(stderr,
"ASYNC NOTIFY of '%s' received from backend PID %d\n",
notify->relname, notify->be_pid);
PQfreemem(notify);
nnotifies++;
}
}
fprintf(stderr, "Done.\n");
/* close the connection to the database and cleanup */
PQfinish(conn);
return 0;
}

Exemple 31.3. Troisime exemple de programme pour libpq

/*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

testlibpq3.c
Test out-of-line parameters and binary I/O.
Before running this, populate a database with the following commands
(provided in src/test/examples/testlibpq3.sql):
CREATE TABLE test1 (i int4, t text, b bytea);
INSERT INTO test1 values (1, 'joe''s place', '\\000\\001\\002\\003\\004');
INSERT INTO test1 values (2, 'ho there', '\\004\\003\\002\\001\\000');
The expected output is:
tuple 0: got
i = (4 bytes) 1
t = (11 bytes) 'joe's place'
b = (5 bytes) \000\001\002\003\004

512

libpq - Bibliothque C

* tuple 0: got
* i = (4 bytes) 2
* t = (8 bytes) 'ho there'
* b = (5 bytes) \004\003\002\001\000
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <libpq-fe.h>
/* for ntohl/htonl */
#include <netinet/in.h>
#include <arpa/inet.h>
static void
exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
/*
* This function prints a query result that is a binary-format fetch from
* a table defined as in the comment above. We split it out because the
* main() function uses it twice.
*/
static void
show_binary_results(PGresult *res)
{
int
i,
j;
int
i_fnum,
t_fnum,
b_fnum;
/* Use
i_fnum
t_fnum
b_fnum

PQfnumber to avoid assumptions about field order in result */


= PQfnumber(res, "i");
= PQfnumber(res, "t");
= PQfnumber(res, "b");

for (i = 0; i < PQntuples(res); i++)


{
char
*iptr;
char
*tptr;
char
*bptr;
int
blen;
int
ival;
/* Get
iptr =
tptr =
bptr =

the field values (we ignore possibility they are null!) */


PQgetvalue(res, i, i_fnum);
PQgetvalue(res, i, t_fnum);
PQgetvalue(res, i, b_fnum);

/*
* The binary representation of INT4 is in network byte order, which
* we'd better coerce to the local byte order.
*/
ival = ntohl(*((uint32_t *) iptr));
/*
* The binary representation
* was nice enough to append
* as a C string.
*
* The binary representation
* include embedded nulls so
*/

of TEXT is, well, text, and since libpq


a zero byte to it, it'll work just fine
of BYTEA is a bunch of bytes, which could
we have to pay attention to field length.

513

libpq - Bibliothque C

blen = PQgetlength(res, i, b_fnum);


printf("tuple %d: got\n", i);
printf(" i = (%d bytes) %d\n",
PQgetlength(res, i, i_fnum), ival);
printf(" t = (%d bytes) '%s'\n",
PQgetlength(res, i, t_fnum), tptr);
printf(" b = (%d bytes) ", blen);
for (j = 0; j < blen; j++)
printf("\\%03o", bptr[j]);
printf("\n\n");
}
}
int
main(int argc,
{
const char
PGconn
PGresult
const char
int
int
uint32_t

char **argv)
*conninfo;
*conn;
*res;
*paramValues[1];
paramLengths[1];
paramFormats[1];
binaryIntVal;

/*
* If the user supplies a parameter on the command line, use it as the
* conninfo string; otherwise default to setting dbname=postgres and using
* environment variables or defaults for all other connection parameters.
*/
if (argc > 1)
conninfo = argv[1];
else
conninfo = "dbname = postgres";
/* Make a connection to the database */
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
exit_nicely(conn);
}
/*
* The point of this program is to illustrate use of PQexecParams() with
* out-of-line parameters, as well as binary transmission of data.
*
* This first example transmits the parameters as text, but receives the
* results in binary format. By using out-of-line parameters we can
* avoid a lot of tedious mucking about with quoting and escaping, even
* though the data is text. Notice how we don't have to do anything
* special with the quote mark in the parameter value.
*/
/* Here is our out-of-line parameter value */
paramValues[0] = "joe's place";
res = PQexecParams(conn,
"SELECT * FROM test1 WHERE t = $1",
1,
/* one param */
NULL,
/* let the backend deduce param type */
paramValues,
NULL,
/* don't need param lengths since text */
NULL,
/* default to all text params */
1);
/* ask for binary results */

514

libpq - Bibliothque C

if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
show_binary_results(res);
PQclear(res);
/*
* In this second example we transmit an integer parameter in binary
* form, and again retrieve the results in binary form.
*
* Although we tell PQexecParams we are letting the backend deduce
* parameter type, we really force the decision by casting the parameter
* symbol in the query text. This is a good safety measure when sending
* binary parameters.
*/
/* Convert integer value "2" to network byte order */
binaryIntVal = htonl((uint32_t) 2);
/* Set up parameter arrays for PQexecParams */
paramValues[0] = (char *) &binaryIntVal;
paramLengths[0] = sizeof(binaryIntVal);
paramFormats[0] = 1;
/* binary */
res = PQexecParams(conn,
"SELECT * FROM test1 WHERE i = $1::int4",
1,
/* one param */
NULL,
/* let the backend deduce param type */
paramValues,
paramLengths,
paramFormats,
1);
/* ask for binary results */
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
show_binary_results(res);
PQclear(res);
/* close the connection to the database and cleanup */
PQfinish(conn);
return 0;
}

515

Chapitre 32. Objets larges


PostgreSQL a des fonctionnalits concernant les objets larges, fournissant un accs style flux aux donnes utilisateurs stockes dans une structure spciale. L'accs en flux est utile pour travailler avec des valeurs de donnes trop larges pour tre manipuler convenablement en entier.
Ce chapitre dcrit l'implmentation, la programmation et les interfaces du langage de requtes pour les donnes de type objet
large dans PostgreSQL. Nous utilisons la bibliothque C libpq pour les exemples de ce chapitre mais la plupart des interfaces
natives de programmation de PostgreSQL supportent des fonctionnalits quivalentes. D'autres interfaces pourraient utiliser
l'interface des objets larges en interne pour fournir un support gnrique des valeurs larges. Ceci n'est pas dcrit ici.

32.1. Introduction
Tous les objets larges sont placs dans une seule table systme appele pg_largeobject. PostgreSQL supporte aussi un
systme de stockage appel TOAST qui stocke automatiquement les valeurs ne tenant pas sur une page de la base de donnes dans une aire de stockage secondaire par table. Ceci rend partiellement obsolte la fonctionnalit des objets larges. Un
avantage restant des objets larges est qu'il autorise les valeurs de plus de 2 Go en taille alors que les champs TOAST peuvent
tre d'au plus 1 Go. Nanmoins, les objets larges peuvent tre modifis au hasard en utilisant une API de lecture/criture qui est
plus efficace que la ralisation de telles oprations utilisant TOAST.

32.2. Fonctionnalits d'implmentation


L'implmentation des objets larges, les coupe en morceaux (chunks) stocks dans les lignes de la base de donnes. Un index
B-tree garantit des recherches rapides sur le numro du morceau lors d'accs alatoires en lecture et criture.
partir de PostgreSQL 9.0, les Large Objects ont un propritaire et un ensemble de droits d'accs pouvant tre grs en
utilisant les commandes GRANT(7) et REVOKE(7). Pour une compatibilit avec des versions prcdentes, voir
lo_compat_privileges. Les droits SELECT sont requis pour lire un Large Object , et les droits UPDATE sont requis pour
crire ou tronquer. Seul le propritaire du Large Object ou le propritaire de la base de donnes peut supprimer, ajouter un
commentaire ou modifier le propritaire d'un Large Object .

32.3. Interfaces client


Cette section dcrit les possibilits que les bibliothques d'interfaces clientes de PostgreSQL fournissent pour accder aux objets larges. Toutes les manipulations d'objets larges utilisant ces fonctions doivent prendre place dans un bloc de transaction
SQL. L'interface des objets larges de PostgreSQL prend comme modle l'interface des systmes de fichiers Unix avec des
fonctions analogues pour open, read, write, lseek, etc.
Les applications clientes utilisant l'interface des objets larges dans libpq doivent inclure le fichier d'en-tte libpq/
libpq-fs.h et tablir un lien avec la bibliothque libpq.

32.3.1. Crer un objet large


La fonction
Oid lo_creat(PGconn *conn, int mode);
cre un nouvel objet large. La valeur de retour est un OID assign au nouvel objet large ou InvalidOid (zro) en cas d'erreur.
mode est inutilise et ignore sur PostgreSQL 8.1 ; nanmoins, pour la compatibilit avec les anciennes versions, il est prfrable de l'initialiser INV_READ, INV_WRITE, ou INV_READ | INV_WRITE (ces constantes symboliques sont dfinies
dans le fichier d'en-tte libpq/libpq-fs.h).
Un exemple :
inv_oid = lo_creat(conn, INV_READ|INV_WRITE);
La fonction
Oid lo_create(PGconn *conn, Oid lobjId);
cre aussi un nouvel objet large. L'OID affecter peut tre spcifi par lobjId ; dans ce cas, un chec survient si l'OID est dj utilis pour un autre objet large. Si lobjId vaut InvalidOid (zero), alors lo_create affecte un OID inutilis (ceci est le
mme comportement que lo_creat). La valeur de retour est l'OID qui a t affect au nouvel objet large ou InvalidOid (zero)
en cas d'chec.
lo_create est nouveau depuis PostgreSQL 8.1 ; si cette fonction est utilise partir d'un serveur d'une version plus an516

Objets larges

cienne, elle chouera et renverra InvalidOid.


Un exemple :
inv_oid = lo_create(conn, desired_oid);

32.3.2. Importer un objet large


Pour importer un fichier du systme d'exploitation en tant qu'objet large, appelez
Oid lo_import(PGconn *conn, const char *filename);
filename spcifie le nom du fichier importer comme objet large. Le code de retour est l'OID assign au nouvel objet large ou
InvalidOid (zero) en cas d'chec. Notez que le fichier est lu par la bibliothque d'interface du client, pas par le serveur. Donc il
doit exister dans le systme de fichier du client et lisible par l'application du client.
La fonction
Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);
importe aussi un nouvel large object . L'OID affecter peut tre indiqu par lobjId ; dans ce cas, un chec survient si l'OID
est dj utilis pour un autre large object . Si lobjId vaut InvalidOid (zro) alors lo_import_with_oid affecte un OID
inutilis (et donc obtient ainsi le mme comportement que lo_import). La valeur de retour est l'OID qui a t affect au nouveau large object ou InvalidOid (zro) en cas d'chec.
lo_import_with_oid est une nouveaut de PostgreSQL 8.4, et utilise en interne lo_create qui tait une nouveaut de
la 8.1 ; si cette fonction est excute sur un serveur en 8.0 voire une version prcdente, elle chouera et renverra InvalidOid.

32.3.3. Exporter un objet large


Pour exporter un objet large en tant que fichier du systme d'exploitation, appelez
int lo_export(PGconn *conn, Oid lobjId, const char *filename);
L'argument lobjId spcifie l'OID de l'objet large exporter et l'argument filename spcifie le nom du fichier. Notez que le
fichier est crit par la bibliothque d'interface du client, pas par le serveur. Renvoie 1 en cas de succs, -1 en cas d'chec.

32.3.4. Ouvrir un objet large existant


Pour ouvrir un objet large existant pour lire ou crire, appelez
int lo_open(PGconn *conn, Oid lobjId, int mode);
L'argument lobjId spcifie l'OID de l'objet large ouvrir. Les bits mode contrlent si l'objet est ouvert en lecture
(INV_READ), criture (INV_WRITE) ou les deux (ces constantes symboliques sont dfinies dans le fichier d'en-tte libpq/
libpq-fs.h). Un objet large ne peut pas tre ouvert avant d'avoir t cr. lo_open renvoie un descripteur (positif) d'objet
large pour une utilisation future avec lo_read, lo_write, lo_lseek, lo_tell et lo_close. Le descripteur est uniquement valide pour la dure de la transaction en cours. En cas d'chec, -1 est renvoy.
Actuellement, le serveur ne fait pas de distinction entre les modes INV_WRITE et INV_READ | INV_WRITE : vous tes autoris lire partir du descripteur dans les deux cas. Nanmoins, il existe une diffrence significative entre ces modes et INV_READ
seul : avec INV_READ, vous ne pouvez pas crire sur le descripteur et la donne lue partir de ce dernier, refltera le contenu de
l'objet large au moment o lo_open a t excut dans la transaction active, quelques soient les possibles critures par cette transaction ou par d'autres. Lire partir d'un descripteur ouvert avec INV_WRITE renvoie des donnes refltant toutes les critures
des autres transactions valides ainsi que les critures de la transaction en cours. Ceci est similaire la diffrence de comportement entre les modes de transaction REPEATABLE READ et READ COMMITTED pour les requtes SQL SELECT.
Un exemple :
inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE);

32.3.5. crire des donnes dans un objet large


La fonction
int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
crit len octets de buf dans le descripteur fd de l'objet large. L'argument fd doit avoir t renvoy par un appel prcdent
lo_open. Le nombre d'octets rellement crits est renvoy. Dans le cas d'une erreur, une valeur ngative est renvoye.

517

Objets larges

32.3.6. Lire des donnes partir d'un objet large


La fonction
int lo_read(PGconn *conn, int fd, char *buf, size_t len);
lit len octets du descripteur de l'objet large fd et les place dans buf. L'argument fd doit avoir t renvoy par un appel prcdent lo_open. Le nombre d'octets rellement lus est renvoy. Dans le cas d'une erreur, une valeur ngative est renvoye.

32.3.7. Recherche dans un objet large


Pour modifier l'emplacement courant de lecture ou criture associ au descripteur d'un objet large, on utilise
int lo_lseek(PGconn *conn, int fd, int offset, int whence);
Cette fonction dplace le pointeur d'emplacement courant pour le descripteur de l'objet large identifi par fd au nouvel emplacement spcifi avec le dcalage (offset). Les valeurs valides pour whence sont SEEK_SET (rechercher depuis le dbut de
l'objet), SEEK_CUR (rechercher depuis la position courante) et SEEK_END (rechercher depuis la fin de l'objet). Le code de retour est le nouvel emplacement du pointeur ou -1 en cas d'erreur.

32.3.8. Obtenir la position de recherche d'un objet large


Pour obtenir la position actuelle de lecture ou criture d'un descripteur d'objet large, appelez
int lo_tell(PGconn *conn, int fd);
En cas d'erreur, le code de retour est ngatif.

32.3.9. Tronquer un Objet Large


Pour tronquer un objet large avec une longueur donne, on utilise
int lo_truncate(PGcon *conn, int fd, size_t len);
tronque l'objet large dcrit par fd avec la longueur len. l'argument fd doit avoir t renvoy par un appel prcdent lo_open.
Si le paramtre len est plus grand que la taille de l'objet courant, l'objet sera complet avec des octets de valeur null ('\0').
Le dcalage reste inchang.
En cas de succs lo_truncate retourne zero. En cas d'erreur, la valeur de retour est ngative.
lo_truncate est une nouveaut de PostgreSQL 8.3; si cette fonction est galement excut sur un version plus ancienne du
serveur, elle chouera et retournera une valeur ngative.

32.3.10. Fermer un descripteur d'objet large


Un descripteur d'objet large peut tre ferm en appelant
int lo_close(PGconn *conn, int fd);
o fd est un descripteur d'objet large renvoy par lo_open. En cas de succs, lo_close renvoie zro. Une valeur negative en
cas d'chec.
Tous les descripteurs d'objets larges restant ouverts la fin d'une transaction seront automatiquement ferms.

32.3.11. Supprimer un objet large


Pour supprimer un objet large de la base de donnes, on utilise
int lo_unlink(PGconn *conn, Oid lobjId);
L'argument lobjId spcifie l'OID de l'objet large supprimer. En cas d'erreur, le code de retour est ngatif.

32.4. Fonctions du ct serveur


Ce sont des fonctions ct serveur appelables partir de SQL et correspondant chaque fonction ct client dcrite ci-dessus ; en
fait, pour leur grande part, les fonctions ct client sont simplement des interfaces vers les fonctions quivalentes ct serveur.
Celles qui sont rellement utiles appeler via des commandes SQL sont lo_creat, lo_create, lo_unlink, lo_import
et lo_export. Voici des exemples de leur utilisation :
CREATE TABLE image (
518

Objets larges

nom
donnees

text,
oid

);
SELECT lo_creat(-1);

-- renvoie l'OID du nouvel objet large

SELECT lo_create(43213);

-- tente de crer l'objet large d'OID 43213

SELECT lo_unlink(173454);

-- supprime l'objet large d'OID 173454

INSERT INTO image (nom, donnees)


VALUES ('superbe image', lo_import('/etc/motd'));
INSERT INTO image (nom, donnees) -- identique ci-dessus, mais prcise l'OID
utiliser
VALUES ('superbe image', lo_import('/etc/motd', 68583));
SELECT lo_export(image.donnees, '/tmp/motd') FROM image
WHERE nom = 'superbe image';
Les fonctions lo_import et lo_export ct serveur se comportent considrablement diffremment de leurs analogues ct
client. Ces deux fonctions lisent et crivent des fichiers dans le systme de fichiers du serveur en utilisant les droits du propritaire
du serveur de base de donnes. Du coup, leur utilisation est restreinte aux superutilisateurs PostgreSQL. Au contraire des fonctions ct serveur, les fonctions d'import et d'export ct client lisent et crivent des fichiers dans le systme de fichiers du client
en utilisant les droits du programme client. Les fonctions ct client ne ncessitent pas le droit superutilisateur.
Les fonctionnalits de lo_read et lo_write sont aussi disponibles via les appels ct serveur mais les noms des fonctions ct serveur diffrent des interfaces ct client (elles n'ont pas les tirets bas). Vous devez appelez ces fonctions sous le nom de loread et de lowrite.

32.5. Programme d'exemple


L'Exemple 32.1, Exemple de programme sur les objets larges avec libpq est un programme d'exemple qui montre une utilisation de l'interface des objets larges avec libpq. Des parties de ce programme disposent de commentaires au bnfice de
l'utilisateur. Ce programme est aussi disponible dans la distribution des sources (src/test/examples/testlo.c).
Exemple 32.1. Exemple de programme sur les objets larges avec libpq

/*-------------------------------------------------------------*
* testlo.c-*
test utilisant des objets larges avec libpq
*
* Copyright (c) 1994, Regents of the University of California
*
*-------------------------------------------------------------*/
#include <stdio.h>
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
#define BUFSIZE

1024

/*
* importFile
*
importe le fichier "in_filename" dans la base de donnes
*
en tant qu'objet "lobjOid"
*
*/
Oid
importFile(PGconn *conn, char *filename)
{
Oid
lobjId;
int
lobj_fd;
char
buf[BUFSIZE];
int
nbytes,
tmp;
519

Objets larges

int

fd;

/*
* ouvre le fichier lire
*/
fd = open(filename, O_RDONLY, 0666);
if (fd < 0)
{
/* error */
fprintf(stderr, "can't open unix file %s\n", filename);
}
/*
* cre l'objet large
*/
lobjId = lo_creat(conn, INV_READ | INV_WRITE);
if (lobjId == 0)
fprintf(stderr, "can't create large object\n");
lobj_fd = lo_open(conn, lobjId, INV_WRITE);
/*
* lit le fichier Unix crit dans le fichier inversion
*/
while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
{
tmp = lo_write(conn, lobj_fd, buf, nbytes);
if (tmp < nbytes)
fprintf(stderr, "error while reading large object\n");
}
(void) close(fd);
(void) lo_close(conn, lobj_fd);
return lobjId;
}
void
pickout(PGconn *conn, Oid lobjId, int start, int len)
{
int
lobj_fd;
char
*buf;
int
nbytes;
int
nread;
lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd < 0)
{
fprintf(stderr, "can't open large object %d\n",
lobjId);
}
lo_lseek(conn, lobj_fd, start, SEEK_SET);
buf = malloc(len + 1);
nread = 0;
while (len - nread > 0)
{
nbytes = lo_read(conn, lobj_fd, buf, len - nread);
buf[nbytes] = ' ';
fprintf(stderr, ">>> %s";, buf);
nread += nbytes;
}
free(buf);
fprintf(stderr, "\n");
lo_close(conn, lobj_fd);
}
void
overwrite(PGconn *conn, Oid lobjId, int start, int len)
520

Objets larges

{
int
char
int
int
int

lobj_fd;
*buf;
nbytes;
nwritten;
i;

lobj_fd = lo_open(conn, lobjId, INV_WRITE);


if (lobj_fd < 0)
{
fprintf(stderr, "can't open large object %d\n",
lobjId);
}
lo_lseek(conn, lobj_fd, start, SEEK_SET);
buf = malloc(len + 1);
for (i = 0; i < len; i++)
buf[i] = 'X';
buf[i] = ' ';
nwritten = 0;
while (len - nwritten > 0)
{
nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
nwritten += nbytes;
}
free(buf);
fprintf(stderr, "\n");
lo_close(conn, lobj_fd);
}
/*
* exportFile
*
exporte l'objet large "lobjOid" dans le fichier
* "out_filename"
*
*/
void
exportFile(PGconn *conn, Oid lobjId, char *filename)
{
int
lobj_fd;
char
buf[BUFSIZE];
int
nbytes,
tmp;
int
fd;
/*
* ouvre l' objet large
*/
lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd < 0)
{
fprintf(stderr, "can't open large object %d\n",
lobjId);
}
/*
* ouvre le fichier crire
*/
fd = open(filename, O_CREAT | O_WRONLY, 0666);
if (fd < 0)
{
/* error */
fprintf(stderr, "can't open unix file %s\n",
filename);
}
/*
* lit partir du fichier inversion et crit dans le fichier Unix
521

Objets larges

*/
while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
{
tmp = write(fd, buf, nbytes);
if (tmp < nbytes)
{
fprintf(stderr, "error while writing %s\n",
filename);
}
}
(void) lo_close(conn, lobj_fd);
(void) close(fd);
return;
}
void
exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int
main(int argc, char **argv)
{
char
*in_filename,
*out_filename;
char
*database;
Oid
lobjOid;
PGconn
*conn;
PGresult
*res;
if (argc != 4)
{
fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
argv[0]);
exit(1);
}
database = argv[1];
in_filename = argv[2];
out_filename = argv[3];
/*
* initialise la connexion
*/
conn = PQsetdb(NULL, NULL, NULL, NULL, database);
/* check to see that the backend connection was successfully made */
if (PQstatus(conn) == CONNECTION_BAD)
{
fprintf(stderr, "Connection to database '%s' failed.\n", database);
fprintf(stderr, "%s", PQerrorMessage(conn));
exit_nicely(conn);
}
res = PQexec(conn, "begin");
PQclear(res);
/*

printf("importing file %s\n", in_filename);


lobjOid = importFile(conn, in_filename); */
lobjOid = lo_import(conn, in_filename);

/*
printf("as large object %d.\n", lobjOid);
printf("picking out bytes 1000-2000 of the large object\n");
pickout(conn, lobjOid, 1000, 1000);
522

Objets larges

printf("overwriting bytes 1000-2000 of the large object with X's\n");


overwrite(conn, lobjOid, 1000, 1000);
*/
/*

printf("exporting large object to file %s\n", out_filename);


exportFile(conn, lobjOid, out_filename); */
lo_export(conn, lobjOid, out_filename);
res = PQexec(conn, "end");
PQclear(res);
PQfinish(conn);
exit(0);

523

Chapitre 33. ECPG SQL embarqu en C


Ce chapitre dcrit le module de SQL embarqu pour PostgreSQL. Il a t crit par Linus Tolke (<linus@epact.se>) et
Michael Meskes (< meskes@postgresql.org>). Initialement, il a t crit pour fonctionner avec le C. Il fonctionne aussi
avec le C++, mais il ne reconnait pas encore toutes les syntaxes du C++.
Ce document est assez incomplet. Mais comme l'interface est standardise, des informations supplmentaires peuvent tre trouves dans beaucoup de documents sur le SQL.

33.1. Le Concept
Un programme SQL embarqu est compos de code crit dans un langage de programmation ordinaire, dans notre cas le C, mlang avec des commandes SQL dans des sections spcialement balises. Pour compiler le programme, le code source (*.pgc)
passe d'abord dans un prprocesseur pour SQL embarqu, qui le convertit en un programme C ordinaire (*.c), afin qu'il puisse
ensuite tre trait par un compilateur C. (Pour les dtails sur la compilation et l'dition de lien dynamique voyez Section 33.10,
Traiter des Programmes en SQL Embarqu ). Les applications ECPG converties appellent les fonctions de la librairie libpq
au travers de la librairie SQL embarque (ecpgli), et communique avec le server PostgreSQL au travers du protocole clientserveur normal.
Le SQL embarqu a des avantages par rapport aux autres mthodes de manipulation du SQL dans le code C. Premirement, il
s'occupe du laborieux passage d'information de et vers les variables de votre programme C. Deuximement, le code SQL du programme est vrifi la compilation au niveau syntaxique. Troisimement, le SQL embarqu en C est support par beaucoup
d'autres bases de donnes SQL. L'implmentation PostgreSQL est conue pour correspondre ce standard autant que possible, et il est habituellement possible de porter du SQL embarqu d'autres bases SQL vers PostgreSQL assez simplement.
Comme dj expliqu prcdemment, les programmes crits pour du SQL embarqu sont des programmes C normaux, avec du
code spcifique insr pour excuter des oprations lies la base de donnes. Ce code spcifique est toujours de la forme:
EXEC SQL ...;
Ces ordres prennent, syntaxiquement, la place d'un ordre SQL. En fonction de l'ordre lui-mme, ils peuvent apparatre au niveau
global ou l'intrieur d'une fonction. Les ordres SQL embarqus suivent les rgles habituelles de sensibilit la casse du code
SQL, et pas celles du C.
Les sections suivantes expliquent tous les ordres SQL embarqus.

33.2. Grer les Connexions la Base de Donnes


Cette section explique comment ouvrir, fermer, et changer de connexion la base.

33.2.1. Se Connecter au Serveur de Base de Donnes


On se connecte la base de donnes avec l'ordre suivant:
EXEC SQL CONNECT TO cible [AS nom-connexion] [USER nom-utilisateur];
La cible peut tre spcifie des faons suivantes:

nomdb[@nomhte][:port]

tcp:postgresql://nomhte[:port][/nomdb][?options]

unix:postgresql://nomhte[:port][/nomdb][?options]

une chaine SQL littrale contenant une des formes prcdentes

une rfrence une variable caractre contenant une des formes prcdentes (voyez les exemples)

DEFAULT

Si vous spcifiez la chaine de connection de faon littrale (c'est dire, pas par une rfrence une variable) et que vous ne mettez pas la valeur entre guillemets, alors les rgles d'insensibilit la casse du SQL normal sont appliques. Dans ce cas, vous
pouvez aussi mettre entre guillemets doubles chaue paramtre individuel sparment au besoin. En pratique, il y a probablement
moins de risques d'erreur utiliser une chane de caractres entre simples guillemets, ou une rfrence une variable. La cible
de connexion DEFAULT initie une connexion la base de donnes par dfaut avec l'utilisateur par dfaut. Il n'est pas ncessaire
de prciser sparment un nom d'utilisateur ou un nom de connexion dans ce cas.
524

ECPG SQL embarqu en C

Il y a aussi plusieurs faons de spcifier le nom de l'utilisateur:

nomutilisateur

nomutilisateur/motdepasse

nomutilisateur IDENTIFIED BY motdepasse

nomutilisateur USING motdepasse

Comme prcdemment, les paramtres nomutilisateur et motdepasse peuvent tre un identifiant SQL, une chane SQL
littrale, ou une rfrence une variable caractre.
Le nom-connexion est utilis pour grer plusieurs connexions dans un programme. Il peut tre omis si le programme n'utilise
qu'une connexion. La connexion la plus rcemment ouverte devient la connexion courante, qui est utilise par dfaut quand un
ordre SQL doit tre excut (voyez plus bas dans ce chapitre).
Voici quelques exemples d'ordres CONNECT:
EXEC SQL CONNECT TO mabase@sql.mondomaine.com;
EXEC SQL CONNECT TO unix:postgresql://sql.mondomaine.com/mabase AS maconnexion USER
john;
EXEC SQL BEGIN DECLARE SECTION;
const char *cible = "mabase@sql.mondomaine.com";
const char *utilisateur = "john";
EXEC SQL END DECLARE SECTION;
...
EXEC SQL CONNECT TO :cible USER :utilisateur;
La dernire forme utilie la variante dont on parlait prcdemment sous le nom de rfrence par variable. Vous verrez dans les sections finales comment des variables C peuvent tre utilises dans des ordres SQL quand vous les prfixez par deux-points.
Notez que le format de la cible de connexion n'est pas spcifi dans le standard SQL. Par consquent si vous voulez dvelopper
des applications portables, vous pourriez vouloir utiliser quelque chose ressemblant au dernier exemple pour encapsuler la cible de
connexion quelque part.

33.2.2. Choisir une connexion


Les ordres des programmes SQL embarqu sont par dfaut excuts dans la connexion courante, c'est dire la plus rcemment ouverte. Si une application a besoin de grer plusieurs connexions, alors il y a deux faons de le grer.
La premire solution est de choisir explicitement une connexion pour chaque ordre SQL, par exemple:
EXEC SQL AT nom-connexion SELECT ...;
Cette option est particulirement approprie si l'application a besoin d'alterner les accs plusieurs connexions.
Si votre application utilise plusieurs threads d'excution, ils ne peuvent pas utiliser une connexion simultanment. Vous devez soit
contrler explicitement l'accs la connexion (en utilisant des mutexes), ou utiliser une connexion pour chaque thread. Si chaque
thread utilise sa propre connexion, vous aurez besoin d'utiliser la clause AT pour spcifier quelle connexion le thread utilisera.
La seconde option est d'excuter un ordre pour changer de connexion courante. Cet ordre est:
EXEC SQL SET CONNECTION nom-connexion;
Cette option est particulirement pratique si de nombreux ordres doivent tre excuts sur la mme connexion. Elle n'est pas locale un thread.
Voici un programme exemple qui gre plusieurs connexions base de donnes:
#include <stdio.h>
EXEC SQL BEGIN DECLARE SECTION;
char nomdb[1024];
EXEC SQL END DECLARE SECTION;
int
525

ECPG SQL embarqu en C

main()
{
EXEC SQL CONNECT TO basetest1 AS con1 USER utilisateurtest;
EXEC SQL CONNECT TO basetest2 AS con2 USER utilisateurtest;
EXEC SQL CONNECT TO basetest3 AS con3 USER utilisateurtest;
/* Cette requte serait excut dans la dernire base ouverte "basetest3". */
EXEC SQL SELECT current_database() INTO :nomdb;
printf("courante=%s (devrait tre basetest3)\n", nomdb);
/* Utiliser "AT" pour excuter une requte dans "basetest2" */
EXEC SQL AT con2 SELECT current_database() INTO :nomdb;
printf("courante=%s (devrait tre basetest2)\n", nomdb);
/* Switch the courante connection to "basetest1". */
EXEC SQL SET CONNECTION con1;
EXEC SQL SELECT current_database() INTO :nomdb;
printf("courante=%s (devrait tre basetest1)\n", nomdb);
EXEC SQL DISCONNECT ALL;
return 0;
}
Cet exemple devrait produire cette sortie:
courante=basetest3 (devrait tre basetest3)
courante=basetest2 (devrait tre basetest2)
courante=basetest1 (sdevrait tre basetest1)

33.2.3. Fermer une Connexion


Pour fermer une connexion, utilisez l'ordre suivant:
EXEC SQL DISCONNECT [connexion];
La connexion peut tre spcifie des faons suivantes:

nom-connexion

DEFAULT

CURRENT

ALL

Si aucun nom de connexion n'est spcifi, la connexion courante est ferme.


C'est une bonne pratique qu'une application ferme toujours explicitement toute connexion qu'elle a ouverte.

33.3. Excuter des Commandes SQL


Toute commande SQL peut tre excute l'intrieur d'une application SQL embarque. Voici quelques exemples montrant comment le faire.

33.3.1. Excuter des Ordres SQL


Crer une table:
EXEC SQL CREATE TABLE truc (nombre integer, ascii char(16));
EXEC SQL CREATE UNIQUE INDEX num1 ON truc(nombre);
EXEC SQL COMMIT;
Inserting rows:
EXEC SQL INSERT INTO truc (nombre, ascii) VALUES (9999, 'doodad');
526

ECPG SQL embarqu en C

EXEC SQL COMMIT;


Deleting rows:
EXEC SQL DELETE FROM truc WHERE nombre = 9999;
EXEC SQL COMMIT;
Updates:
EXEC SQL UPDATE truc
SET ascii = 'trucmachin'
WHERE nombre = 9999;
EXEC SQL COMMIT;
Les ordres SELECT qui retournent un seul enregistrement peuvent aussi tre excuts en utilisant EXEC SQL directement. Pour
traiter des jeux de rsultats de plusieurs enregistrements, une application doit utiliser un curseur; voyez Section 33.3.2, Utiliser
des Curseurs plus bas. (Exceptionnellement, une application peut rcuprer plusieurs enregistrements en une seule fois dans une
variable hte tableau; voyez Section 33.4.4.3.1, Arrays .)
Select mono-ligne:
EXEC SQL SELECT truc INTO :trucmachin FROM table1 WHERE ascii = 'doodad';
De mme, un paramtre de configuration peut tre rcupr avec la commande SHOW:
EXEC SQL SHOW search_path INTO :var;
Les tokens de la forme :quelquechose sont des variables htes, c'est--dire qu'ils font rfrence des variables dans le programme C. Elles sont expliques dans Section 33.4, Utiliser des Variables Htes .

33.3.2. Utiliser des Curseurs


Pour rcuprer un rsultat contenant plusieurs enregistrements, une application doit dclarer un curseur et rcuprer chaque enregistrement de ce curseur. Les tapes pour dclarer un curseur sont les suivantes: dclarer le curseur, l'ouvrir, rcuprer un enregistrement partir du curseur, rpter, et finalement le fermer.
Select avec des curseurs:
EXEC SQL DECLARE truc_machin CURSOR FOR
SELECT nombre, ascii FROM foo
ORDER BY ascii;
EXEC SQL OPEN truc_machin;
EXEC SQL FETCH truc_machin INTO :TrucMachin, MachinChouette;
...
EXEC SQL CLOSE truc_machin;
EXEC SQL COMMIT;
Pour plus de dtails propos de la dclaration du curseur, voyez DECLARE, et voyez FETCH(7) pour le dtail de la commande
FETCH

Note
La commande DECLARE ne dclenche pas rellement l'envoi d'un ordre au serveur PostgreSQL. Le curseur est
ouvert dans le processus serveur (en utilisant la commande DECLARE) au moment o la commande OPEN est
excute.

33.3.3. Grer les Transactions


Dans le mode par dfaut, les ordres SQL ne sont valids que quand EXEC SQL COMMIT est envoye. L'interface SQL embarque supporte aussi l'auto-commit des transactions (de faon similaire au comportement de libpq) via l'option de ligne de commande -t d'ecpg (voyez ecpg(1)) ou par l'ordre EXEC SQL SET AUTOCOMMIT TO ON. En mode auto-commit, chaque commande est valide automatiquement sauf si elle se trouve dans un bloc explicite de transaction. Ce mode peut tre explicitement
527

ECPG SQL embarqu en C

dsactiv en utilisant EXEC SQL SET AUTOCOMMIT TO OFF.


Les commandes suivantes de gestion de transaction sont disponibles:
EXEC SQL COMMIT
Valider une transaction en cours.
EXEC SQL ROLLBACK
Annuler une transaction en cours.
EXEC SQL SET AUTOCOMMIT TO ON
Activer le mode auto-commit.
SET AUTOCOMMIT TO OFF
Dsactiver le mode auto-commit. C'est la valeur par dfaut.

33.3.4. Requtes prpares


Quand les valeurs passer un ordre SQL ne sont pas connues au moment de la compilation, ou que le mme ordre SQL va tre
utilis de nombreuses fois, les requtes prpares peuvent tre utiles.
L'ordre est prpar en utilisant la commande PREPARE. Pour les valeurs qui ne sont pas encore connues, utilisez le substitut
? :
EXEC SQL PREPARE stmt1 FROM "SELECT oid, datname FROM pg_database WHERE oid = ?";
Si un ordre retourne une seule ligne, l'application peut appeler EXECUTE aprs PREPARE pour excuter l'ordre, en fournissant les
vraies valeurs pour les substituts avec une clause USING:
EXEC SQL EXECUTE stmt1 INTO :dboid, :dbname USING 1;
Si un ordre retourne plusieurs enregistrements, l'application peut utiliser un curseur dclars en se servant d'une requte prpare.
Pour lier les paramtres d'entre, le curseur doit tre ouvert avec une clause USING:
EXEC SQL PREPARE stmt1 FROM "SELECT oid,datname FROM pg_database WHERE oid > ?";
EXEC SQL DECLARE foo_bar CURSOR FOR stmt1;
/* Quand la fin du jeu de rsultats est atteinte, sortir de la boucle while */
EXEC SQL WHENEVER NOT FOUND DO BREAK;
EXEC SQL OPEN foo_bar USING 100;
...
while (1)
{
EXEC SQL FETCH NEXT FROM foo_bar INTO :dboid, :dbname;
...
}
EXEC SQL CLOSE foo_bar;
Quand vous n'avez plus besoin de la requte prpare, vous devriez la dsallouer:
EXEC SQL DEALLOCATE PREPARE nom;
Pour plus de dtails sur PREPARE, voyez PREPARE. Voyez aussi Section 33.5, SQL Dynamique pour plus de dtails propos de l'utilisation des substituts et des paramtres d'entre.

33.4. Utiliser des Variables Htes


Dans Section 33.3, Excuter des Commandes SQL vous avez vu comment excuter des ordres SQL dans un programme SQL
embarqu. Certains de ces ordres n'ont utilis que des valeurs constantes et ne fournissaient pas de moyen pour insrer des valeurs
fournies par l'utilisateur dans des ordres ou pour permettre au programme de traiter les valeurs retournes par la requte. Ces types
d'ordres ne sont pas trs utiles dans des applications relles. Cette section explique en dtail comment faire passer des donnes
entre votre programme en C et les ordres SQL embarqus en utilisant un simple mcanisme appel variables htes. Dans un programme SQL embarqu nous considrons que les ordres SQL sont des invits dans le code du programme C qui est le langage
528

ECPG SQL embarqu en C

hte. Par consquent, les variables du programme C sont appeles variables htes.
Une autre faon d'changer des valeurs entre les serveurs PostgreSQL et les applications ECPG est l'utilisation de descripteurs
SQL, dcrits dans Section 33.7, Utiliser les Zones de Descripteur .

33.4.1. Overview
Passer des donnes entre le programme en C et les ordres SQL est particulirement simple en SQL embarqu. Plutt que d'avoir
un programme qui conne des donnes dans un ordre SQL, ce qui entrane des complications varies, comme protger correctement
la valeur, vous pouvez simplement crire le nom d'une variable C dans un ordre SQL, prfixe par un deux-points. Par exemple:
EXEC SQL INSERT INTO unetable VALUES (:v1, 'foo', :v2);
Cet ordre fait rfrence deux variables C appeles v1 et v2 et utilise aussi une chane SQL classique, pour montrer que vous
n'tes pas oblig de vous cantonner un type de donnes ou l'autre.
Cette faon d'insrer des variables C dans des ordres SQL fonctionne partout o une expression de valeur est attendue dans un
ordre SQL.

33.4.2. Sections Declare


Pour passer des donnes du programme la base, par exemple comme paramtres d'une requte, ou pour passer des donnes de la
base vers le programme, les variables C qui sont prvues pour contenir ces donnes doivent tre dclares dans des sections spcialement identifies, afin que le prprocesseur SQL embarqu puisse s'en rendre compte.
Cette section commence par:
EXEC SQL BEGIN DECLARE SECTION;
et se termine par:
EXEC SQL END DECLARE SECTION;
Entre ces lignes, il doit y avoir des dclarations de variables C normales, comme:
int
char

x = 4;
foo[16], bar[16];

Comme vous pouvez le voir, vous pouvez optionnellement assigner une valeur initiale une variable. La porte de la variable est
dtermine par l'endroit o se trouve la section de dclaration dans le programme. Vous pouvez aussi dclarer des variables avec
la syntaxe suivante, qui cre une section declare implicite:
EXEC SQL int i = 4;
Vous pouvez avoir autant de sections de dclaration que vous voulez dans un programme.
Ces dclarations sont aussi envoyes dans le fichier produit comme des variables C normales, il n'est donc pas ncessaire de les
dclarer une seconde fois. Les variables qui n'ont pas besoin d'tre utilises dans des commandes SQL peuvent tre dclares normalement l'extrieur de ces sections spciales.
La dfinition d'une structure ou d'un union doit aussi tre prsente dans une section DECLARE. Sinon, le prprocesseur ne peut pas
traiter ces types, puisuq'il n'en connait pas la dfinition.

33.4.3. Rcuprer des Rsultats de Requtes


Maintenant, vous devriez tre capable de passer des donnes gnres par votre programme dans une commande SQL. Mais comment rcuprer les rsultats d'une requte? cet effet, le SQL embarqu fournit certaines variantes spciales de commandes SELECT et FETCH habituelles. Ces commandes ont une clause spciale INTO qui spcifie dans quelles variables htes les valeurs
rcupres doivent tre stockes. SELECT est utilis pour une requte qui ne retourne qu'un seul enregistrement, et FETCH est
utilis pour une requte qui retourne plusieurs enregistrement, en utilisant un curseur.
Voici un exemple:
/*
* Avec cette table:
* CREATE TABLE test1 (a int, b varchar(50));
*/
529

ECPG SQL embarqu en C

EXEC SQL BEGIN DECLARE SECTION;


int v1;
VARCHAR v2;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL SELECT a, b INTO :v1, :v2 FROM test;
La clause INTO apparat entre la liste de slection et la clause FROM. Le nombre d'lments dans la liste SELECT et dans la liste
aprs INTO (aussi appele la liste cible) doivent tre gaux.
Voici un exemple utilisant la commande FETCH:
EXEC SQL BEGIN DECLARE SECTION;
int v1;
VARCHAR v2;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL DECLARE truc CURSOR FOR SELECT a, b FROM test;
...
do
{
...
EXEC SQL FETCH NEXT FROM truc INTO :v1, :v2;
...
} while (...);
Ici, la clause INTO apparat aprs toutes les clauses normales.

33.4.4. Correspondance de Type


Quand les applications ECPG changent des valeurs entre le serveur PostgreSQL et l'application C, comme quand elles rcuprent
des rsultats de requte venant du serveur, ou qu'elles excutent des ordres SQL avec des paramtres d'entre, les valeurs doivent
tre converties entre les types de donnes PostgreSQL et les types du language hte (ceux du langage C). Une des fonctionnalits
les plus importantes d'ECPG est qu'il s'occupe de cela automatiquement dans la plupart des cas.
De ce point de vue, il y a deux sortes de types de donnes: des types de donnes PostgreSQL simples, comme des integer et text,
qui peuvent tre lus et crits directement par l'application. Les autres types PostgreSQL, comme timestamp ou numeric ne peuvent
tre accds qu' travers des fonctions spciales de librairie; voyez Section 33.4.4.2, Accder des Types de Donnes Spciaux .
Tableau 33.1, Correspondance Entre les Types PostgreSQL et les Types de Variables C montre quels types de donnes de
PostgreSQL correspondent quels types C. Quand vous voulez envoyer ou recevoir une valeur d'un type PostgreSQL donn, vous
devriez dclarer une variable C du type C correspondant dans la section declare.
Tableau 33.1. Correspondance Entre les Types PostgreSQL et les Types de Variables C

type de donnes PostgreSQL

type de variable hte

smallint

short

integer

int

bigint

long long int

decimal

decimala

numeric

numericb

real

float

double precision

double

serial

int

bigserial

long long int


530

ECPG SQL embarqu en C

type de donnes PostgreSQL

type de variable hte

oid

unsigned int

character(n), varchar(n), text

char[n+1], VARCHAR[n+1]c

name

char[NAMEDATALEN]

timestamp

timestampd

interval

intervale

date

datef

boolean

boolg

Ce type ne peut tre accd qu' travers des fonctions spciales de librairie. Voyez Section 33.4.4.2, Accder des Types de Donnes Spciaux .
Ce type ne peut tre accd qu' travers des fonctions spciales de librairie. Voyez Section 33.4.4.2, Accder des Types de Donnes Spciaux .
c
dclar dans ecpglib.h
d
Ce type ne peut tre accd qu' travers des fonctions spciales de librairie. Voyez Section 33.4.4.2, Accder des Types de Donnes Spciaux .
e
Ce type ne peut tre accd qu' travers des fonctions spciales de librairie. Voyez Section 33.4.4.2, Accder des Types de Donnes Spciaux .
f
Ce type ne peut tre accd qu' travers des fonctions spciales de librairie. Voyez Section 33.4.4.2, Accder des Types de Donnes Spciaux .
g
dclar dans ecpglib.h si non natif
b

33.4.4.1. Manipuler des Chanes de Caractres


Pour manipuler des types chanes de caractres SQL, comme varchar et text, il y a deux faons de dclarer les variables htes.
Une faon est d'utiliser char[], un tableau de char, qui est la faon la plus habituelle de grer des donnes texte en C.
EXEC SQL BEGIN DECLARE SECTION;
char str[50];
EXEC SQL END DECLARE SECTION;
Notez que vous devez grer la longueur vous-mme. Si vous utilisez cette variable he comme variable cible d'une requte qui retourne une chane de plus de 49 caractres, un dbordement de tampon se produira. occurs.
L'autre faon est d'utiliser le type VARCHAR, qui est un type spcial fourni par ECPG. La dfinition d'un tableau de type VARCHAR est convertie dans un struct nomm pour chaque variable. Une dclaration comme:
VARCHAR var[180];
est convertie en:
struct varchar_var { int len; char arr[180]; } var;
Le membre arr contient la chane termine par un octet zro. Par consquent, la variable hte doit tre dclare avec la longueur incluant le terminateur de chane. Le membre len stocke la longueur de la chane stocke dans arr sans l'octet zro final.
Quand une variable hte est utilis comme entre pour une requte, si strlen et len sont diffrents, le plus petit est utilis.
VARCHAR peut tre crit en majuscule ou en minuscule, mais pas dans un mlange des deux.
Les variables htes char et VARCHAR peuvent aussi contenir des valeurs d'autres types SQL, qui seront stocks dans leur forme
chane.

33.4.4.2. Accder des Types de Donnes Spciaux


ECPG contient des types spciaux qui vous aident intragir facilement avec des types de donnes spciaux du serveur PostgreSQL. En particulier, sont supports les types numeric, decimal, date, timestamp, et interval. Ces types de donnes ne peuvent pas
tre mis de faon utile en correspondance avec des types primitifs du langage htes (tels que int, long long int, ou char[]), parce
qu'ils ont une structure interne complexe. Les applications manipulent ces types en dclarant des variables htes dans des types
spciaux et en y accdant avec des fonctions de la librairie pgtypes. La librairie pgtypes, dcrite en dtail dans Section 33.6,
Librairie pgtypes contient des fonctions de base pour traiter ces types, afin que vous n'ayez pas besoin d'envoyer une requte
au serveur SQL juste pour additionner un interval un timestamp par exemple.
Les sous-sections suivantes dcrivent ces types de donnes spciaux. Pour plus de dtails propos des fonctions de librairie pgtype, voyez Section 33.6, Librairie pgtypes .
33.4.4.2.1. timestamp, date

Voici une mthode pour manipuler des variables timestamp dans l'application hte ECPG.
Tout d'abord, le programme doit inclure le fichier d'en-tte pour le type timestamp:
531

ECPG SQL embarqu en C

#include <pgtypes_timestamp.h>
Puis, dclarez une variable hte comme type timestamp dans la section declare:
EXEC SQL BEGIN DECLARE SECTION;
timestamp ts;
EXEC SQL END DECLARE SECTION;
Et aprs avoir lu une valeur dans la variable hte, traitez la en utilisant les fonctions de la librairie pgtypes. Dans l'exemple qui
suit, la valeur timestamp est convertie sous forme texte (ASCII) avec la fonction PGTYPEStimestamp_to_asc():
EXEC SQL SELECT now()::timestamp INTO :ts;
printf("ts = %s\n", PGTYPEStimestamp_to_asc(ts));
Cet exemple affichere des rsultats de ce type:
ts = 2010-06-27 18:03:56.949343
Par ailleurs, le type DATE peut tre manipul de la mme faon. Le programme doit inclure pgtypes_date.h, dclarer une
variable hte comme tant du type date et convertir une valeur DATE dans sa forme texte en utilisant la fonction PGTYPESdate_to_asc(). Pour plus de dtails sur les fonctions de la librairie pgtypes, voyez Section 33.6, Librairie pgtypes .
33.4.4.2.2. interval

La manipulation du type interval est aussi similaire aux types timestamp et date. Il est ncessaire, par contre, d'allouer de la mmoire pour une valeur de type interval de faon explicite. Ou dit autrement, l'espace mmoire pour la variable doit tre alloue du
tas, et non de la pile.
Voici un programme de dmonstration:
#include <stdio.h>
#include <stdlib.h>
#include <pgtypes_interval.h>
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
interval *in;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb;
in = PGTYPESinterval_new();
EXEC SQL SELECT '1 min'::interval INTO :in;
printf("interval = %s\n", PGTYPESinterval_to_asc(in));
PGTYPESinterval_free(in);
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
return 0;
}
33.4.4.2.3. numeric, decimal

La manipulation des types numeric et decimal est similaire au type interval: elle requiert de dfinir d'un pointeur, d'allouer de la
mmoire sur le tas, et d'accder la variable au mouyen des fonctions de librairie pgtypes. Pour plus de dtails sur les fonctions de
la librairie pgtypes, voyez Section 33.6, Librairie pgtypes .
Aucune fonction n'est fournie spcifiquement pour le type decimal. Une application doit le convertir vers une variable numeric en
utilisant une fonction de la librairie pgtypes pour pouvoir le traiter.
Voici un programme montrant la manipulation des variables de type numeric et decimal.

532

ECPG SQL embarqu en C

#include <stdio.h>
#include <stdlib.h>
#include <pgtypes_numeric.h>
EXEC SQL WHENEVER SQLERROR STOP;
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
numeric *num;
numeric *num2;
decimal *dec;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb;
num = PGTYPESnumeric_new();
dec = PGTYPESdecimal_new();
EXEC SQL SELECT 12.345::numeric(4,2), 23.456::decimal(4,2) INTO :num, :dec;
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0));
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1));
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2));
/* Convertir le decimal en numeric pour montrer une valeur dcimale. */
num2 = PGTYPESnumeric_new();
PGTYPESnumeric_from_decimal(dec, num2);
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0));
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1));
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2));
PGTYPESnumeric_free(num2);
PGTYPESdecimal_free(dec);
PGTYPESnumeric_free(num);
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
return 0;
}

33.4.4.3. Variables Htes avec des Types Non-Primitifs


Vous pouvez aussi utiliser des tableaux, typedefs, structs et pointeurs comme variables htes.
33.4.4.3.1. Arrays

Il y a deux cas d'utilisations pour des tableaux comme variables htes. Le premier est une faon de stocker des chanes de texte
dans des char[] ou VARCHAR[], comme expliqu Section 33.4.4.1, Manipuler des Chanes de Caractres . Le second cas
d'utilisation est de rcuprer plusieurs enregistrements d'une requte sans utiliser de curseur. Sans un tableau, pour traiter le rsultat d'une requte de plusieurs lignes, il est ncessaire d'utiliser un curseur et la commande FETCH. Mais avec une variable hte de
type variable, plusieurs enregistrements peuvent tre rcuprs en une seule fois. La longueur du tableau doit tre dfinie pour
pouvoir recevoir tous les enregistrements d'un coup, sans quoi un buffer overflow se produira probablement.
Les exemples suivants parcourent la table systme pg_database et montrent tous les OIDs et noms des bases de donnes disponibles:
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
int dbid[8];
char dbname[8][16];
int i;
EXEC SQL END DECLARE SECTION;
533

ECPG SQL embarqu en C

memset(dbname, 0, sizeof(char)* 16 * 8);


memset(dbid, 0, sizeof(int) * 8);
EXEC SQL CONNECT TO testdb;
/* Rcuprer plusieurs enregistrements dans des tableaux d'un coup. */
EXEC SQL SELECT oid,datname INTO :dbid, :dbname FROM pg_database;
for (i = 0; i < 8; i++)
printf("oid=%d, dbname=%s\n", dbid[i], dbname[i]);
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
return 0;
}
Cet exemple affiche le rsultat suivant. (Les valeurs exactes dpendent de votre environnement.)
oid=1, dbname=template1
oid=11510, dbname=template0
oid=11511, dbname=postgres
oid=313780, dbname=testdb
oid=0, dbname=
oid=0, dbname=
oid=0, dbname=
33.4.4.3.2. Structures

Une structure dont les noms des membres correspondent aux noms de colonnes du rsultat d'une requte peut tre utilise pour rcuprer plusieurs colonnes d'un coup. La structure permet de grer plusieurs valeurs de colonnes dans une seule variable hte.
L'exemple suivant rcupre les OIDs, noms, et tailles des bases de donnes disponibles partir de la table systme
pg_database, et en utilisant la fonction pg_database_size(). Dans cet exemple, une variable structure dbinfo_t avec
des membres dont les noms correspondent chaque colonnes du rsultat du SELECT est utilise pour rcuprer une ligne de rsultat sans avoir besoin de mettre plusieurs variables htes dans l'ordre FETCH.
EXEC SQL BEGIN DECLARE SECTION;
typedef struct
{
int oid;
char datname[65];
long long int size;
} dbinfo_t;
dbinfo_t dbval;
EXEC SQL END DECLARE SECTION;
memset(&dbval, 0, sizeof(dbinfo_t));
EXEC SQL DECLARE cur1 CURSOR FOR SELECT oid, datname, pg_database_size(oid) AS size
FROM pg_database;
EXEC SQL OPEN cur1;
/* quand la fin du jeu de donnes est atteint, sortir de la boucle while */
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* Rcuprer plusieurs colonnes dans une structure. */
EXEC SQL FETCH FROM cur1 INTO :dbval;
/* Afficher les membres de la structure. */
printf("oid=%d, datname=%s, size=%lld\n", dbval.oid, dbval.datname,
dbval.size);
}
EXEC SQL CLOSE cur1;
534

ECPG SQL embarqu en C

Cet exemple montre le rsultat suivant. (Les valeurs exactes dpendent du contexte.)
oid=1, datname=template1, size=4324580
oid=11510, datname=template0, size=4243460
oid=11511, datname=postgres, size=4324580
oid=313780, datname=testdb, size=8183012
Les variables htes structures absorbent autant de colonnes que la structure a de champs. Des colonnes additionnelles peuvent
tre assignes d'autres variables htes. Par exemple, le programme ci-dessus pourrait tre restructur comme ceci, avec la variable size hors de la structure:
EXEC SQL BEGIN DECLARE SECTION;
typedef struct
{
int oid;
char datname[65];
} dbinfo_t;
dbinfo_t dbval;
long long int size;
EXEC SQL END DECLARE SECTION;
memset(&dbval, 0, sizeof(dbinfo_t));
EXEC SQL DECLARE cur1 CURSOR FOR SELECT oid, datname, pg_database_size(oid) AS size
FROM pg_database;
EXEC SQL OPEN cur1;
/* quand la fin du jeu de donnes est atteint, sortir de la boucle while */
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* Rcuprer plusieurs colonnes dans une structure. */
EXEC SQL FETCH FROM cur1 INTO :dbval, :size;
/* Afficher les membres de la structure. */
printf("oid=%d, datname=%s, size=%lld\n", dbval.oid, dbval.datname, size);
}
EXEC SQL CLOSE cur1;
33.4.4.3.3. Typedefs

Utilisez le mot cl typedef pour faire correspondre de nouveaux types aux types existants.
EXEC SQL BEGIN DECLARE SECTION;
typedef char mychartype[40];
typedef long serial_t;
EXEC SQL END DECLARE SECTION;
Notez que vous pourriez aussi utiliser:
EXEC SQL TYPE serial_t IS long;
Cette dclaration n'a pas besoin de faire partie d'une section declare.
33.4.4.3.4. Pointeurs

Vous pouvez dclarer des pointeurs vers les types les plus communs. Notez toutefois que vous ne pouvez pas utiliser des pointeurs
comme variables cibles de requtes sans auto-allocation. Voyez Section 33.7, Utiliser les Zones de Descripteur pour plus
d'information sur l'auto-allocation.
EXEC SQL BEGIN DECLARE SECTION;
535

ECPG SQL embarqu en C

int
*intp;
char **charp;
EXEC SQL END DECLARE SECTION;

33.4.5. Manipuler des Types de Donnes SQL Non-Primitives


Cette section contient des informations sur comment manipuler des types non-scalaires et des types de donnes dfinies au niveau
SQL par l'utilisateur dans des applications ECPG. Notez que c'est distinct de la manipulation des variables htes des types nonprimitifs, dcrits dans la section prcdente.

33.4.5.1. Tableaux
Les tableaux au niveau SQL ne sont pas supports directement dans ECPG. Il n'est pas possible de mettre simplement en correspondance un tableau SQL avec une variable hte de type tableau. Cela entranera un comportement indfini. Quelques contournements existent, toutefois.
Si une requte accde aux lments d'un tableau sparment, cela vite l'utilisation des tableaux dans ECPG. Dans ce cas, une variable hte avec un type qui peut tre mis en correspondance avec le type de l'lment devrait tre utilis. Par exemple, si le type
d'une colonne est un tableau d'integer, une variable hte de type int peut tre utilise. Par ailleurs, si le type de l'lment est varchar, ou text, une variable hte de type char[] ou VARCHAR[] peut tre utilise.
Voici un exemple. Prenez la table suivante:
CREATE TABLE t3 (
ii integer[]
);
testdb=> SELECT * FROM t3;
ii
------------{1,2,3,4,5}
(1 row)
Le programme de dmonstration suivant rcupre le 4me lment du tableau et le stocke dans une variable hte de type int: type
int:
EXEC SQL BEGIN DECLARE SECTION;
int ii;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[4] FROM t3;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH FROM cur1 INTO :ii ;
printf("ii=%d\n", ii);
}
EXEC SQL CLOSE cur1;
Cet exemple affiche le rsultat suivant:
ii=4
Pour mettre en correspondance de multiples lments de tableaux avec les multiples lments d'une variable hte tableau, chaque
lment du tableau doit tre gr sparment, par exemple; for example:
EXEC SQL BEGIN DECLARE SECTION;
int ii_a[8];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[1], ii[2], ii[3], ii[4] FROM t3;
EXEC SQL OPEN cur1;
536

ECPG SQL embarqu en C

EXEC SQL WHENEVER NOT FOUND DO BREAK;


while (1)
{
EXEC SQL FETCH FROM cur1 INTO :ii_a[0], :ii_a[1], :ii_a[2], :ii_a[3];
...
}
Notez nouveau que
EXEC SQL BEGIN DECLARE SECTION;
int ii_a[8];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii FROM t3;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* FAUX */
EXEC SQL FETCH FROM cur1 INTO :ii_a;
...
}
ne fonctionnerait pas correctement dans ce cas, parce que vous ne pouvez pas mettre en correspondance une colonne de type tableau et une variable hte de type tableau directement.
Un autre contournement possible est de stocker les tableaux dans leur forme de reprsentation texte dans des variables htes de
type char[] ou VARCHAR[]. Pour plus de dtails sur cette reprsentation, voyez Section 8.14.2, Saisie de valeurs de type tableau . Notez que cela implique que le tableau ne peut pas tre accd naturellement comme un tableau dans le programme hte
(sans traitement supplmentaire qui transforme la reprsentation texte).

33.4.5.2. Types Composite


Les types composite ne sont pas directement supports dans ECPG, mais un contournement simple est possible. Les contournements disponibles sont similaires ceux dcrits pour les tableaux ci-dessus: soit accder chaque attribut sparment, ou utiliser
la reprsentation externe en mode chane de caractres.
Pour les exemples suivants, soient les types et table suivants:
CREATE TYPE comp_t AS (intval integer, textval varchar(32));
CREATE TABLE t4 (compval comp_t);
INSERT INTO t4 VALUES ( (256, 'PostgreSQL') );
La solution la plus vidente est d'accder chaque attribut sparment. Le programme suivant rcupre les donnes de la table
exemple en slectionnant chaque attribut du type comp_t sparment:
EXEC SQL BEGIN DECLARE SECTION;
int intval;
varchar textval[33];
EXEC SQL END DECLARE SECTION;
/* Mettre chaque lment de la colonne de type composite dans la liste SELECT. */
EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* Rcuprer chaque lment du type de colonne composite dans des variables htes.
*/
EXEC SQL FETCH FROM cur1 INTO :intval, :textval;
printf("intval=%d, textval=%s\n", intval, textval.arr);
537

ECPG SQL embarqu en C

}
EXEC SQL CLOSE cur1;
Pour amliorer cet exemple, les variables htes qui vont stocker les valeurs dans la commande FETCH peuvent tre rassembles
sous forme de structure, voyez Section 33.4.4.3.2, Structures . Pour passer la structure, l'exemple peut-tre modifi comme ci
dessous. Les deux variables htes, intval et textval, deviennent membres de comp_t, et la structure est spcifie dans la
commande FETCH.
EXEC SQL BEGIN DECLARE SECTION;
typedef struct
{
int intval;
varchar textval[33];
} comp_t;
comp_t compval;
EXEC SQL END DECLARE SECTION;
/* Mettre chaque lment de la colonne de type composite dans la liste SELECT. */
EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* Mettre toutes les valeurs de la liste SELECT dans une structure. */
EXEC SQL FETCH FROM cur1 INTO :compval;
printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr);
}
EXEC SQL CLOSE cur1;
Bien qu'une structure soit utilise dans la commande FETCH, les noms d'attributs dans la clause SELECT sont spcifis un par
un. Cela peut tre amlior en utilisant un * pour demander tous les attributs de la valeur de type composite.
...
EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).* FROM t4;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* Mettre toutes les valeurs de la liste SELECT dans une structure. */
EXEC SQL FETCH FROM cur1 INTO :compval;
printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr);
}
...
De cette faon, les types composites peuvent tre mis en correspondance avec des structures de faon quasi transparentes, alors
qu'ECPG ne comprend pas lui-mme le type composite.
Et pour finir, il est aussi possible de stocker les valeurs de type composite dans leur reprsentation externe de type chane dans des
variables htes de type char[] ou VARCHAR[]. Mais de cette faon, il n'est pas facilement possible d'accder aux champs de la
valeur dans le programme hte.

33.4.5.3. Types de Base Dfinis par l'Utilisateur


Les nouveaux types de base dfinis par l'utilisateur ne sont pas directement supports par ECPG. Vous pouvez utiliser les reprsentations externes de type chane et les variables htes de type char[] ou VARCHAR[], et cette solution est en fait approprie et
suffisante pour de nombreux types.
Voici un exemple utilisant le type de donnes complex de l'exemple tir de Section 35.11, Types utilisateur . La reprsentation
externe sous forme de chane de ce type est (%lf,%lf), qui est dfinie dans les fonctions complex_in() et com538

ECPG SQL embarqu en C

plex_out(). L'exemple suivant insre les valeurs de type complexe (1,1) et (3,3) dans les colonnes a et b, et les slectionne partir de la table aprs cela.
EXEC SQL BEGIN DECLARE SECTION;
varchar a[64];
varchar b[64];
EXEC SQL END DECLARE SECTION;
EXEC SQL INSERT INTO test_complex VALUES ('(1,1)', '(3,3)');
EXEC SQL DECLARE cur1 CURSOR FOR SELECT a, b FROM test_complex;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH FROM cur1 INTO :a, :b;
printf("a=%s, b=%s\n", a.arr, b.arr);
}
EXEC SQL CLOSE cur1;
Cet exemple affiche le rsultat suivant:
a=(1,1), b=(3,3)
Un autre contournement est d'viter l'utilisation directe des types dfinis par l'utilisateur dans ECPG et la place crer une fonction ou un cast qui convertit entre le type dfini par l'utilisateur et un type primitif que ECPG peut traiter. Notez, toutefois, que les
conversions de types, particulirement les implicites, ne devraient tre introduits dans le systme de typage qu'avec la plus grande
prudence.
For example,
CREATE FUNCTION create_complex(r double, i double) RETURNS complex
LANGUAGE SQL
IMMUTABLE
AS $$ SELECT $1 * complex '(1,0')' + $2 * complex '(0,1)' $$;
After this definition, the following
EXEC SQL BEGIN DECLARE SECTION;
double a, b, c, d;
EXEC SQL END DECLARE SECTION;
a
b
c
d

=
=
=
=

1;
2;
3;
4;

EXEC SQL INSERT INTO test_complex VALUES (create_complex(:a, :b), create_complex(:c,


:d));
a le mme effet que
EXEC SQL INSERT INTO test_complex VALUES ('(1,2)', '(3,4)');

33.4.6. Indicateurs
Les exemples prcdents ne grent pas les valeurs nulles. En fait, les exemples de rcupration de donnes remonteront une erreur
si ils rcuprent une valeur nulle de la base. Pour tre capable de passer des valeurs nulles la base ou d'un rcuprer, vous devez
rajouter une seconde spcification de variable hte chaque variable hte contenant des donnes. Cette seconde variable est appele l'indicateur et contient un drapeau qui indique si le datum est null, dans quel cas la valeur de la vraie variable hte est ignore.
Voici un exemple qui gre la rcupration de valeurs nulles correctement:

539

ECPG SQL embarqu en C

EXEC SQL BEGIN DECLARE SECTION;


VARCHAR val;
int val_ind;
EXEC SQL END DECLARE SECTION:
...
EXEC SQL SELECT b INTO :val :val_ind FROM test1;
La variable indicateur val_ind sera zro si la valeur n'tait pas nulle, et sera ngative si la valeur tait nulle.
L'indicateur a une autre fonction: si la valeur de l'indicateur est positive, cela signifie que la valeur n'est pas nulle, mais qu'elle a
t tronque quand elle a t stocke dans la variable hte.
Si l'argument -r no_indicator est passe au prprocesseur ecpg, il fonction dans le mode no-indicator . En mode noindicator, si aucune variable indicator n'est spcifie, les valeurs nulles sont signales (en entre et en sortie) pour les types
chanes de caractre comme des chanes vides et pour les types integer comme la plus petite valeur possible pour le type (par
exempple, INT_MIN pour int).

33.5. SQL Dynamique


Frquemment, les ordres SQL particuliers qu'une application doit excuter sont connus au moment o l'application est crite. Dans
certains cas, par contre, les ordres SQL sont composs l'excution ou fournis par une source externe. Dans ces cas, vous ne pouvez pas embarquer les ordres SQL directement dans le code source C, mais il y a une fonctionnalit qui vous permet d'excuter
des ordres SQL que vous fournissez dans une variable de type chane.

33.5.1. Excuter des Ordres SQL Dynamiques sans Jeu de Donne


La faon la plus simple d'excuter un ordre SQL dynamique est d'utiliser la commande EXECUTE IMMEDIATE. Par exemple:
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "CREATE TABLE test1 (...);";
EXEC SQL END DECLARE SECTION;
EXEC SQL EXECUTE IMMEDIATE :stmt;
EXECUTE IMMEDIATE peut tre utilis pour des ordres SQL qui ne retournent pas de donnes (par exemple, LDD, INSERT,
UPDATE, DELETE). Vous ne pouvez pas excuter d'ordres qui ramnent des donnes (par exemple, SELECT) de cette faon.
La prochaine section dcrit comment le faire.

33.5.2. Excuter une Requte avec Des Paramtres d'Entre


Une faon plus puissante d'excuter des ordres SQL arbitraires est de les prparer une fois et d'excuter la requte prpare aussi
souvent que vous le souhaitez. Il est aussi possible de prparer une version gnralis d'une requte et d'ensuite en excuter des
versions spcifiques par substitution de paramtres. Quand vous prparez la requte, mettez des points d'interrogation o vous
voudrez substituer des paramtres ensuite. Par exemple:
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "INSERT INTO test1 VALUES(?, ?);";
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE mystmt FROM :stmt;
...
EXEC SQL EXECUTE mystmt USING 42, 'foobar';
Quand vous n'avez plus besoin de la requte prpare, vous devriez la dsallouer:
EXEC SQL DEALLOCATE PREPARE name;

33.5.3. Excuter une Requte avec un Jeu de Donnes


Pour excuter une requte SQL avec une seule ligne de rsultat, vous pouvez utiliser EXECUTE. Pour enregistrer le rsultat,
ajoutez une clause INTO.

540

ECPG SQL embarqu en C

EXEC SQL BEGIN DECLARE SECTION;


const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?";
int v1, v2;
VARCHAR v3[50];
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE mystmt FROM :stmt;
...
EXEC SQL EXECUTE mystmt INTO :v1, :v2, :v3 USING 37;
Une commande EXECUTE peut avoir une clause INTO, une clause USING, les deux, ou aucune.
Si une requte peut ramener plus d'un enregistrement, un curseur devrait tre utilis, comme dans l'exemple suivant. Voyez Section 33.3.2, Utiliser des Curseurs pour plus de dtails propos des curseurs.)
EXEC
char
char
char

SQL BEGIN DECLARE SECTION;


dbaname[128];
datname[128];
*stmt = "SELECT u.usename as dbaname, d.datname "
" FROM pg_database d, pg_user u "
" WHERE d.datdba = u.usesysid";
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb AS con1 USER testuser;
EXEC SQL PREPARE stmt1 FROM :stmt;
EXEC SQL DECLARE cursor1 CURSOR FOR stmt1;
EXEC SQL OPEN cursor1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH cursor1 INTO :dbaname,:datname;
printf("dbaname=%s, datname=%s\n", dbaname, datname);
}
EXEC SQL CLOSE cursor1;
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;

33.6. Librairie pgtypes


La librairie pgtypes met en correspondance les types de la base de donnes PostgreSQL avec des quivalents en C qui peuvent
tre utiliss dans des programmes en C. Elle fournit aussi des fonctions pour effectuer les calculs de base avec ces types en C, c'est
dire, sans l'aide du serveur PostgreSQL. Voyez l'exemple suivant:
EXEC SQL BEGIN DECLARE SECTION;
date date1;
timestamp ts1, tsout;
interval iv1;
char *out;
EXEC SQL END DECLARE SECTION;
PGTYPESdate_today(&date1);
EXEC SQL SELECT started, duration INTO :ts1, :iv1 FROM datetbl WHERE d=:date1;
PGTYPEStimestamp_add_interval(&ts1, &iv1, &tsout);
out = PGTYPEStimestamp_to_asc(&tsout);
printf("Started + duration: %s\n", out);
free(out);

33.6.1. Le TYpe numeric


541

ECPG SQL embarqu en C

Le type numeric permet de faire des calculs de prcision arbitraire. Voyez Section 8.1, Types numriques pour le type quivalent dans le serveur PostgreSQL. En raison de cette prcision arbitraire cette variable doit pouvoir s'tendre et se rduire dynamiquement. C'est pour cela que vous ne pouvez crer des variables numeric que sur le tas, en utilisant les fonctions PGTYPESnumeric_new et PGTYPESnumeric_free. Le type dcimal, qui est similaire mais de prcision limite, peut tre cr sur la
pile ou sur le tas.
Les fonctions suivantes peuvent tre utilises pour travailler avec le type numeric:
PGTYPESnumeric_new
Demander un pointeur vers une variable numrique nouvellement alloue.
numeric *PGTYPESnumeric_new(void);
PGTYPESnumeric_free
Dsallouer un type numrique, librer toute sa mmoire.
void PGTYPESnumeric_free(numeric *var);
PGTYPESnumeric_from_asc
Convertir un type numrique partir de sa notation chane.
numeric *PGTYPESnumeric_from_asc(char *str, char **endptr);
Les formats valides sont par exemple: -2, .794, +3.44, 592.49E07 or -32.84e-4. Si la valeur peut tre convertie correctement, un pointeur valide est retourn, sinon un pointeur NULL. l'heure actuelle ECPG traite toujours la chaine en entier, il n'est donc pas possible pour le moment de stocker l'adresse du premier caractre invalide dans *endptr. Vous pouvez
sans risque positionner endptr NULL.
PGTYPESnumeric_to_asc
Retourne un pointeur vers la chane alloue par malloc qui contient la reprsentation chane du type numrique num.
char *PGTYPESnumeric_to_asc(numeric *num, int dscale);
La valeur numrique sera affiche avec dscale chiffres dcimaux, et sera arrondie si ncessaire.
PGTYPESnumeric_add
Ajoute deux variables numriques une troisime.
int PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result);
La fonction additionne les variables var1 et var2 dans la variable rsultat result. La fonction retourne 0 en cas de succs
et -1 en cas d'erreur.
PGTYPESnumeric_sub
Soustrait deux variables numriques et retourne le rsultat dans une troisime.
int PGTYPESnumeric_sub(numeric *var1, numeric *var2, numeric *result);
La fonction soustrait la variable var2 de la variable var1. Le rsultat de l'opration est stock dans la variable result. La
fonction retourne 0 en cas de succs et -1 en cas d'erreur.
PGTYPESnumeric_mul
Multiplie deux valeurs numeric et retourne le rsultat dans une troisime.
int PGTYPESnumeric_mul(numeric *var1, numeric *var2, numeric *result);
La fonction multiplie la variable var2 de la variable var1. Le rsultat de l'opration est stock dans la variable result. La
fonction retourne 0 en cas de succs et -1 en cas d'erreur.
PGTYPESnumeric_div
Divise deux valeurs numeric et retourne le rsultat dans une troisime.
int PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result);
La fonction divise la variable var2 de la variable var1. Le rsultat de l'opration est stock dans la variable result. La
542

ECPG SQL embarqu en C

fonction retourne 0 en cas de succs et -1 en cas d'erreur.


PGTYPESnumeric_cmp
Compare deux variables numeric.
int PGTYPESnumeric_cmp(numeric *var1, numeric *var2)
Cette fonction compare deux variables numeric. En cas d'erreur, INT_MAX est retourn. En cas de russite, la fonction retourne un des trois rsultats suivants:

1, si var1 est plus grand que var2

-1, si var1 est plus petit que var2

0, si var1 et var2 sont gaux

PGTYPESnumeric_from_int
Convertit une variable int en variable numeric.
int PGTYPESnumeric_from_int(signed int int_val, numeric *var);
Cette fonction accepte une variable de type signed int et la stocke dans la variable numeric var. La fonction retourne 0 en cas
de russite, et -1 en cas d'chec.
PGTYPESnumeric_from_long
Convertit une variable long int en variable numeric.
int PGTYPESnumeric_from_long(signed long int long_val, numeric *var);
Cette fonction accepte une variable de type signed long int et la stocke dans la variable numeric var. La fonction retourne 0
en cas de russite, et -1 en cas d'chec.
PGTYPESnumeric_copy
Copie une variable numeric dans une autre.
int PGTYPESnumeric_copy(numeric *src, numeric *dst);
Cette fonction copie la valeur de la variable vers laquelle src pointe dans la variable vers laquelle dst. Elle retourne 0 en
cas de russite et -1 en cas d'chec.
PGTYPESnumeric_from_double
Convertit une variable de type double en variable numeric.
int

PGTYPESnumeric_from_double(double d, numeric *dst);

Cette fonction accepte une variable de type double et la stocke dans la variable numeric dst. La fonction retourne 0 en cas de
russite, et -1 en cas d'chec.
PGTYPESnumeric_to_double
Convertit une variable de type numeric en double.
int PGTYPESnumeric_to_double(numeric *nv, double *dp)
Cette fonction convertit la valeur numeric de la variable vers la quelle nv pointe vers la variable double vers laquelle dp
pointe. Elle retourne 0 en cas de russite et -1 en cas d'chec, les cas de dpassement de capacit inclus. En cas de dpassement, la variable globale errno sera positionne PGTYPES_NUM_OVERFLOW en plus.
PGTYPESnumeric_to_int
Convertit une variable de type numeric en int.
int PGTYPESnumeric_to_int(numeric *nv, int *ip);
Cette fonction convertit la valeur numeric de la variable vers la quelle nv pointe vers la variable int vers laquelle ip pointe.
Elle retourne 0 en cas de russite et -1 en cas d'chec, les cas de dpassement de capacit inclus. En cas de dpassement, la
variable globale errno sera positionne PGTYPES_NUM_OVERFLOW en plus.
PGTYPESnumeric_to_long
Convertit une variable de type numeric en long.
543

ECPG SQL embarqu en C

int PGTYPESnumeric_to_long(numeric *nv, long *lp);


Cette fonction convertit la valeur numeric de la variable vers la quelle nv pointe vers la variable long vers laquelle lp pointe.
Elle retourne 0 en cas de russite et -1 en cas d'chec, les cas de dpassement de capacit inclus. En cas de dpassement, la
variable globale errno sera positionne PGTYPES_NUM_OVERFLOW en plus. additionally.
PGTYPESnumeric_to_decimal
Convertit une variable de type numeric en decimal.
int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst);
Cette fonction convertit la valeur numeric de la variable vers la quelle src pointe vers la variable decimal vers laquelle dst
pointe. Elle retourne 0 en cas de russite et -1 en cas d'chec, les cas de dpassement de capacit inclus. En cas de dpassement, la variable globale errno sera positionne PGTYPES_NUM_OVERFLOW en plus.
PGTYPESnumeric_from_decimal
Convertit une variable de type decimal en numeric. Convert a variable of type decimal to numeric.
int PGTYPESnumeric_from_decimal(decimal *src, numeric *dst);
Cette fonction convertit la valeur decimal de la variable vers la quelle src pointe vers la variable numeric vers laquelle dst
pointe. Elle retourne 0 en cas de russite et -1 en cas d'chec. Comme le type decimal est implmente comme une version limite du type numeric, un dpassement ne peut pas se produire lors de cette conversion.

33.6.2. Le Type date


Le type date en C permet votre programme de traiter les donnes type type SQL date. Voyez Section 8.5, Types date/heure
pour le type quivalent du serveur PostgreSQL.
Les fonctions suivantes peuvent tre utilises pour travailler avec le type date:
PGTYPESdate_from_timestamp
Extraire la partie date d'un timestamp.
date PGTYPESdate_from_timestamp(timestamp dt);
Cette fonction reoit un timestamp comme seul argument et retourne la partie date extraite de ce timestamp.
PGTYPESdate_from_asc
Convertit une date partir de sa reprsentation textuelle.
date PGTYPESdate_from_asc(char *str, char **endptr);
Cette fonction reoit une chane char* C str et un pointeur vers une chane char* C endptr. l'heure actuelle ECPG traite
toujours intgralement la chane, et ne supporte donc pas encore l'adresse du premier caractre invalide dans *endptr. Vous
pouvez positionner endptr NULL sans risque.
Notez que la fonction attend toujours une date au format MDY et qu'il n'y a aucune variable l'heure actuelle pour changer
cela dans ECPG.
Tableau 33.2, Formats d'Entre Valides pour PGTYPESdate_from_asc shows the allowed input formats.
Tableau 33.2. Formats d'Entre Valides pour PGTYPESdate_from_asc

Entre

Sortie

January 8, 1999

January 8, 1999

1999-01-08

January 8, 1999

1/8/1999

January 8, 1999

1/18/1999

January 18, 1999

01/02/03

February 1, 2003

1999-Jan-08

January 8, 1999

Jan-08-1999

January 8, 1999
544

ECPG SQL embarqu en C

Entre

Sortie

08-Jan-1999

January 8, 1999

99-Jan-08

January 8, 1999

08-Jan-99

January 8, 1999

08-Jan-06

January 8, 2006

Jan-08-99

January 8, 1999

19990108

ISO 8601; January 8, 1999

990108

ISO 8601; January 8, 1999

1999.008

year and day of year

J2451187

Julian day

January 8, 99 BC

year 99 before the Common Era

PGTYPESdate_to_asc
Retourne la reprsentation textuelle d'une variable date.
char *PGTYPESdate_to_asc(date dDate);
La fonction reoit la date dDate comme unique paramtre. Elle retournera la date dans la forme 1999-01-18, c'est--dire
le format YYYY-MM-DD.
PGTYPESdate_julmdy
Extrait les valeurs pour le jour, le mois et l'anne d'une variable de type date.
void PGTYPESdate_julmdy(date d, int *mdy);
La fonction reoit la date d et un pointeur vers un tableau de 3 valeurs entires mdy. Le nom de variable indique l'ordre squentiel: mdy[0] contiendra le numro du mois, mdy[1] contiendra le numro du jour et mdy[2] contiendra l'anne.
PGTYPESdate_mdyjul
Cre une valeur date partir d'un tableau de 3 entiers qui spcifient le jour, le mois et l'anne de la date.
void PGTYPESdate_mdyjul(int *mdy, date *jdate);
Cette fonction reoit le tableau des 3 entiers (mdy) comme premier argument, et son second argument est un pointeur vers la
variable de type date devant contenir le rsultat de l'opration.
PGTYPESdate_dayofweek
Retourne un nombre reprsentant le jour de la semaine pour une valeur date.
int PGTYPESdate_dayofweek(date d);
La fonction reoit la variable date d comme seul argument et retourne un entier qui indique le jour de la semaine pour cette
date. this date.

0 - Dimanche

1 - Lundi

2 - Mardi

3 - Mercredi

4 - Jeudi

5 - Vendredi

6 - Samedi

PGTYPESdate_today
Rcuprer la date courante.
void PGTYPESdate_today(date *d);
545

ECPG SQL embarqu en C

Cette fonction reoin un pointeur vers une variable date (d) qu'il positionne la date courante.
PGTYPESdate_fmt_asc
Converir une variable de type date vers sa reprsentation textuelle en utilisant un masque de formatage.
int PGTYPESdate_fmt_asc(date dDate, char *fmtstring, char *outbuf);
La fonction reoit la date convertir (dDate), le masque de formatage (fmtstring) et la chane qui contiendra la reprsentation textuelle de la date (outbuf).
En cas de succs, 0 est retourn, et une valeur ngative si une erreur s'est produite.
Les littraux suivants sont les spcificateurs de champs que vous pouvez utiliser:

dd - Le numro du jour du mois.

mm - Le numro du mois de l'anne.

yy - Le numro de l'anne comme nombre deux chiffres.

yyyy - Le numro de l'anne comme nombre quatre chiffres.

ddd - Le nom du jour (abrg).

mmm - Le nom du mois (abrg).

Tout autre caractre est recopi tel quel dans la chane de sortie.
Tableau 33.3, Formats d'Entre Valides pour PGTYPESdate_fmt_asc indique quelques formats possibles. Cela vous
donnera une ide de comment utiliser cette fonction. Toutes les lignes de sortie reposent sur la mme date: Le 23 novembre
1959.
Tableau 33.3. Formats d'Entre Valides pour PGTYPESdate_fmt_asc

Format

Rsultat

mmddyy

112359

ddmmyy

231159

yymmdd

591123

yy/mm/dd

59/11/23

yy mm dd

59 11 23

yy.mm.dd

59.11.23

.mm.yyyy.dd.

.11.1959.23.

mmm. dd, yyyy

Nov. 23, 1959

mmm dd yyyy

Nov 23 1959

yyyy dd mm

1959 23 11

ddd, mmm. dd, yyyy

Mon, Nov. 23, 1959

(ddd) mmm. dd, yyyy

(Mon) Nov. 23, 1959

PGTYPESdate_defmt_asc
Utiliser un masque de formatage pour convertir une chane de caractre char* en une valeur de type date.
int PGTYPESdate_defmt_asc(date *d, char *fmt, char *str);
La fonction reoit un pointeur vers la valeur de date qui devrait stocker le rsultat de l'opration (d), le masque de formatage
utiliser pour traiter la date (fmt) et la chane de caractres char* C contenant la reprsentation textuelle de la date (str). La
reprsentation textuelle doit correspondre au masque de formatage. Toutefois, vous n'avez pas besoin d'avoir une correspondance exacte entre la chane et le masque de formatage. La fonction n'analyse qu'en ordre squentiel et cherche les litraux yy
ou yyyy qui indiquent la position de l'anne, mm qui indique la position du mois et dd qui indique la position du jour.
Tableau 33.4, Formats d'Entre Valides pour rdefmtdate indique quelques formats possibles. Cela vous donnera une
ide de comment utiliser cette fonction
546

ECPG SQL embarqu en C

Tableau 33.4. Formats d'Entre Valides pour rdefmtdate

Format

Chane

Rsultat

ddmmyy

21-2-54

1954-02-21

ddmmyy

2-12-54

1954-12-02

ddmmyy

20111954

1954-11-20

ddmmyy

130464

1964-04-13

mmm.dd.yyyy

MAR-12-1967

1967-03-12

yy/mm/dd

1954, February 3rd

1954-02-03

mmm.dd.yyyy

041269

1969-04-12

yy/mm/dd

In the year 2525, in the 2525-07-28


month of July, mankind will
be alive on the 28th day

dd-mm-yy

I said on the 28th of July 2525-07-28


in the year 2525

mmm.dd.yyyy

9/14/58

1958-09-14

yy/mm/dd

47/03/29

1947-03-29

mmm.dd.yyyy

oct 28 1975

1975-10-28

mmddyy

Nov 14th, 1985

1985-11-14

33.6.3. Le Type timestamp


Le type timestamp en C permet vos programmes de manipuler les donnes du type SQL timestamp. Voyez Section 8.5, Types
date/heure pour le type quivalent dans le serveur PostgreSQL.
Les fonctions suivantes peuvent tre utilises pour manipuler le type timestamp:
PGTYPEStimestamp_from_asc
Transformer un timestamp de sa reprsentation texte vers une variable timestamp.
timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr);
La fonction reoit la chane analyser (str) et un pointeur vers un char* C (endptr). The function receives the string to
parse (str) and a pointer to a C char* (endptr). l'heure actuelle ECPG traite toujours intgralement la chane, et ne supporte donc pas encore l'adresse du premier caractre invalide dans *endptr. Vous pouvez positionner endptr NULL
sans risque.
La fonction retourne le timestamp identifi en cas de russite. En cas d'erreur, PGTYPESInvalidTimestamp est retourn
et error est positionn PGTYPES_TS_BAD_TIMESTAMP. Voyez PGTYPESInvalidTimestamp pour des informations importantes sur cette valeur.
En gnral, la chane d'entre peut contenir toute combinaison d'une spcification de date autorise, un caractre espace et une
spcification de temps (time) autorise. Notez que les timezones ne sont pas supportes par ECPG. Il peut les analyzer mais
n'applique aucune calcul comme le ferait le serveur PostgreSQL par exemple. Les spcificateurs de timezone sont ignores
en silence.
Tableau 33.5, Formats d'Entre Valide pour PGTYPEStimestamp_from_asc contient quelques exemples pour les
chanes d'entre.
Tableau 33.5. Formats d'Entre Valide pour PGTYPEStimestamp_from_asc

Entre

Rsultat

1999-01-08 04:05:06

1999-01-08 04:05:06

January 8 04:05:06 1999 PST

1999-01-08 04:05:06

1999-Jan-08 04:05:06.789-8

1999-01-08 04:05:06.789 (time zone specifier ignored)


547

ECPG SQL embarqu en C

Entre

Rsultat

J2451187 04:05-08:00

1999-01-08
ignored)

04:05:00

(time

zone

specifier

PGTYPEStimestamp_to_asc
Convertit une date vers une chane char* C.
char *PGTYPEStimestamp_to_asc(timestamp tstamp);
Cette fonction reoin le timestamp tstamp comme seul argument et retourne une chane alloue qui contient la reprsentation textuelle du timestamp.
PGTYPEStimestamp_current
Rcupre le timestamp courant.
void PGTYPEStimestamp_current(timestamp *ts);
Cette fonction rcupre le timestamp courant et le sauve dans la variable timestamp vers laquelle ts pointe.
PGTYPEStimestamp_fmt_asc
Convertit une variable timestamp vers un char* C en utilisant un masque de formatage.
int PGTYPEStimestamp_fmt_asc(timestamp *ts, char *output, int str_len, char
*fmtstr);
Cette fonction reoin ut pointeur vers le timestamp convertir comme premier argument (ts), un pointeur vers le tampon de
sortie (output), la longueur maximale qui a t alloue pour le tampon de sortie (str_len) et le masque de formatage
utiliser pour la conversion (fmtstr).
En cas de russite, la fonction retourne 0, et une valeur ngative en cas d'erreur.
Vous pouvez utiliser les spcificateurs de format suivant pour le masque de formatage. Les spcificateurs sont les mmes que
ceux utiliss dans la fonction strftime de la libc. Tout spcificateur ne correspondant pas du formatage sera copi
dans le tampon de sortie.

%A - est remplac par la reprsentation nationale du nom complet du jour de la semaine.

%a - est remplac par la reprsentation nationale du nom abrg du jour de la semaine.

%B - est remplac par la reprsentation nationale du nom complet du mois.

%b - est remplac par la reprsentation nationale du nom abrg du mois.

%C - est remplac par (anne / 100) sous forme de nombre dcimal; les chiffres seuls sont prcds par un zro.

%c - est rempalc par la reprsentation nationale de time et date.

%D - est quivalent %m/%d/%y.

%d - est remplac par le jour du mois sous forme de nombre dcimal (01-31).

%E* %O* - Extensions locales POSIX Les squences: %Ec %EC %Ex %EX %Ey %EY %Od %Oe %OH %OI %Om %OM %OS
%Ou %OU %OV %Ow %OW %Oy sont supposes fournir des reprsentations alternatives.
De plus, %OB est implment pour reprsenter des noms de mois alternatifs (utilis seul, sans jour mentionn).

%e - est remplac par le jour du mois comme nombre dcimal (1-31); les chiffres seuls sont prcds par un blanc.

%F - est quivalent %Y-%m-%d.

%G - est remplac par une anne comme nombre dcimal avec le sicle. L'anne courante est celle qui contient la plus
grande partie de la semaine (Lundi est le premier jour de la semaine).

%g - est remplac par la mme anne que dans %G, mais comme un nombre dcimal sans le sicle. (00-99).

%H - est remplac par l'heure (horloge sur 24 heures) comme nombre dcimal (00-23).

%h - comme %b.

%I - est remplac par l'heure (horloge sur 12 heures) comme nombre dcimal(01-12).

548

ECPG SQL embarqu en C

%j - est remplac par le jour de l'anne comme nombre dcimal (001-366).

%k - est remplac par l'heure (horloge sur 24 heures) comme nombre dcimal (0-23); les chiffres seuls sont prcds par
un blanc.

%l - est remplac par l'heure (horloge sur 12 heures) comme nombre dcimal (1-12); les chiffres seuls sont prcds par
un blanc.

%M - est remplac par la minute comme nombre dcimal (00-59).

%m - est remplac par le mois comme nombre dcimal (01-12).

%n - est remplac par un caractre nouvelle ligne.

%O* - comme %E*.

%p - est remplac par la reprsentation nationale de ante meridiem ou post meridiem suivant la valeur approprie.

%R - est quivalent %H:%M.

%r - est quivalent %I:%M:%S %p.

%S - est remplac par la seconde comme nombre dcimal (00-60).

%s - est remplac par le nombre de secondes depuis l'Epoch, en UTC.

%T - est quivalent %H:%M:%S

%t - est remplac par une tabulation.

%U - est remplac par le numro de la semaine dans l'anne (Dimanche est le premier jour de la semaine) comme nombre
dcimal(00-53).

%u - est remplac par le jour de la semaine (Lundi comme premier jour de la semaine) comme nombre dcimal (1-7).

%V - est remplac par le numro de la semaine dans l'anne (Lundi est le premier jour de la semaine) comme nombre dcimal (01-53). Si l'anne contenant le 1er Janvier a 4 jours ou plus dans la nouvelle anne, alors c'est la semaine numro 1;
sinon, c'est la dernire semaine de l'anne prcdente, et la semaine suivante est la semaine 1.

%v - est quivalent %e-%b-%Y.

%W - est remplac par le numro de la semaine dans l'anne (Lundi est le premier jour de la semaine) comme nombre dcimal (00-53).

%w - est remplac par le jour de la semaine (Dimanche comme premier jour de la semaine) comme nombre dcimal (0-6).

%X - est remplac par la reprsentation nationale du temps.

%x - est remplac par la reprsentation nationale de la date.

%Y - est remplac par l'anne avec le sicle comme un nombre dcimal.

%y - est remplac par l'anne sans le sicle comme un nombre dcimal (00-99).

%Z - est remplac par le nom de la zone de temps.

%z - est remplac par le dcalage de la zone de temps par rapport UTC; un signe plus initial signifie l'est d'UTC, un
signe moins l'ouest d'UTC, les heures et les minutes suivent avec deux chiffres chacun et aucun dlimiteur entre eux
(forme commune pour les enttes de date spcifis par la RFC 822).

%+ - est remplac par la reprsentation nationale de la date et du temps.

%-* - extension de la libc GNU. Ne pas faire de padding (bourrage) sur les sorties numriques.

$_* - extension de la libc GNU. Spcifie explicitement l'espace pour le padding.

%0* - extension de la libc GNU. Spcifie explicitement le zro pour le padding.

%% - est remplac par %.

PGTYPEStimestamp_sub
Soustraire un timestamp d'un autre et sauver le rsultat dans une variable de type interval.
int PGTYPEStimestamp_sub(timestamp *ts1, timestamp *ts2, interval *iv);
Cette fonction soustrait la variable timestamp vers laquelle pointe ts2 de la variable de timestamp vers laquelle ts1 pointe,
549

ECPG SQL embarqu en C

et stockera le rsultat dans la variable interval vers laquelle iv pointe.


En cas de succs, la fonction retourne 0, et une valeur ngative si une erreur s'est produite.
PGTYPEStimestamp_defmt_asc
Convertit une valeur timestamp de sa reprsentation textuelle en utilisant un masque de formatage.
int PGTYPEStimestamp_defmt_asc(char *str, char *fmt, timestamp *d);
Cette fonction reoit la reprsentation textuelle d'un timestamp dans la variable str ainsi que le masque de formatage utiliser dans la variable fmt. Le rsultat sera stock dans la variable vers laquelle d pointe.
Si le masque de formatage fmt est NULL, la fonction se rabattra vers le masque de formatage par dfaut qui est %Y-%m-%d
%H:%M:%S.
C'est la fonction inverse de PGTYPEStimestamp_fmt_asc. Voyez la documentation cet endroit pour dcouvrir toutes
les entres possibles de masque de formatage.
PGTYPEStimestamp_add_interval
Ajouter une variable interval une variable timestamp.
int PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout);
Cette fonction reoit un pointeur vers une variable timestamp tin et un pointeur vers une variable interval span. Elle ajoute
l'intervalle au timestapm et sauve le timestamp rsultat dans la variable vers laquelle tout pointe.
En cas de succs, la fonction retourne 0, et une valeur ngative si une erreur s'est produite.
PGTYPEStimestamp_sub_interval
Soustrait une variable interval d'une variable timestamp.
int PGTYPEStimestamp_sub_interval(timestamp *tin, interval *span, timestamp *tout);
Cette fonction soustrait la variable interval vers laquelle span pointe de la variable timestamp vers laquelle tin pointe et
sauve le rsultat dans la variable vers laquelle tout pointe.
En cas de succs, la fonction retourne 0, et une valeur ngative si une erreur s'est produite.

33.6.4. Le Type interval


Le type interval en C permet vos programmes de manipuler des donnes du type SQL interval. Voyez Section 8.5, Types date/
heure pour le type quivalent dans le serveur PostgreSQL.
Les fonctions suivantes peuvent tre utilises pour travailler avec le type interval:
PGTYPESinterval_new
Retourne un pointeur vers une variable interval nouvellement alloue.
interval *PGTYPESinterval_new(void);
PGTYPESinterval_free
Libre la mmoire d'une variable interval prcdemment alloue.
void PGTYPESinterval_new(interval *intvl);
PGTYPESinterval_from_asc
Convertit un interval partir de sa reprsentation textuelle.
interval *PGTYPESinterval_from_asc(char *str, char **endptr);
Cette fonction traite la chane d'entre str et retourne un pointeur vers une variable interval alloue. l'heure actuelle ECPG
traite toujours intgralement la chane, et ne supporte donc pas encore l'adresse du premier caractre invalide dans *endptr.
Vous pouvez positionner endptr NULL sans risque.
PGTYPESinterval_to_asc
Convertit une variable de type interval vers sa reprsentation textuelle.
550

ECPG SQL embarqu en C

char *PGTYPESinterval_to_asc(interval *span);


Cette fonction convertit la variable interval vers laquelle span pointe vers un char* C. La sortie ressemble cet exemple: @
1 day 12 hours 59 mins 10 secs.
PGTYPESinterval_copy
Copie une variable de type interval.
int PGTYPESinterval_copy(interval *intvlsrc, interval *intvldest);
Cette fonction copie la variable interval vers laquelle intvlsrc pointe vers la variable vers laquelle intvldest pointe.
Notez que vous devrez allouer la mmoire pour la variable destination auparavant.

33.6.5. Le Type decimal


Le type decimal est similaire au type numeric. Toutefois il est limit une prcision maximale de 30 chiffres significatifs.
l'oppose du type numeric que ne peut tre cr que sur le tas, le type decimal peur tre cr soit sur la pile soit sur le tas (au
moyen des fonctions PGTYPESdecimal_new et PGTYPESdecimal_free). Il y a beaucoup d'autres fonctions qui manipulent le type decimal dans le mode de compatibilit Informix dcrit dans Section 33.15, Mode de Compatibilit
Informix .
Les fonctions suivantes peut tre utilise pour travailler avec le type decimal et ne sont pas seulement contenues dans la librairie
libcompat.
PGTYPESdecimal_new
Demande un pointeur vers une variable decimal nouvellement alloue.
decimal *PGTYPESdecimal_new(void);
PGTYPESdecimal_free
Libre un type decimal, libre toute sa mmoire.
void PGTYPESdecimal_free(decimal *var);

33.6.6. errno Valeurs de pgtypeslib


PGTYPES_NUM_BAD_NUMERIC
Un argument devrait contenir une variable numeric (ou pointer vers une variable numeric) mais en fait sa reprsentation en
mmoire tait invalide.
PGTYPES_NUM_OVERFLOW
Un dpassement de capacit s'est produit. Comme le type numeric peut travailler avec une prcision quasi-arbitraire, convertir
une variable numeric vers d'autres types peut causer un dpassement.
PGTYPES_NUM_UNDERFLOW
Un soupassement de capacit s'est produit. Comme le type numeric peut travailler avec une prcision quasi-arbitraire, convertir une variable numeric vers d'autres types peut causer un soupassement.
PGTYPES_NUM_DIVIDE_ZERO
Il y a eu une tentative de division par zro.
PGTYPES_DATE_BAD_DATE
Une chane de date invalide a t passe la fonction PGTYPESdate_from_asc.
PGTYPES_DATE_ERR_EARGS
Des arguments invalides ont t passs la fonction PGTYPESdate_defmt_asc.
PGTYPES_DATE_ERR_ENOSHORTDATE
Un indicateur invalide a t trouv dans la chane d'entre par la fonction PGTYPESdate_defmt_asc.
PGTYPES_INTVL_BAD_INTERVAL
Une chane invalide d'interval a t passe la fonction PGTYPESinterval_from_asc, ou une valeur invalide d'interval
a t passe la fonction PGTYPESinterval_to_asc.
551

ECPG SQL embarqu en C

PGTYPES_DATE_ERR_ENOTDMY
Il n'a pas t possible de trouver la correspondance dans l'assignement jour/mois/anne de la fonction PGTYPESdate_defmt_asc.
PGTYPES_DATE_BAD_DAY
Un jour de mois invalide a t trouv par la fonction the PGTYPESdate_defmt_asc.
PGTYPES_DATE_BAD_MONTH
Une valeur de mois invalide a t trouve par la fonction the PGTYPESdate_defmt_asc.
PGTYPES_TS_BAD_TIMESTAMP
Une chane de timestamp invalide a t passe la fonction PGTYPEStimestamp_from_asc, ou une valeur invalide de
timestamp a t passe la fonction PGTYPEStimestamp_to_asc.
PGTYPES_TS_ERR_EINFTIME
Une valeur infinie de timestamp a t recontre dans un context qui ne peut pas la manipuler.

33.6.7. Constantes Spciales de pgtypeslib


PGTYPESInvalidTimestamp
Une valeur de timestamp reprsentant un timestamp invalide. C'est retourn par la fonction PGTYPEStimestamp_from_asc en cas d'erreur de conversion. Notez qu'en raison de la reprsentation interne du type de donnes timestamp, PGTYPESInvalidTimestamp est aussi un timestamp valide en mme temps. Il est positionn 1899-12-31
23:59:59. Afin de detecter les erreurs, assurez vous que votre application teste non seulement PGTYPESInvalidTimestamp mais aussi error != 0 aprs chaque appel PGTYPEStimestamp_from_asc.

33.7. Utiliser les Zones de Descripteur


Une zone de descripteur SQL (SQL Descriptor Area ou SQLDA) est une mthode plus sophistique pour traiter le rsultat d'un
ordre SELECT, FETCH ou DESCRIBE. Une zone de descripteur SQL regroupe les donnes d'un enregistrement avec ses mtadonnes dans une seule structure. Ces mtadonnes sont particulirement utiles quand on excute des ordres SQL dynamiques,
o_la nature des colonnes rsultat ne sont pas forcment connues l'avance. PostgreSQL fournit deux faons d'utiliser des Zones
de Descripteur: les Zones de Descripteur SQL nomme et les structures C SQLDA.

33.7.1. Zones de Descripteur SQL nommes


Une zone descripteur SQL nomm est compose d'un entte, qui contient des donnes concernant l'ensemble du descripteur, et
une ou plusieurs zones de descriptions d'objets, qui en fait dcrivent chaque colonne de l'enregistrement rsultat.
Avant que vous puissiez utiliser une zone de descripteur SQL, vous devez en allouer une:
EXEC SQL ALLOCATE DESCRIPTOR identifiant;
L'identifiant sert de nom de variable de la zone de descripteur. La porte de descripteur est QUOI?. Quand vous n'avez plus
besoin du descripteur, vous devriez le dsallouer:
EXEC SQL DEALLOCATE DESCRIPTOR identifiant;
Pour utiliser une zone de descripteur, spcifiez le comme cible de stockage dans une clause INTO, la place d'une liste de variables htes:
EXEC SQL FETCH NEXT FROM mycursor INTO SQL DESCRIPTOR mydesc;
Si le jeu de donnes retourn est vide, la zone de descripteur contiendra tout de mme les mtadonnes de la requte, c'est dire
les noms des champs.
Pour les requtes prpares mais pas encore excutes, l'ordre DESCRIBE peut tre utilis pour rcuprer les mtadonnes du rsultat:
EXEC SQL BEGIN DECLARE SECTION;
char *sql_stmt = "SELECT * FROM table1";
EXEC SQL END DECLARE SECTION;
552

ECPG SQL embarqu en C

EXEC SQL PREPARE stmt1 FROM :sql_stmt;


EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;
Avant PostgreSQL 9.0, le mot cl SQL tait optionnel, par consquent utiliser DESCRIPTOR et SQL DESCRIPTOR produisaent
les mmes zones de descripteur SQL. C'est maintenant obligatoire, et oublier le mot cl SQL produit des zones de descripteurs
SQLDA, voyez Section 33.7.2, Zones de Descripteurs SQLDA .
Dans les ordres DESCRIBE et FETCH, les mots-cls INTO et USING peuvent tre utiliss de faon similaire: ils produisent le
jeu de donnes et les mtadonnes de la zone de descripteur.
Maintenant, comment rcuprer les donnes de la zone de descripteur? Vous pouvez voir la zone de descripteur comme une structure avec des champs nomms. Pour rcuprer la valeur d'un champ partir de l'entte et le stocker dans une variable hte, utilisez
la commande suivante:
EXEC SQL GET DESCRIPTOR name :hostvar = field;
l'heure actuelle, il n'y a qu'un seul champ d'entte dfini: COUNT, qui dit combien il y a de zones de descripteurs d'objets (c'est
dire, combien de colonnes il y a dans le rsultat). La variable hte doit tre de type integer. Pour rcuprer un champ de la zone de
description d'objet, utilisez la commande suivante:
EXEC SQL GET DESCRIPTOR name VALUE num :hostvar = field;
num peut tre un integer literal, ou une variable hte contenant un integer. Les champs possibles sont:
CARDINALITY (integer)
nombres d'enregistrements dans le rsultat
DATA
objet de donne proprement dit (par consquent, le type de donnes de ce champ dpend de la requte)
DATETIME_INTERVAL_CODE (integer)
Quand TYPE est 9, DATETIME_INTERVAL_CODE aura une valeur de 1 pour DATE, 2 pour TIME, 3 pour TIMESTAMP, 4
pour TIME WITH TIME ZONE, or 5 pour TIMESTAMP WITH TIME ZONE.
DATETIME_INTERVAL_PRECISION (integer)
non implment
INDICATOR (integer)
l'indicateur (indique une valeur null ou une troncature de valeur)
KEY_MEMBER (integer)
non implment
LENGTH (integer)
longueur de la donne en caractres
NAME (string)
nom de la colonne
NULLABLE (integer)
non implment
OCTET_LENGTH (integer)
longueur de la reprsentation caractre de la donne en octets
PRECISION (integer)
prcision (pour les types numeric)
RETURNED_LENGTH (integer)
longueur de la donne en caractres
RETURNED_OCTET_LENGTH (integer)
longueur de la reprsentation caractre de la donne en octets
SCALE (integer)
chelle (pour le type numeric)
TYPE (integer)
code numrique du type de donnes de la colonne

553

ECPG SQL embarqu en C

Dans les ordres EXECUTE, DECLARE and OPEN, l'effet des mots cls INTO and USING est diffrent. Une zone de descripteur peut aussi tre construite manuellement pour fournir les paramtres d'entr pour une requte ou un curseur et USING SQL
DESCRIPTOR name est la faon de passer les paramtres d'entre une requte paramtrise. L'ordre pour construire une zone
de descripteur SQL est ci-dessous:
EXEC SQL SET DESCRIPTOR name VALUE num field = :hostvar;
PostgreSQL supporte la rcupration de plus d'un enregistrement dans un ordre FETCH et les variables htes dans ce cas doivent
tre des tableaux. Par exemple:
EXEC SQL BEGIN DECLARE SECTION;
int id[5];
EXEC SQL END DECLARE SECTION;
EXEC SQL FETCH 5 FROM mycursor INTO SQL DESCRIPTOR mydesc;
EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :id = DATA;

33.7.2. Zones de Descripteurs SQLDA


Une zone de descripteur SQLDA est une structure C qui peut aussi tre utilis pour rcuprer les rsultats et les mtadonnes
d'une requte. Une structure stocke un enregistrement du jeu de rsultat.
EXEC SQL include sqlda.h;
sqlda_t
*mysqlda;
EXEC SQL FETCH 3 FROM mycursor INTO DESCRIPTOR mysqlda;
Netez que le mot cl SQL est omis. Les paragraphes qui parlent des cas d'utilisation de INTO and USING dans Section 33.7.1,
Zones de Descripteur SQL nommes s'appliqent aussi ici, avec un point supplmentaire. Dans un ordre DESCRIBE le mot cl
DESCRIPTOR peut tre compltement omis si le mot cl INTO est utilis:
EXEC SQL DESCRIBE prepared_statement INTO mysqlda;
Le droulement gnral d'un programme qui utilise des SQLDA est:
1.

Prparer une requte, et dclarer un curseur pour l'utiliser.

2.

Dclarer une SQLDA pour les lignes de rsultat.

3.

Dclarer une SQLDA pour les paramtres d'entres, et les initialiser (allocation mmoire, positionnement des paramtres).

4.

Ouvrir un curseur avec la SQLDA d'entre.

5.

Rcuprer les enregistrements du curseur, et les stocker dans une SQLDA de sortie.

6.

Lire les valeurs de la SQLDA de sortie vers les variables htes (avec conversion si ncessaire).

7.

Fermer le curseur.

8.

Librer la zone mmoire alloue pour la SQLDA d'entre.

33.7.2.1. Structure de Donnes SQLDA


Les SQLDA utilisent 3 types de structures de donnes: sqlda_t, sqlvar_t, et struct sqlname.

Astuce
La structure de la SQLDA de PostgreSQL est similaire celle de DB2 Universal Database d'IBM, des informations
techniques sur la SQLDA de DB2 peuvent donc aider mieux comprendre celle de PostgreSQL.
33.7.2.1.1. Structure sqlda_t

554

ECPG SQL embarqu en C

Le type de structure sqlda_t est le type de la SQLDA proprement dit. Il contient un enregistrement. Et deux ou plus sqlda_t
peuvent tre connectes par une liste chane par le pointeur du champ desc_next, reprsentant par consquent une collection
ordonne d'enregistrements. Par consquent, quand deux enregistrements ou plus sont rcuprs, l'application peut les lire en suivant le pointeur desc_next dans chaque nud sqlda_t.
La dfinition de sqlda_t est:
struct sqlda_struct
{
char
sqldaid[8];
long
sqldabc;
short
sqln;
short
sqld;
struct sqlda_struct *desc_next;
struct sqlvar_struct sqlvar[1];
};
typedef struct sqlda_struct sqlda_t;
La signification des champs est:
sqldaid
Elle contient la chane littrale "SQLDA ".
sqldabc
Il contient la taille de l'espace allou en octets.
sqln
Il content le nombre de paramtres d'entre pour une requte paramtrique, dans le cas o il est pass un ordre OPEN, DECLARE ou EXECUTE utilisant le mot cl USING. Dans le cas o il sert de sortie un ordre SELECT, EXECUTE ou
FETCH statements, sa valeur est la mme que celle du champ sqld.
sqld
Il contient le nombre de champs du rsultat.
desc_next
Si la requte retourne plus d'un enregistrement, plusieurs structures SQLDA chanes sont retournes, et desc_next
contient un pointeur vers l'lment suivant (enregistrement) de la liste.
sqlvar
C'est le tableau des colonnes du rsultat.
33.7.2.1.2. Structure de sqlvar_t

Le type structure sqlvar_t contient la valeur d'une colonne et les mtadonnes telles que son type et sa longueur. La dfinition du
type est:
struct sqlvar_struct
{
short
sqltype;
short
sqllen;
char
*sqldata;
short
*sqlind;
struct sqlname sqlname;
};
typedef struct sqlvar_struct sqlvar_t;
La signification des champs est:
sqltype
Contient l'identifiant de type du champ. Pour les valeurs, voyez enum ECPGttype dans ecpgtype.h.
sqllen
Contient la longueur binaire du champ, par exemple 4 octets pour ECPGt_int.
sqldata
Pointe vers la donne. Le format de la donne est dcrit dans Section 33.4.4, Correspondance de Type .
555

ECPG SQL embarqu en C

sqlind
Pointe vers l'indicateur de nullit. 0 signifie non nul, -1 signifie nul. null.
sqlname
Le nom du champ.
33.7.2.1.3. Structure struct sqlname

Une structure struct sqlname contient un nom de colonne. Il est utilis comme membre de la structure sqlvar_t. La dfinition de la
structure est:
#define NAMEDATALEN 64
struct sqlname
{
short
char
};

length;
data[NAMEDATALEN];

La signification des champs est:


length
Contient la longueur du nom du champ.
data
Contient le nom du champ proprement dit.

33.7.2.2. Rcuprer un jeu de donnes au moyen d'une SQLDA


Les tapes gnrales pour rcuprer un jeu de donnes au moyen d'une SQLDA sont:
1.

Dclarer une structure sqlda_t pour recevoir le jeu de donnes.

2.

Excuter des commandes FETCH/EXECUTE/DESCRIBE pour traiter une requte en spcifiant la SQLDA dclare.

3.

Vrifier le nombre d'enregistrements dans le rsultat en inspectant sqln, un membre de la structure sqlda_t.

4.

Rcuprer les valeurs de chaque colonne des membres sqlvar[0], sqlvar[1], etc., de la structure sqlda_t.

5.

Aller l'enregistrement suivant (sqlda_t structure) en suivant le pointeur desc_next, un membre de la structure sqlda_t.

6.

Rpter l'tape ci-dessus au besoin.

Voici un exemple de rcupration d'un jeu de rsultats au moyen d'une SQLDA.


Tout d'abord, dclarer une structure sqlda_t pour recevoir le jeu de rsultats.
sqlda_t *sqlda1;
Puis, spcifier la SQLDA dans une commande. Voici un exemple avec une commande FETCH.
EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
Faire une boucle suivant la liste chane pour rcuprer les enregistrements.
sqlda_t *cur_sqlda;
for (cur_sqlda = sqlda1;
cur_sqlda != NULL;
cur_sqlda = cur_sqlda->desc_next)
{
...
}

556

ECPG SQL embarqu en C

Dans la boucle, faire une autre boucle pour rcuprer chaque colonne de donnes (sqlvar_t) de l'enregistrement.
for (i = 0; i < cur_sqlda->sqld; i++)
{
sqlvar_t v = cur_sqlda->sqlvar[i];
char *sqldata = v.sqldata;
short sqllen = v.sqllen;
...
}
Pour rcuprer une valeur de colonne, vrifiez la valeur de sqltype. Puis, suivant le type de la colonne, basculez sur une faon
approprie de copier les donnes du champ sqlvar vers une variable hte.
char var_buf[1024];
switch (v.sqltype)
{
case ECPGt_char:
memset(&var_buf, 0, sizeof(var_buf));
memcpy(&var_buf, sqldata, (sizeof(var_buf) <= sqllen ? sizeof(var_buf) - 1 :
sqllen));
break;
case ECPGt_int: /* integer */
memcpy(&intval, sqldata, sqllen);
snprintf(var_buf, sizeof(var_buf), "%d", intval);
break;
...
}

33.7.2.3. Passer des Paramtres de Requte en Utilisant une SQLDA


La mthode gnrale pour utiliser une SQLDA pour passer des paramtres d'entre une requte prpare sont:
1.

Crer une requte prpare (prepared statement)

2.

Dclarer une structure sqlda_t comme SQLDA d'entre.

3.

Allouer une zone mmorie (comme structure sqlda_t) pour la SQLDA d'entre.

4.

Positionner (copier) les valeurs d'entre dans la mmoire alloupe.

5.

Ouvrir un curseur en spcifiant la SQLDA d'entre.

Voici un exemple.
D'abord, crer une requte prpare.
EXEC SQL BEGIN DECLARE SECTION;
char query[1024] = "SELECT d.oid, * FROM pg_database d, pg_stat_database s WHERE d.oid
= s.datid AND (d.datname = ? OR d.oid = ?)";
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE stmt1 FROM :query;
Puis, allouer de la mmoire pour une SQLDA, et positionner le nombre de paramtres d'entrne dans sqln, une variable membre
de la structure<sqlda_t>. Quand deux paramtres d'entre ou plus sont requis pour la requte prpare, l'application doit allouer de
la mmoire supplmentaire qui est calcule par (nombre de paramtres -1) * sizeof<sqlvar_t>. Les exemples affichs ici allouent
de l'espace mmoire pour deux paramtres d'entre.
sqlda_t *sqlda2;
sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
557

ECPG SQL embarqu en C

memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));


sqlda2->sqln = 2; /* nombre de variables d'entre */
Aprs l'allocation mmoire, stocker les valeurs des paramtres dans le tableausqlvar[]. (C'est le mme tableau que celui qui est
utilis quand la SQLDA reoit un jeu de rsultats.) Dans cet exemple, les paramtres d'entre sont "postgres", de type chane,
et 1, de type integer.
sqlda2->sqlvar[0].sqltype = ECPGt_char;
sqlda2->sqlvar[0].sqldata = "postgres";
sqlda2->sqlvar[0].sqllen = 8;
int intval = 1;
sqlda2->sqlvar[1].sqltype = ECPGt_int;
sqlda2->sqlvar[1].sqldata = (char *) &intval;
sqlda2->sqlvar[1].sqllen = sizeof(intval);
En ouvrant un curseur et en spcifiant la SQLDA qui a t positionn auparavant, les paramtres d'entre sont passs la requte
prpare.
EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
Et pour finir, aprs avoir utilis les SQLDAs d'entre, la mmoire alloue doit tre libre explicitement, contrairement aux SQLDAs utilis pour recevoir le rsultat d'une requte.
free(sqlda2);

33.7.2.4. Une application de Dmonstration Utilisant SQLDA


Voici un programme de dmonstration, qui montre comment rcuprer des statistiques d'accs des bases, spcifies par les paramtres d'entre, dans les catalogues systmes.
Cette application joint deux tables systmes, pg_database et pg_stat_database sur l'oid de la base, et rcupre et affiche aussi les
statistiques des bases qui sont spcifies par deux paramtres d'entres (une base postgres et un OID 1).
Tout d'abord, dclarer une SQLDA pour l'entre et une SQLDA pour la sortie.
EXEC SQL include sqlda.h;
sqlda_t *sqlda1; /* un descripteur de sortie */
sqlda_t *sqlda2; /* un descripteur d'entre */
Puis, se connecter la base, prparer une requte, et dclarer un curseur pour la requte prpare.
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE
d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb AS con1 USER testuser;
EXEC SQL PREPARE stmt1 FROM :query;
EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
Puis, mettre des valeurs dans la SQLDA d'entre pour les paramtres d'entre. Allouer de la mmoire pour la SQL d'entre, et positionner le nombre de paramtres d'entre dans sqln. Stocker le type, la valeur et la longueur de la valeur dans sqltype, sqldata et sqllen dans la structure sqlvar.
/* Crer une structure SQLDA pour les paramtres d'entre. */
sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
558

ECPG SQL embarqu en C

memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));


sqlda2->sqln = 2; /* number of input variables */
sqlda2->sqlvar[0].sqltype = ECPGt_char;
sqlda2->sqlvar[0].sqldata = "postgres";
sqlda2->sqlvar[0].sqllen = 8;
intval = 1;
sqlda2->sqlvar[1].sqltype = ECPGt_int;
sqlda2->sqlvar[1].sqldata = (char *)&intval;
sqlda2->sqlvar[1].sqllen = sizeof(intval);
Aprs avoir positionn la SQLDA d'entre, ouvrir un curseur avec la SQLDA d'entre.
/* Ouvrir un curseur avec les paramtres d'entre. */
EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
Rcuprer les enregistrements dans la SQLDA de sortie partir du curseur ouvert. (En gnral, il faut appeler FETCH de faon
rpte dans la boucle, pour rcuprer tous les enregistrements du jeu de donnes.)
while (1)
{
sqlda_t *cur_sqlda;
/* Assigner le descripteur au curseur */
EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
Ensuite, rcuprer les enregistrements du FETCH de la SQLDA, en suivant la liste chane de la structure sqlda_t.
for (cur_sqlda = sqlda1 ;
cur_sqlda != NULL ;
cur_sqlda = cur_sqlda->desc_next)
{
...
Lire chaque colonne dans le premier enregistrement. Le nombre de colonnes est stock dans sqld, les donnes relles de la premire colonne sont stockes dans sqlvar[0], tous deux membres de la structuresqlda_t.
/* Afficher toutes les colonnes d'un enregistrement. */
for (i = 0; i < sqlda1->sqld; i++)
{
sqlvar_t v = sqlda1->sqlvar[i];
char *sqldata = v.sqldata;
short sqllen = v.sqllen;
strncpy(name_buf, v.sqlname.data, v.sqlname.length);
name_buf[v.sqlname.length] = '\0';
Maintenant, la donne de la colonne est stocke dans la variable v. Copier toutes les donnes dans les variables host, en inspectant
v.sqltype pour connatre le type de la colonne.
switch (v.sqltype) {
int intval;
double doubleval;
unsigned long long int longlongval;
case ECPGt_char:
memset(&var_buf, 0, sizeof(var_buf));
memcpy(&var_buf, sqldata, (sizeof(var_buf) <= sqllen ?
sizeof(var_buf)-1 : sqllen));
break;
case ECPGt_int: /* integer */
memcpy(&intval, sqldata, sqllen);
559

ECPG SQL embarqu en C

snprintf(var_buf, sizeof(var_buf), "%d", intval);


break;
...
default:
...
}
printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
}
Fermer le curseur aprs avoir trait tous les enregistrements, et se dconnecter de la base de donnes.
EXEC SQL CLOSE cur1;
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
Le programme dans son entier est visible dans Exemple 33.1, Programme de Dmonstration SQLDA .
Exemple 33.1. Programme de Dmonstration SQLDA

#include
#include
#include
#include
#include

<stdlib.h>
<string.h>
<stdlib.h>
<stdio.h>
<unistd.h>

EXEC SQL include sqlda.h;


sqlda_t *sqlda1; /* descripteur pour la sortie */
sqlda_t *sqlda2; /* descripteur pour l'entre */
EXEC SQL WHENEVER NOT FOUND DO BREAK;
EXEC SQL WHENEVER SQLERROR STOP;
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE
d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
int intval;
unsigned long long int longlongval;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO uptimedb AS con1 USER uptime;
EXEC SQL PREPARE stmt1 FROM :query;
EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
/* Crer une structure SQLDB pour let paramtres d'entre */
sqlda2 = (sqlda_t *)malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
sqlda2->sqln = 2; /* a number of input variables */
sqlda2->sqlvar[0].sqltype = ECPGt_char;
sqlda2->sqlvar[0].sqldata = "postgres";
sqlda2->sqlvar[0].sqllen = 8;
intval = 1;
sqlda2->sqlvar[1].sqltype = ECPGt_int;
sqlda2->sqlvar[1].sqldata = (char *) &intval;
sqlda2->sqlvar[1].sqllen = sizeof(intval);
560

ECPG SQL embarqu en C

/* Ouvrir un curseur avec les paramtres d'entre. */


EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
while (1)
{
sqlda_t *cur_sqlda;
/* Assigner le descripteur au curseur */
EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
for (cur_sqlda = sqlda1 ;
cur_sqlda != NULL ;
cur_sqlda = cur_sqlda->desc_next)
{
int i;
char name_buf[1024];
char var_buf[1024];
/* Afficher toutes les colonnes d'un enregistrement. */
for (i=0 ; i<cur_sqlda->sqld ; i++)
{
sqlvar_t v = cur_sqlda->sqlvar[i];
char *sqldata = v.sqldata;
short sqllen = v.sqllen;
strncpy(name_buf, v.sqlname.data, v.sqlname.length);
name_buf[v.sqlname.length] = '\0';
switch (v.sqltype)
{
case ECPGt_char:
memset(&var_buf, 0, sizeof(var_buf));
memcpy(&var_buf, sqldata, (sizeof(var_buf)<=sqllen ?
sizeof(var_buf)-1 : sqllen) );
break;
case ECPGt_int: /* integer */
memcpy(&intval, sqldata, sqllen);
snprintf(var_buf, sizeof(var_buf), "%d", intval);
break;
case ECPGt_long_long: /* bigint */
memcpy(&longlongval, sqldata, sqllen);
snprintf(var_buf, sizeof(var_buf), "%lld", longlongval);
break;
default:
{
int i;
memset(var_buf, 0, sizeof(var_buf));
for (i = 0; i < sqllen; i++)
{
char tmpbuf[16];
snprintf(tmpbuf, sizeof(tmpbuf), "%02x ", (unsigned char)
sqldata[i]);
strncat(var_buf, tmpbuf, sizeof(var_buf));
}
}
break;
}
printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
}
printf("\n");
}
}

561

ECPG SQL embarqu en C

EXEC SQL CLOSE cur1;


EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
return 0;
}
L'exemple suivant devrait ressembler quelque chose comme ce qui suit (des nombres seront diffrents).
oid = 1 (type: 1)
datname = template1 (type: 1)
datdba = 10 (type: 1)
encoding = 0 (type: 5)
datistemplate = t (type: 1)
datallowconn = t (type: 1)
datconnlimit = -1 (type: 5)
datlastsysoid = 11510 (type: 1)
datfrozenxid = 379 (type: 1)
dattablespace = 1663 (type: 1)
datconfig = (type: 1)
datacl = {=c/uptime,uptime=CTc/uptime} (type: 1)
datid = 1 (type: 1)
datname = template1 (type: 1)
numbackends = 0 (type: 5)
xact_commit = 113606 (type: 9)
xact_rollback = 0 (type: 9)
blks_read = 130 (type: 9)
blks_hit = 7341714 (type: 9)
tup_returned = 38262679 (type: 9)
tup_fetched = 1836281 (type: 9)
tup_inserted = 0 (type: 9)
tup_updated = 0 (type: 9)
tup_deleted = 0 (type: 9)
oid = 11511 (type: 1)
datname = postgres (type: 1)
datdba = 10 (type: 1)
encoding = 0 (type: 5)
datistemplate = f (type: 1)
datallowconn = t (type: 1)
datconnlimit = -1 (type: 5)
datlastsysoid = 11510 (type: 1)
datfrozenxid = 379 (type: 1)
dattablespace = 1663 (type: 1)
datconfig = (type: 1)
datacl = (type: 1)
datid = 11511 (type: 1)
datname = postgres (type: 1)
numbackends = 0 (type: 5)
xact_commit = 221069 (type: 9)
xact_rollback = 18 (type: 9)
blks_read = 1176 (type: 9)
blks_hit = 13943750 (type: 9)
tup_returned = 77410091 (type: 9)
tup_fetched = 3253694 (type: 9)
tup_inserted = 0 (type: 9)
tup_updated = 0 (type: 9)
tup_deleted = 0 (type: 9)

33.8. Gestion des Erreurs


Cett section explique comment vous pouvez traiter des conditions d'exception et des avertissements dans un programme SQL embarqu. Il y a deux fonctionnalits non-exclusives pour cela.

Des fonctions de rappel (callbacks) peuvent tre configures pour traiter les conditions d'avertissement et d'erreur en utilisant
562

ECPG SQL embarqu en C

la commande WHENEVER.

Des informations dtailles propos de l'erreur ou de l'avertissement peuvent tre obtenues de la variable sqlca.

33.8.1. Mettre en Place des Callbacks


Une mthode simple pour intercepter des erreurs et des avertissements est de paramtrer des actions spcifiques excuter ds
qu'une condition particulire se produit. En gnral:
EXEC SQL WHENEVER condition action;
condition peut tre un des lments suivants:
SQLERROR
L'action spcifie est appele ds qu'une erreur se produit durant l'excution d'un ordre SQL.
SQLWARNING
L'action spcifie est appele ds qu'un avertissement se produit durant l'excution d'un ordre SQL.
NOT FOUND
L'action spcifie est appele ds qu'un ordre SQL rcupre ou affecte zro enregistrement. (Cette condition n'est pas une erreur, mais vous pourriez tre intress par un traitement spcial dans ce cas).
action peut tre un des lments suivants:
CONTINUE
Cela signifie en fait que la condition est ignore. C'est le comportement par dfaut.
GOTO label, GO TO label
Sauter au label spcifi (en utilisant un ordre goto C).
SQLPRINT
Affiche un message vers la sortie standard. C'est utile pour des programmes simples ou durant le prototypage. Le dtail du
message ne peut pas tre configur.
STOP
Appelle exit(1), ce qui mettra fin au programme.
DO BREAK
Excuter l'ordre C break. Cela ne devrait tre utilis que dans des boucles ou des ordres switch.
CALL name (args), DO name (args)
Appelle la fonction C spcifie avec les arguments spcifis.
Le standard SQL ne fournit que les actions CONTINUE et GOTO (and GO TO).
Voici un exemple de ce que pourriez vouloir utiliser dans un programme simple. Il affichera un message quand un avertissement
se produit et tuera le programme quand une erreur se produit:
EXEC SQL WHENEVER SQLWARNING SQLPRINT;
EXEC SQL WHENEVER SQLERROR STOP;
L'ordre EXEC SQL WHENEVER est une directive du prprocesseur SQL, pas un ordre SQL. L'action sur erreur ou avertissement
qu'il met en place s'applique tous les ordres SQL embarqus qui apparaissent aprs le point o le gestionnaire est mis en place,
sauf si une autre action a t mise en place pour la mme condition entre le premier EXEC SQL WHENEVER et l'ordre SQL entrainant la condition, quel que soit le droulement du programme C. Par consquent, aucun des extraits des deux programmes C
suivants n'aura l'effet escompt:
/*
* WRONG
*/
int main(int argc, char *argv[])
{
...
if (verbose) {
EXEC SQL WHENEVER SQLWARNING SQLPRINT;
563

ECPG SQL embarqu en C

}
...
EXEC SQL SELECT ...;
...
}
/*
* WRONG
*/
int main(int argc, char *argv[])
{
...
set_error_handler();
...
EXEC SQL SELECT ...;
...
}
static void set_error_handler(void)
{
EXEC SQL WHENEVER SQLERROR STOP;
}

33.8.2. sqlca
Pour une gestion plus approfondie des erreurs, l'interface SQL embarque fournit une variable globale appele sqlca (SQL communication area, ou zone de communication SQL) qui a la structure suivante:
struct
{
char sqlcaid[8];
long sqlabc;
long sqlcode;
struct
{
int sqlerrml;
char sqlerrmc[SQLERRMC_LEN];
} sqlerrm;
char sqlerrp[8];
long sqlerrd[6];
char sqlwarn[8];
char sqlstate[5];
} sqlca;
(Dans un programme multi-thread, chaque thread rcupre automatiquement sa propre copie de sqlca. Ce fonctionnement est
similaire celui de la variable C globale errno.) errno.)
sqlca couvre la fois les avertissements et les erreurs. Si plusieurs avertissements ou erreurs se produisent durant l'excution
d'un ordre, alors sqlca ne contiendra d'informations que sur le dernier.
Si aucune erreur ne s'est produite durant le dernier ordre SQL, sqlca.sqlcode vaudra 0 sqlca.sqlstate vaudra
"00000". Si un avertissement ou erreur s'est produit, alors sqlca.sqlcode sera ngatif sqlca.sqlstate sera diffrent de
"00000". Une valeur positive de sqlca.sqlcode indique une condition sans gravit comme le fait que la dernire requte ait
retourn zro enregistrements. sqlcode et sqlstate sont deux diffrents schemas de code d'erreur; les dtails sont fournis
plus bas.
Si le dernier ordre SQL a russi, alors sqlca.sqlerrd[1] contient l'OID de la ligne traite, si applicable, et sqlca.sqlerrd[2] contient le nombre d'enregistrements traits ou retourns, si applicable la commande.
En cas d'erreur ou d'avertissement, sqlca.sqlerrm.sqlerrmc contiendra une chaine qui dcrira une erreur. Le champ sqlca.sqlerrm.sqlerrml contiendra la longueur du message d'erreur qui est stock dans sqlca.sqlerrm.sqlerrmc (le
rsultat de strlen(), par rellement intressant pour un programmeur C). Notez que certains messages sont trop longs pour tenir dans le tableau de taille fixe sqlerrmc; ils seront tronqus.
En cas d'avertissement, sqlca.sqlwarn[2] est positionn W. (Dans tous les autres cas, il est positionn quelque chose de
diffrent de W.) Si sqlca.sqlwarn[1] est positionn W, alors une valeur a t tronque quand elle a t stocke dans une variable hte. sqlca.sqlwarn[0] est positionn W si n'importe lequel des autres lments est positionn pour indiquer un aver564

ECPG SQL embarqu en C

tissement.
Les champs sqlcaid, sqlcabc, sqlerrp, et les lments restants de sqlerrd et sqlwarn ne contiennent pour le moment
aucune information utile.
La structure sqlca n'est pas dfinie dans le standard SQL, mais est implmente dans plusieurs autres systmes de base de donnes. Les dfinitions sont similaires dans leur principe, mais si vous voulez crire des applications portables, vous devriez tudier
les diffrentes implmentations de faon attentive.
Voici un exemple qui combine l'utilisation de WHENEVER et de sqlca, en affichant le contenu de sqlca quand une erreur se
produit. Cela pourrait tre utile pour dboguer ou prototyper des applications, avant d'installer un gestionnaire d'erreurs plus
user-friendly .
EXEC SQL WHENEVER SQLERROR CALL print_sqlca();
void
print_sqlca()
{
fprintf(stderr, "==== sqlca ====\n");
fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n",
sqlca.sqlerrd[0],sqlca.sqlerrd[1],sqlca.sqlerrd[2],
sqlca.sqlerrd[3],sqlca.sqlerrd[4],sqlca.sqlerrd[5]);
fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0],
sqlca.sqlwarn[1], sqlca.sqlwarn[2],
sqlca.sqlwarn[3],
sqlca.sqlwarn[4], sqlca.sqlwarn[5],
sqlca.sqlwarn[6],
sqlca.sqlwarn[7]);
fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
fprintf(stderr, "===============\n");
}
Le rsultat pourrait ressembler ce qui suit (ici une erreur due un nom de table mal saisi):
==== sqlca ====
sqlcode: -400
sqlerrm.sqlerrml: 49
sqlerrm.sqlerrmc: relation "pg_databasep" does not exist on line 38
sqlerrd: 0 0 0 0 0 0
sqlwarn: 0 0 0 0 0 0 0 0
sqlstate: 42P01
===============

33.8.3. SQLSTATE contre SQLCODE


Les champs sqlca.sqlstate et sqlca.sqlcode sont deux schmas qui fournissent des codes d'erreurs. Les deux sont drivs du standard SQL, mais SQLCODE a t marqu comme dprci dans l'dition SQL-92 du standard, et a t supprim des
ditions suivantes. Par consquent, les nouvelles applications ont fortement intrt utiliser SQLSTATE.
SQLSTATE est un tableau de cinq caractres. Les cinq caractres contiennent des chiffres ou des lettres en majuscule qui reprsentent les codes des diffrentes conditions d'erreur et d'avertissement. SQLSTATE a un schma hirarchique: les deux premiers
caractres indiquent la classe gnrique de la condition, les trois caractres suivants indiquent la sous-classe de la condition gnrique. Un tat de succs est indiqu par le code 00000. Les codes SQLSTATE sont pour la plupart dfinis dans le standard SQL.
Le serveur PostgreSQL supporte nativement les codes d'erreur SQLSTATE; par consquent, un haut niveau de cohrence entre
toutes les applications peut tre obtenu en utilisant ce schma de codes d'erreur. Pour plus d'informations voyez Annexe A, Codes
d'erreurs de PostgreSQL.
SQLCODE, le schma d'erreurs dprci, est un entier simple. Une valeur de 0 indique le succs, une valeur positive indique un
succs avec des informations supplmentaires, une valeur ngative indique une erreur. Le standard SQL ne dfinit que la valeur
positive +100, qui indique que l'ordre prcdent a retourn ou affect zro enregistrement, et aucune valeur ngative spcifique.
par consquent, ce schma ne fournit qu'une pitre portabilit et n'a pas de hirarchie de code d'erreurs. Historiquement, le processeur de SQL embarqu de PostgreSQL a assign des valeurs spcifiques de SQLCODE pour son utilisation propre, qui sont listes ci-dessous avec leur valeur numrique et leur nom symbolique. Rappelez vous qu'ils ne sont pas portables vers d'autres implmentations SQL. Pour simplifier le portage des applications vers le schma SQLSTATE, les valeurs SQLSTATE sont aussi listes.
565

ECPG SQL embarqu en C

Il n'y a pas, toutefois, de correspondance un un ou un plusieurs entre les deux schmas (c'est en fait du plusieurs plusieurs),
vous devriez donc consulter la liste globale SQLSTATE dans Annexe A, Codes d'erreurs de PostgreSQL au cas par cas.
Voici les valeurs de SQLCODE assignes:
0 (ECPG_NO_ERROR)
Indique pas d'erreur. (SQLSTATE 00000)
100 (ECPG_NOT_FOUND)
C'est un tat sans danger indicant que la dernire commande a rcupr ou trait zro enregistrements, ou que vous tes au
bout du curseur. (SQLSTATE 02000)
Quand vous bouclez sur un curseur, vous pourriez utiliser ce code comme faon de dtecter quand arrter la boucle, comme
ceci:
while (1)
{
EXEC SQL FETCH ... ;
if (sqlca.sqlcode == ECPG_NOT_FOUND)
break;
}
Mais WHENEVER NOT FOUND DO BREAK fait en fait cela en interne, il n'y a donc habituellement aucun avantage crire
ceci de faon explicite.
-12 (ECPG_OUT_OF_MEMORY)
Indique que votre mmoire virtuelle est puise. La valeur numrique est dfinie comme -ENOMEM. (SQLSTATE YE001)
-200 (ECPG_UNSUPPORTED)
Indique que le prprocesseur a gnr quelque chose que la librairie ne connait pas. Peut-tre tes vous en train d'utiliser des
versions incompatibles du prprocesseur et de la librairie. (SQLSTATE YE002)
-201 (ECPG_TOO_MANY_ARGUMENTS)
Cela signifie que la commande a spcifi plus de variables hte que la commande n'en attendait. (SQLSTATE 07001 or
07002)
-202 (ECPG_TOO_FEW_ARGUMENTS)
Cela signifie que la commande a spcifi moins de variables htes que la commande n'en attendait. (SQLSTATE 07001 or
07002)
-203 (ECPG_TOO_MANY_MATCHES)
Cela signifie que la requte a retourn pluiseurs enregistrements mais que l'ordre n'tait capable d'en recevoir qu'un (par
exemple parce que les variables spcifies ne sont pas des tableaux. (SQLSTATE 21000)
-204 (ECPG_INT_FORMAT)
La variable hte est du type int et la donne dans la base de donnes est d'un type diffrent et contient une valeur qui ne peut
pas tre interprte comme un int. La librairie utilise strtol() pour cette conversion. (SQLSTATE 42804).
-205 (ECPG_UINT_FORMAT)
La variable hte est du type unsigned int et la donne dans la base de donnes est d'un type diffrent et contient une valeur qui
ne peut pas tre interprte comme un unsigned int. La librairie utilise strtoul() pour cette conversion. (SQLSTATE
42804).
-206 (ECPG_FLOAT_FORMAT)
La variable hte est du type float et la donne dans la base de donnes est d'un type diffrent et contient une valeur qui ne peut
pas tre interprte comme un float. La librairie utilise strtod() pour cette conversion. (SQLSTATE 42804).
-207 (ECPG_NUMERIC_FORMAT)
La variable hte est du type numeric et la donne dans la base de donnes est d'un type diffrent et contient une valeur qui ne
peut pas tre interprte comme un numeric. (SQLSTATE 42804).
-208 (ECPG_INTERVAL_FORMAT)
La variable hte est du type interval et la donne dans la base de donnes est d'un type diffrent et contient une valeur qui ne
peut pas tre interprte comme un interval. (SQLSTATE 42804).
-209 (ECPG_DATE_FORMAT)
La variable hte est du type date et la donne dans la base de donnes est d'un type diffrent et contient une valeur qui ne peut
pas tre interprte comme un date. (SQLSTATE 42804).
-210 (ECPG_TIMESTAMP_FORMAT)
566

ECPG SQL embarqu en C

La variable hte est du type timestamp et la donne dans la base de donnes est d'un type diffrent et contient une valeur qui
ne peut pas tre interprte comme un timestamp. (SQLSTATE 42804).
-211 (ECPG_CONVERT_BOOL)
Cela signifie que la variable hte est de type bool et que la donne dans la base n'est ni 't' ni 'f'. (SQLSTATE 42804)
-212 (ECPG_EMPTY)
L'ordre envoy au serveur PostgreSQL tait vide. (Cela ne peut normalement pas arriver dans un programme SQL embarqu, cela pourrait donc laisser supposer une erreur interne.) (SQLSTATE YE002)
-213 (ECPG_MISSING_INDICATOR)
Une valeur null a t retourne et aucune variable d'indicateur null n'a t fournie. (SQLSTATE 22002)
-214 (ECPG_NO_ARRAY)
Une variable ordinaire a t utilise un endroit qui ncessite un tableau. (SQLSTATE 42804)
-215 (ECPG_DATA_NOT_ARRAY)
La base a retourn une variable ordinaire un endroir qui ncessite une variable de tableau. (SQLSTATE 42804)
-220 (ECPG_NO_CONN)
Le programme a essay d'utiliser une connexion qui n'existe pas. (SQLSTATE 08003)
-221 (ECPG_NOT_CONN)
Le programme a essay d'utiliser une connexion qui existe mais n'est pas ouverte. (C'est une erreur interne.) (SQLSTATE
YE002)
-230 (ECPG_INVALID_STMT)
L'ordre que vous essayez d'excuter n'a pas t prpar. (SQLSTATE 26000)
-239 (ECPG_INFORMIX_DUPLICATE_KEY)
Erreur de cl en doublon, violation de contrainte unique (mode de compatibilit Informix). (SQLSTATE 23505)
-240 (ECPG_UNKNOWN_DESCRIPTOR)
Le descripteur spcifi n'a pas t trouv. L'ordre que vous essayez d'utiliser n'a pas t prpar. (SQLSTATE 33000)
-241 (ECPG_INVALID_DESCRIPTOR_INDEX)
L'index de descripteur spcifi tait hors de porte. (SQLSTATE 07009)
-242 (ECPG_UNKNOWN_DESCRIPTOR_ITEM)
Un objet de descripteur invalide a t demand. (C'est une erreur interne.) (SQLSTATE YE002)
-243 (ECPG_VAR_NOT_NUMERIC)
Durant l'excution d'un ordre dynamique, la base a retourn une valeur numeric et la variable hte n'tait pas numeric.
(SQLSTATE 07006)
-244 (ECPG_VAR_NOT_CHAR)
Durant l'excution d'un ordre dynamique, la base a retourn une valeur non numeric et la variable hte tait numeric.
(SQLSTATE 07006)
-284 (ECPG_INFORMIX_SUBSELECT_NOT_ONE)
Un rsultat de la sous-requte n'tait pas un enregistrement seul (mode de compatibilit Informix). (SQLSTATE 21000)
-400 (ECPG_PGSQL)
Une erreur cause par le serveur PostgreSQL. Le message contient le message d'erreur du serveur PostgreSQL.
-401 (ECPG_TRANS)
Le serveur PostgreSQL a signal que nous ne pouvons pas dmarrer, valider ou annuler la transaction. (SQLSTATE 08007)
-402 (ECPG_CONNECT)
La tentative de connexion la base n'a pas russi. (SQLSTATE 08001)
-403 (ECPG_DUPLICATE_KEY)
Erreur de cl duplique, violation d'une contrainte unique. (SQLSTATE 23505)
-404 (ECPG_SUBSELECT_NOT_ONE)
Un rsultat de la sous-requte n'est pas un enregistrement unique. (SQLSTATE 21000)
-602 (ECPG_WARNING_UNKNOWN_PORTAL)
Un nom de curseur invalide a t spcifi. (SQLSTATE 34000)
-603 (ECPG_WARNING_IN_TRANSACTION)
Transaction en cours. (SQLSTATE 25001)

567

ECPG SQL embarqu en C

-604 (ECPG_WARNING_NO_TRANSACTION)
Il n'y a pas de transaction active (en cours). (SQLSTATE 25P01)
-605 (ECPG_WARNING_PORTAL_EXISTS)
Un nom de curseur existant a t spcifi. (SQLSTATE 42P03)

33.9. Directives de Prprocesseur


Plusieurs directives de prprocesseur sont disponibles, qui modifient comment le prprocesseur ecpg analyse et traite un fichier.

33.9.1. Inclure des Fichiers


Pour inclure un fichier externe dans votre fichier SQL embarqu, utilisez:
EXEC SQL INCLUDE filename;
EXEC SQL INCLUDE <filename>;
EXEC SQL INCLUDE "filename";
Le prprocesseur de SQL embarqu recherchera un fichier appel filename.h, le prprocessera, et l'incluera dans la sortie C
rsultante. En consquence de quoi, les ordres SQL embarqus dans le fichier inclus seront traits correctement.
Le prprocesseurs ecpg cherchera un fichier dans plusieurs rpertoires dans l'ordre suivant:

rpertoire courant

/usr/local/include

Le rpertoire d'inclusion de PostgreSQL, dfini la compilation (par exemple, /usr/local/pgsql/include)

/usr/include

Mais quand EXEC SQL INCLUDE "filename" est utilis, seul le rpertoire courant est parcouru.
Dans chaque rpertoire, le prprocesseur recherchera d'abord le nom de fichier tel que spcifi, et si non trouv, rajoutera .h au
nom de fichier et essaiera nouveau (sauf si le nom de fichier spcifi a dj ce suffixe).
Notez que EXEC SQL INCLUDE est diffrent de:
#include <filename.h>
parce que ce fichier ne serait pas soumis au prprocessing des commandes SQL. Naturellement, vous pouvez continuer d'utiliser la
directive C #include pour inclure d'autres fichiers d'entte. files.

Note
Le nom du fichier inclure est sensible la casse, mme si le reste de la commante EXEC SQL INCLUDE suit les
rgles normales de sensibilit la casse de SQL.

33.9.2. Les Directives define et undef


Similaires aux directives #define qui sont connues en C, le SQL embarqu a un concept similaire:
EXEC SQL DEFINE name;
EXEC SQL DEFINE name value;
Vous pouvez donc dfinir un nom:
EXEC SQL DEFINE HAVE_FEATURE;
Et vous pouvez aussi dfinir des constantes:
EXEC SQL DEFINE MYNUMBER 12;
EXEC SQL DEFINE MYSTRING 'abc';
Utilisez undef pour supprimer une dfinition prcdente:
568

ECPG SQL embarqu en C

EXEC SQL UNDEF MYNUMBER;


Bien sr, vous pouvez continuer d'utiliser les versions C de #define et #undef dans votre programme SQL embarqu. La diffrence est le moment o vos valeurs dfinies sont values. Si vous utilisez EXEC SQL DEFINE alors la prprocesseur ecpg
value les dfinition et substitiue les valeurs. Par exemple si vous crivez:
EXEC SQL DEFINE MYNUMBER 12;
...
EXEC SQL UPDATE Tbl SET col = MYNUMBER;
alors ecpg fera d'emble la substitution et votre compilateur C ne verra jamais aucun nom ou identifiant MYNUMBER. Notez que
vous ne pouvez pas utiliser #define pour une constante que vous allez utiliser dans une requte SQL embarque parce que dans
ce cas le prcompipilateur SQL embarqu n'est pas capable de voir cette dclaration.

33.9.3. Directives ifdef, ifndef, else, elif, et endif


Vous pouvez utiliser les directives suivantes pour compiler des sections de code sous condition:
EXEC SQL ifdef nom;
Vrifie un nom et traite les lignes suivante si nom a t cr avec EXEC SQL define nom.
EXEC SQL ifndef nom;
Vrifie un nom et traite les lignes suivantes si nom n'a pas t cr avec EXEC SQL define nom.
EXEC SQL else;
Traite une section alternative d'une section introduite par soit EXEC SQL ifdef nom soit EXEC SQL ifndef nom.
EXEC SQL elif nom;
Vrifie nom et dmarre une section alternative si nom a t cr avec EXEC SQL define nom.
EXEC SQL endif;
Termine une section alternative.
Exemple:
EXEC
EXEC
EXEC
EXEC
EXEC
EXEC
EXEC

SQL
SQL
SQL
SQL
SQL
SQL
SQL

ifndef TZVAR;
SET TIMEZONE TO 'GMT';
elif TZNAME;
SET TIMEZONE TO TZNAME;
else;
SET TIMEZONE TO TZVAR;
endif;

33.10. Traiter des Programmes en SQL Embarqu


Maintenant que vous avez une ide de comment rdiger des programmes SQL embarqu en C, vous voudrez probablement savoir
comment les compiler. Avant de les compiler, vous passez le fichier dans le prprocesseur C SQL embarqu, qui convertira les
ordres SQL que vous avez utilis vers des appels de fonction spciaux. Ces fonctions rcuprent des donnes partir de leurs arguments, effectuent les commands SQL en utilisant l'interface libpq, et met le rsultat dans les arguments spcifis comme sortie.
Le programme prprocesseur est appel ecpg et fait partie d'une installation normale de PostgreSQL. Les programmes SQL
embarqus sont typiquement nomms avec une extension .pgc. Si vous avez un fichier de programme appel prog1.pgc, vous
pouvez le prprocesser en appelant simplement:
ecpg prog1.pgc
Cela crera un fichier appel prog1.c. Si vos fichiers d'entre ne suivent pas les rgles de nommage suggres, vous pouvez
spcifier le fichier de sortie explicitement en utilisant l'option -o.
Le fichier prprocess peut tre compil normalement, par exemple:
cc -c prog1.c
Les fichiers sources C gnrs incluent les fichiers d'entte de l'installation PostgreSQL, donc si vous avez install
569

ECPG SQL embarqu en C

un endroit qui n'est pas recherch par dfaut, vous devrez ajouter une option comme -I/usr/local/pgsql/include
la ligne de commande de compilation.
Pour lier un programme SQL embarqu, vous aurez besoin d'inclure la librairie libecpg, comme ceci:
cc -o myprog prog1.o prog2.o ... -lecpg
De nouveau, vous pourriez avoir besoin d'ajouter une option comme -L/usr/local/pgsql/lib la ligne de commande.
Si vous grez le processus de compilation d'un projet de grande taille en utilisant make, il serait pratique d'inclure la rgle implicite suivante vos makefiles:
ECPG = ecpg
%.c: %.pgc
$(ECPG) $<
La syntaxe complte de la commande ecpg est dtaille dans ecpg(1).
La librairie ecpg est thread-safe par dfaut. Toutefois, vous aurez peut-tre besoin d'utiliser des options de ligne de commande
spcifiques aux threads pour compiler votre code client.

33.11. Fonctions de la Librairie


La librairie libecpg contient principalement des fonctions caches qui sont utilise pour implmenter les fonctionnalits exprimes par les commandes SQL embarques. Mais il il y quelques fonctions qui peuvent tre appeles directement de faon utile.
Notez que cela rendre votre code non-portable.

ECPGdebug(int on, FILE *stream) active les traces de dboggage si appel avec une valeur diffrente de 0 en premier argument. La trace contient tous les ordres SQL avec toutes les variables d'entres insres, et les rsultats du serveur
PostgreSQL. Cela peut tre trs utile quand vous tes la recherche d'erreurs dans vos ordres SQL.

Note
Sous Windows, si les librairies ecpg et les applications sont compiles avec des options diffrentes, cet appel de
fonction fera planter l'application parce que la reprsentation interne des pointeurs FILE diffre. En particulier,
les options multithreaded/single-threaded, release/debug, et static/dynamic doivent tre les mmes pour la librairie et toutes les applications qui l'utilisent.

ECPGget_PGconn(const char *nom_connexion) retourne le descriteur de connexion la base de donnes de la


librairie identifi par le nom fourni. Si nom_connexion est positionn NULL, le descripteur de connexion courant est retourn. Si aucun descripteur de connexion ne peut tre identifi, la fonction retourne NULL. Le descripteur de connexion retourn peut tre utilis pour appeler toute autre fonction de la libpq, si ncessaire.

Note
C'est une mauvaise ide de manipuler les descripteurs de connexion la base de donne faits par ecpg directement avec des routines de libpq.

ECPGtransactionStatus(const char *nom_connexion) retourne l'tat de la transaction courante de la


connexion identifie par nom_connexion. Voyez Section 31.2, Fonctions de statut de connexion et la fonction de la
libpq PQtransactionStatus() pour les dtails propos des codes d'tat retourns.

ECPGstatus(int lineno, const char* nom_connexion) retoure vrai si vous tes connect une base et faux
sinon. nom_connexion peut valoir NULL si une seule connexion est utilise.

33.12. Large Objects


Les Large objects ne sont pas supports directement par ECPG, mais les application ECPG peuvent manipuler des large objects au
moyen les fonctions large objects de la libpq, en obtenant l'objet PGconn ncessaire par l'appel de la fonction
ECPGget_PGconn. (Toutefois, l'utilisation directe de la fonction ECPGget_PGconn et la manipulation d'objets PGconn devrait tre effectue de faon trs prudente, et idalement pas mlange avec d'autres appels la base par ECPG.)
Pour plus de dtails propos de ECPGget_PGconn, voyez Section 33.11, Fonctions de la Librairie . Pour les informations
570

ECPG SQL embarqu en C

sur les fonctions d'interfaage avec les large objects, voyez Chapitre 32, Objets larges.
Les fonctions large object doivent tre appeles dans un bloc de transaction, donc quand autocommit est off, les commandes BEGIN doivent tre effectues explicitement.
Exemple 33.2, Programme ECPG Accdant un Large Object montre un programme de dmonstration sur les faons de crer,
crire et lire un large object dans une application ECPG.
Exemple 33.2. Programme ECPG Accdant un Large Object

#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<libpq-fe.h>
<libpq/libpq-fs.h>

EXEC SQL WHENEVER SQLERROR STOP;


int
main(void)
{
PGconn
Oid
int
char
int
char
int

*conn;
loid;
fd;
buf[256];
buflen = 256;
buf2[256];
rc;

memset(buf, 1, buflen);
EXEC SQL CONNECT TO testdb AS con1;
conn = ECPGget_PGconn("con1");
printf("conn = %p\n", conn);
/* crer */
loid = lo_create(conn, 0);
if (loid < 0)
printf("lo_create() failed: %s", PQerrorMessage(conn));
printf("loid = %d\n", loid);
/* test d'criture */
fd = lo_open(conn, loid, INV_READ|INV_WRITE);
if (fd < 0)
printf("lo_open() failed: %s", PQerrorMessage(conn));
printf("fd = %d\n", fd);
rc = lo_write(conn, fd, buf, buflen);
if (rc < 0)
printf("lo_write() failed\n");
rc = lo_close(conn, fd);
if (rc < 0)
printf("lo_close() failed: %s", PQerrorMessage(conn));
/* read test */
fd = lo_open(conn, loid, INV_READ);
if (fd < 0)
printf("lo_open() failed: %s", PQerrorMessage(conn));
printf("fd = %d\n", fd);
rc = lo_read(conn, fd, buf2, buflen);
if (rc < 0)
printf("lo_read() failed\n");

571

ECPG SQL embarqu en C

rc = lo_close(conn, fd);
if (rc < 0)
printf("lo_close() failed: %s", PQerrorMessage(conn));
/* vrifier */
rc = memcmp(buf, buf2, buflen);
printf("memcmp() = %d\n", rc);
/* nettoyer */
rc = lo_unlink(conn, loid);
if (rc < 0)
printf("lo_unlink() failed: %s", PQerrorMessage(conn));
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
return 0;
}

33.13. Applications C++


ECPG a un support limit pour les applications C++. Cette section dcrit des piges.
Le prprocesseur ecpg prend un fichier d'entre crit en C (ou quelque chose qui ressemble du C) et des commandes SQL embarques, et convertit les commandes SQL embarques dans des morceaux de langage, et finalement gnre un fichier .c. Les dclarations de fichiers d'entte des fonctions de librairie utilises par les morceaux de langage C que gnre ecpg sont entoures de
blocs extern "C" { ... } quand ils sont utiliss en C++, ils devraient donc fonctionner de faon transparente en C++.
En gnral, toutefois, le prprocesseur ecpg ne comprend que le C; il ne gre pas la syntaxe spciale et les mots rservs du langage C++. Par consquent, du code SQL embarqu crit dans du code d'une application C++ qui utilise des fonctionnalits compliques spcifiques au C++ pourrait ne pas tre prprocess correctement ou pourrait ne pas fonctionner comme prvu.
Une faon sre d'utiliser du code SQL embarqu dans une application C++ est de cacher les appels ECPG dans un module C,
que le code C++ de l'application appelle pour accder la base, et lier ce module avec le reste du code C++. Voyez Section 33.13.2, Dveloppement d'application C++ avec un Module Externe en C ce sujet.

33.13.1. Porte des Variable Htes


Le prprocesseur ecpg comprend la port des variables C. Dans le langage C, c'est plutt simple parce que la porte des variables
ne dpend que du bloc de code dans lequel elle se trouve. En C++, par contre, les variables d'instance sont rfrences dans un
bloc de code diffrent de la position de dclaration, ce qui fait que le prprocesseur ecpg ne comprendra pas la porte des variables d'instance.
Par exemple, dans le cas suivant, le prprocesseur ecpg ne peut pas trouver de dclaration pour la variable dbname dans la mthode test, une erreur va donc se produire.
class TestCpp
{
EXEC SQL BEGIN DECLARE SECTION;
char dbname[1024];
EXEC SQL END DECLARE SECTION;
public:
TestCpp();
void test();
~TestCpp();
};
TestCpp::TestCpp()
{
EXEC SQL CONNECT TO testdb1;
}
void Test::test()
{
EXEC SQL SELECT current_database() INTO :dbname;
printf("current_database = %s\n", dbname);
572

ECPG SQL embarqu en C

}
TestCpp::~TestCpp()
{
EXEC SQL DISCONNECT ALL;
}
Ce code gnrera une erreur comme celle qui suit:
ecpg test_cpp.pgc
test_cpp.pgc:28: ERROR: variable "dbname" is not declared
Pour viter ce problme de porte, la mthode test pourrait tre modifie pour utiliser une variable locale comme stockage intermdiaire. Mais cette approche n'est qu'un mauvais contournement, parce qu'elle rend le code peu lgant et rduit la performance.
void TestCpp::test()
{
EXEC SQL BEGIN DECLARE SECTION;
char tmp[1024];
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT current_database() INTO :tmp;
strlcpy(dbname, tmp, sizeof(tmp));
printf("current_database = %s\n", dbname);
}

33.13.2. Dveloppement d'application C++ avec un Module Externe en C


Si vous comprenez ces limitations techniques du prprocesseur ecpg en C++, vous arriverez peut-tre la conclusion que lier des
objets C et C++ au moment du link pour permettre des applications C++ d'utiliser les fonctionnalits d'ECPG pourrait tre mieux
que d'utiliser des commandes SQL embarques dans du code C++ directement. Cette section dcrit un moyen de sparer des commandes SQL embarques du code d'une application C++ travers un exemple simple. Dans cet exemple, l'application est implmente en C++, alors que C et ECPG sont utiliss pour se connecter au serveur PostgreSQL.
Trois types de fichiers devront tre crs: un fichier C (*.pgc), un fichier d'entte, et un fichier C++:
test_mod.pgc
Un module de routines pour excuter des commandes SQL embarques en C. Il sera converti en test_mod.c par le prprocesseur.
#include "test_mod.h"
#include <stdio.h>
void
db_connect()
{
EXEC SQL CONNECT TO testdb1;
}
void
db_test()
{
EXEC SQL BEGIN DECLARE SECTION;
char dbname[1024];
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT current_database() INTO :dbname;
printf("current_database = %s\n", dbname);
}
void
db_disconnect()
{
EXEC SQL DISCONNECT ALL;
}
573

ECPG SQL embarqu en C

test_mod.h
Un fichier d'entte avec les dclarations des fonctions du module C (test_mod.pgc). Il est inclus par test_cpp.cpp.
Ce fichier devra avoir un bloc extern "C" autour des dclarations, parce qu'il sera li partir d'un module C++.
#ifdef __cplusplus
extern "C" {
#endif
void db_connect();
void db_test();
void db_disconnect();
#ifdef __cplusplus
}
#endif
test_cpp.cpp
Le code principal de l'application, incluant la routine main, et dans cet exemple une classe C++.
#include "test_mod.h"
class TestCpp
{
public:
TestCpp();
void test();
~TestCpp();
};
TestCpp::TestCpp()
{
db_connect();
}
void
TestCpp::test()
{
db_test();
}
TestCpp::~TestCpp()
{
db_disconnect();
}
int
main(void)
{
TestCpp *t = new TestCpp();
t->test();
return 0;
}
Pour constuire l'application, procdez comme suit. Convertissez test_mod.pgc en test_mod.c en lanant ecpg, et gnrez
test_mod.o en compilant test_mod.c avec le compilateur C:
ecpg -o test_mod.c test_mod.pgc
cc -c test_mod.c -o test_mod.o
Puis, gnrez test_cpp.o en compilant test_cpp.cpp avec le compilateur C++:
c++ -c test_cpp.cpp -o test_cpp.o
574

ECPG SQL embarqu en C

Finalement, liez ces objets, test_cpp.o et test_mod.o, dans un excutable, en utilisant le compilateur C++:
c++ test_cpp.o test_mod.o -lecpg -o test_cpp

33.14. Commandes SQL Embarques


Cette section dcrit toutes les commandes SQL qui sont spcifiques au SQL embarqu. Consultez aussi les commandes SQL listes dans Commandes SQL, qui peuvent aussi tre utilise dans du SQL embarqu, sauf mention contraire.

575

ECPG SQL embarqu en C

Nom
ALLOCATE DESCRIPTOR alloue une zone de descripteur SQL

Synopsis
ALLOCATE DESCRIPTOR name

Description
ALLOCATE DESCRIPTOR alloue une nouvelle zone de descripteur SQL nomme, qui pourra tre utilise pour changer des
donnes netre le serveure PostgreSQL et le programme hte.
Les zones de descripteur devraient tre libres aprs utilisation avec la commande DEALLOCATE DESCRIPTOR.

Paramtres
name
Un nom de descripeur SQL, sensible la casse. Il peut tre un identifiant SQL ou une variable hte.

Exemple
EXEC SQL ALLOCATE DESCRIPTOR mydesc;

Compatibilit
ALLOCATE DESCRIPTOR est spcifi par le standard SQL.

Voyez aussi
DEALLOCATE DESCRIPTOR, GET DESCRIPTOR, SET DESCRIPTOR

576

ECPG SQL embarqu en C

Nom
CONNECT tablit une connexion la base de donnes

Synopsis
CONNECT TO connection_target [ AS nom_connexion ] [ USER connection_user_name ]
CONNECT TO DEFAULT
CONNECT connection_user_name
DATABASE connection_target

Description
La commande CONNECT tablit une connexion entre le client et le seurveur PostgreSQL.

Paramtres
connection_target
connection_target spcifie le serveur cible de la connexion dans une des formes suivantes:
[ database_name ] [ @host ] [ :port ]
Se connecter par TCP/IP
unix:postgresql://host [ :port ] / [ database_name ] [ ?connection_option ]
Se connecter par une socket de domaine Unix
tcp:postgresql://host [ :port ] / [ database_name ] [ ?connection_option ]
Se connecter par TCP/IP
constante de type chane SQL
contient une valeur d'une des formes prcdentes
variable hte
variable hte du type char[] ou VARCHAR[] contenant une valeur d'une des formes prcdentes
connection_object
Un identifiant optionnel pour la connexion, afin qu'on puisse y faire rfrence dans d'autres commandes. Cela peut tre un
identifiant SQL ou une variable hte.
connection_user
Le nom d'utilisateur pour une connexion la base de donnes.
Ce paramtre peut aussi spcifier un nom d'utilisateur et un mot de passe, en utilisant une des formes user_name/password, user_name IDENTIFIED BY password, or user_name USING password.
Nom d'utilisateur et mot de passe peuvent tre des identifiants SQL, des constantes de type chane, ou des variables htes.
DEFAULT
Utiliser tous les paramtres de connexion par dfaut, comme dfini par libpq.

Exemples
Voici plusieurs variantes pour spcifier des paramtres de connexion:
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
connectuser;
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT

TO "connectdb" AS main;
TO "connectdb" AS second;
TO "unix:postgresql://200.46.204.71/connectdb" AS main USER
TO
TO
TO
TO
TO
TO
TO
TO

"unix:postgresql://localhost/connectdb" AS main USER connectuser;


'connectdb' AS main;
'unix:postgresql://localhost/connectdb' AS main USER :user;
:db AS :id;
:db USER connectuser USING :pw;
@localhost AS main USER connectdb;
REGRESSDB1 as main;
AS main USER connectdb;
577

ECPG SQL embarqu en C

EXEC SQL CONNECT


EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
connectpw;
EXEC SQL CONNECT
BY connectpw;
EXEC SQL CONNECT
EXEC SQL CONNECT
EXEC SQL CONNECT
BY "connectpw";
EXEC SQL CONNECT
"connectpw";
EXEC SQL CONNECT
connectuser;

TO
TO
TO
TO
TO
TO

connectdb AS :id;
connectdb AS main USER connectuser/connectdb;
connectdb AS main;
connectdb@localhost AS main;
tcp:postgresql://localhost/ USER connectdb;
tcp:postgresql://localhost/connectdb USER connectuser IDENTIFIED BY

TO tcp:postgresql://localhost:20/connectdb USER connectuser IDENTIFIED


TO unix:postgresql://localhost/ AS main USER connectdb;
TO unix:postgresql://localhost/connectdb AS main USER connectuser;
TO unix:postgresql://localhost/connectdb USER connectuser IDENTIFIED
TO unix:postgresql://localhost/connectdb USER connectuser USING
TO unix:postgresql://localhost/connectdb?connect_timeout=14 USER

Voici un programme exemple qui illustre l'utilisation de variables htes pour spcifier des paramtres de connexion:
int
main(void)
{
EXEC SQL BEGIN DECLARE
char *dbname
=
char *user
=
char *connection =

SECTION;
"testdb";
/* nom de la base */
"testuser"; /* nom d'utilisateur pour la connexion */
"tcp:postgresql://localhost:5432/testdb";
/* chane de connexion */
char ver[256];
/* buffer pour contenir la chane de version */
EXEC SQL END DECLARE SECTION;
ECPGdebug(1, stderr);
EXEC SQL CONNECT TO :dbname USER :user;
EXEC SQL SELECT version() INTO :ver;
EXEC SQL DISCONNECT;
printf("version: %s\n", ver);
EXEC SQL CONNECT TO :connection USER :user;
EXEC SQL SELECT version() INTO :ver;
EXEC SQL DISCONNECT;
printf("version: %s\n", ver);
return 0;
}

Compatibilit
CONNECT est spcifi dans le standard SQL, mais le format des paramtres de connexion est spcifique l'implmentation.

Voyez aussi
DISCONNECT, ???

578

ECPG SQL embarqu en C

Nom
DEALLOCATE DESCRIPTOR dsalloue une zone de descripteur SQL

Synopsis
DEALLOCATE DESCRIPTOR name

Description
DEALLOCATE DESCRIPTOR dsalloue une zone de descripteur SQL nomme.

Parameters
name
Le nom du descripteur qui va tre dsallou. Il est sensible la casse. Cela peut-tre un identifiant SQL ou une variable hte.

Exemples
EXEC SQL DEALLOCATE DESCRIPTOR mydesc;

Compatibilit
DEALLOCATE DESCRIPTOR est spcifi dans le standard SQL

See Also
ALLOCATE DESCRIPTOR, GET DESCRIPTOR, SET DESCRIPTOR

579

ECPG SQL embarqu en C

Nom
DECLARE definit un curseur

Synopsis
DECLARE
WITHOUT
DECLARE
WITHOUT

nom_curseur [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH |


} HOLD ] FOR nom_prepare
nom_curseur [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH |
} HOLD ] FOR query

Description
DECLARE dclare un cusreur pour itrer sur le jeu de rsultat d'une requte prpare. Cette commande a une smantique lgrement diffrente de celle de l'ordre SQL direct DECLARE: L ou ce dernier excute une requte et prpare le jeu de rsultat pour
la rcupration, cette commande SQL embarqu se contente de dclarer un nom comme variable de boucle pour itrer sur le
rsultat d'une requte; l'excution relle se produit quand le curseur est ouvert avec la commande OPEN.

Paramtres
nom_curseur
Un nom de curseur, sensible la casse. Cela peut tre un identifiant SQL ou une variable hte.
nom_prepare
Le nom de l'une requte prpare, soit comme un identifiant SQL ou comme une variable hte.
query
Une commande SELECT(7) ou VALUES(7) qui fournira les enregistrements que le curseur devra retourner.
Pour la signification des options du curseur, voyez DECLARE(7).

Exemples
Exemples de dclaration de curseur pour une requte:
EXEC SQL DECLARE C CURSOR FOR SELECT * FROM My_Table;
EXEC SQL DECLARE C CURSOR FOR SELECT Item1 FROM T;
EXEC SQL DECLARE cur1 CURSOR FOR SELECT version();
Un exemple de dclaration de curseur pour une requte prpare:
EXEC SQL PREPARE stmt1 AS SELECT version();
EXEC SQL DECLARE cur1 CURSOR FOR stmt1;

Compatibilit
DECLARE est spcifi dans le standard SQL.

Voyez aussi
OPEN, CLOSE(7), DECLARE(7)

580

ECPG SQL embarqu en C

Nom
DESCRIBE obtient des informations propos d'une requte prpare ou d'un jeu de rsultat

Synopsis
DESCRIBE [ OUTPUT ] nom_prepare USING [ SQL ] DESCRIPTOR nom_descripteur
DESCRIBE [ OUTPUT ] nom_prepare INTO [ SQL ] DESCRIPTOR nom_descripteur
DESCRIBE [ OUTPUT ] nom_prepare INTO nom_sqlda

Description
DESCRIBE rcupre des informations sur les mtadonnes propos des colonnes de rsultat contenues dans une requte prpare, sans dclencher la rcupration d'un enregistrement.

Parameters
nom_prepare
Le nom d'une requte prpare. Cela peut tre un identifiant SQL ou une variable hte.
nom_descripteur
Un nom de descriteur. Il est sensible la casse. Cela peut tre un identifiant SQL ou une variable hte.
nom_sqlda
Le nom d'une variable SQLDA.

Exemples
EXEC
EXEC
EXEC
EXEC
EXEC

SQL
SQL
SQL
SQL
SQL

ALLOCATE DESCRIPTOR mydesc;


PREPARE stmt1 FROM :sql_stmt;
DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;
GET DESCRIPTOR mydesc VALUE 1 :charvar = NAME;
DEALLOCATE DESCRIPTOR mydesc;

Compatibilit
DESCRIBE est spcifi dans le standard SQL.

Voyez aussi
ALLOCATE DESCRIPTOR, GET DESCRIPTOR

581

ECPG SQL embarqu en C

Nom
DISCONNECT met fin une connexion de base de donnes

Synopsis
DISCONNECT
DISCONNECT
DISCONNECT
DISCONNECT

nom_connexion
[ CURRENT ]
DEFAULT
ALL

Description
DISCONNECT ferme une connexion (ou toutes les connexions) la base de donnes.

Paramtres
nom_connexion
Une connexion la base tablie par la commande CONNECT.
CURRENT
Ferme la connexion courante , qui est soit la connexion ouverte la plus rcemment, soit la connexion spcifie par la commande SET CONNECTION. C'est aussi la valeur par dfaut si aucun argument n'est donn la commande DISCONNECT.
DEFAULT
Ferme la connexion par dfaut.
ALL
Ferme toutes les connexions ouvertes.

Exemples
int
main(void)
{
EXEC SQL
EXEC SQL
EXEC SQL
EXEC SQL

CONNECT
CONNECT
CONNECT
CONNECT

TO
TO
TO
TO

testdb
testdb
testdb
testdb

AS
AS
AS
AS

EXEC SQL DISCONNECT CURRENT;


EXEC SQL DISCONNECT DEFAULT;
EXEC SQL DISCONNECT ALL;

DEFAULT USER testuser;


con1 USER testuser;
con2 USER testuser;
con3 USER testuser;
/* close con3
*/
/* close DEFAULT
*/
/* close con2 and con1 */

return 0;
}

Compatibilit
DISCONNECT est spcifi dans le standard SQL.

Voyez aussi
CONNECT, ???

582

ECPG SQL embarqu en C

Nom
EXECUTE IMMEDIATE prpare et excute un ordre dynamique

Synopsis
EXECUTE IMMEDIATE chaine

Description
EXECUTE IMMEDIATE prpare et excute immdiatement un ordre SQL spcifi dynamiquement, sans rcuprer les enregistrements du rsultat.

Paramtres
chaine
Une chane C littrale ou une variable hte contenant l'ordre SQL excuter.

Exemples
Voici un exemple qui excute un ordre INSERT en utilisant EXECUTE IMMEDIATE et une variable hte appele commande:
sprintf(commande, "INSERT INTO test (name, amount, letter) VALUES ('db: ''r1''', 1,
'f')");
EXEC SQL EXECUTE IMMEDIATE :commande;

Compatibility
EXECUTE IMMEDIATE est spcifi dans le standard SQL.

583

ECPG SQL embarqu en C

Nom
GET DESCRIPTOR rcupre des informations d'une zone de descripteur SQL

Synopsis
GET DESCRIPTOR nom_descripteur :cvariable = element_entete_descripteur [, ... ]
GET DESCRIPTOR nom_descripteur VALUE numero_colonne :cvariable = element_descripteur [,
... ]

Description
GET DESCRIPTOR rcupre des informations propos du rsultat d'une requte partir d'une zone de descripteur SQL et les
stocke dans des variables htes. Une zone de descripteur est d'ordinaire remplie en utilisant FETCH ou SELECT avant d'utiliser
cette commande pour transfrer l'information dans des variables du langage hte.
Cette commande a deux formes: la premire forme rcupre les objets de l'entte du descripteur, qui s'appliquent au jeu de rsultat dans son ensemble. Un exemple est le nombre d'enregistrements. La seconde forme, qui ncessite le nombre de colonnes
comme paramtre additionnel, rcupre des informations sur une colonne particulire. Par exemple, le type de la colonne, et la valeur relle de la colonne.

Paramtres
nom_descripteur
Un nom de descripteur.
element_entete_descripteur
Un marqueur identifiant de quel objet de l'entte rcuprer l'information. Seul COUNT, qui donne le nombre de colonnes dans
le rsultat, est actuellement support.
numero_colonne
Le numro de la colonne propos duquel on veut rcuprer des informations. Le compte commence 1.
element_descripteur
Un marqueur identifiant quel lment d'information rcuprer d'une colonne. Voyez Section 33.7.1, Zones de Descripteur
SQL nommes pour une liste d'objets supports.
cvariable
Une variable hte qui recevra les donnes rcupres de la zone de descripteur.

Exemples
Un exemple de rcupration du nombre de colonnes dans un rsultat:
EXEC SQL GET DESCRIPTOR d :d_count = COUNT;
Un exemple de rcupration de la longueur des donnes de la premire colonne:
EXEC SQL GET DESCRIPTOR d VALUE 1 :d_returned_octet_length = RETURNED_OCTET_LENGTH;
Un exemple de rcupration des donnes de la seconde colonne en tant que chane:
EXEC SQL GET DESCRIPTOR d VALUE 2 :d_data = DATA;
Voici un exemple pour la procdure complte, lors de l'excution de SELECT current_database(); et montrant le nombre
de colonnes, la longueur de la colonne, et la donnes de la colonne:
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
int d_count;
584

ECPG SQL embarqu en C

char d_data[1024];
int d_returned_octet_length;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb AS con1 USER testuser;
EXEC SQL ALLOCATE DESCRIPTOR d;
/* Dclarer un curseur, l'ouvrir, et assigner un descripteur au curseur */
EXEC SQL DECLARE cur CURSOR FOR SELECT current_database();
EXEC SQL OPEN cur;
EXEC SQL FETCH NEXT FROM cur INTO SQL DESCRIPTOR d;
/* Rcuprer le nombre total de colonnes */
EXEC SQL GET DESCRIPTOR d :d_count = COUNT;
printf("d_count
= %d\n", d_count);
/* Rcuprer la longueur d'une colonne retourne */
EXEC SQL GET DESCRIPTOR d VALUE 1 :d_returned_octet_length = RETURNED_OCTET_LENGTH;
printf("d_returned_octet_length = %d\n", d_returned_octet_length);
/* Rcuprer la conlonne retourne en tant que chane */
EXEC SQL GET DESCRIPTOR d VALUE 1 :d_data = DATA;
printf("d_data
= %s\n", d_data);
/* Fermer */
EXEC SQL CLOSE cur;
EXEC SQL COMMIT;
EXEC SQL DEALLOCATE DESCRIPTOR d;
EXEC SQL DISCONNECT ALL;
return 0;
}
Quand l'exemple est excut, son rsultat ressemble ceci:
d_count
= 1
d_returned_octet_length = 6
d_data
= testdb

Compatibilit
GET DESCRIPTOR est spcifi dans le standard SQL.

Voir aussi
ALLOCATE DESCRIPTOR, SET DESCRIPTOR

585

ECPG SQL embarqu en C

Nom
OPEN ouvre un curseur dynamique

Synopsis
OPEN nom_curseur
OPEN nom_curseur USING valeur [, ... ]
OPEN nom_curseur USING SQL DESCRIPTOR nom_descripteur

Description
OPEN ouvre un curseur et optionnellement lie (bind) les valeurs aux conteneurs (placeholders) dans la dclaration du curseur. Le
curseur doit pralablement avoir t dclar avec la commande DECLARE. L'excution d'OPEN dclenche le dbut de
l'excution de la requte sur le serveur.

Paramtres
nom_curseur
Le nom du curseur ouvrir. Cela peut tre un identifiant SQL ou une variable hte.
valeur
Une valeur lier au placeholder du curseur. Cela peut tre une constante SQL, une variable hte, ou une variable hte avec
indicateur.
nom_descripteur
Le nom du descripteur contenant les valeurs attacher aux placeholders du curseur. Cela peut tre un identifiant SQL ou une
variable hte.

Exemples
EXEC
EXEC
EXEC
EXEC

SQL
SQL
SQL
SQL

OPEN
OPEN
OPEN
OPEN

a;
d USING 1, 'test';
c1 USING SQL DESCRIPTOR mydesc;
:curname1;

Compatibilit
OPEN est spcifie dans le standard SQL.

Voir aussi
DECLARE, CLOSE(7)

586

ECPG SQL embarqu en C

Nom
PREPARE prpare un ordre pour son excution

Synopsis
PREPARE nom FROM chane

Description
PREPARE prpare l'excution d'un ordre spcifi dynamiquement sous forme d'une chane. C'est diffrent des ordres SQL directs
PREPARE(7), qui peuvent aussi tre utiliss dans des programmes embarqus. La commande EXECUTE(7) peut tre utilise
pour excuter les deux types de requtes prpares.

Paramtres
nom_prepare
Un identifiant pour la requte prpare.
chane
Une chane littrale C ou une variable hte contenant un ordre SQL prparable, soit SELECT, INSERT, UPDATE ou DELETE.

Exemples
char *stmt = "SELECT * FROM test1 WHERE a = ? AND b = ?";
EXEC SQL ALLOCATE DESCRIPTOR outdesc;
EXEC SQL PREPARE foo FROM :stmt;
EXEC SQL EXECUTE foo USING SQL DESCRIPTOR indesc INTO SQL DESCRIPTOR outdesc;

Compatibilit
PREPARE est spcifi dans le standard SQL.

Voir aussi
CONNECT, DISCONNECT

587

ECPG SQL embarqu en C

Nom
SET DESCRIPTOR positionne des informations dans une zone de descripteur SQL

Synopsis
SET DESCRIPTOR nom_descripteur objet_entete_descripteur = valeur [, ... ]
SET DESCRIPTOR nom_descripteur VALUE numero objet_descripteur = valeur [, ...]

Description
SET DESCRIPTOR remplit une zone de descripteur SQL de valeurs. La zone de descripteur est habituellement utilise pour lier
les paramtres lors d'une excution de requte prpare
Cette commande a deux formes: la premire forme s'applique l' entte du descripteur, qui est indpendant des donnes spcifiques. La seconde forme assigne des valeurs aux donnes, identifies par un numro.

Paramtres
nom_descripteur
Un nom de descripteur.
objet_entete_descripteur
Un identifiant pour spcifier quelle information de l'entte est concerne. Seul COUNT, qui sert indiquer le nombre de descripteurs, est support pour le moment.
number
Le numro de l'objet du descripteur modifier. Le compte commence 1.
objet_descripteur
Un identifiant spcifiant quelle information du descripteur est concerne. Voyez Section 33.7.1, Zones de Descripteur SQL
nommes pour une liste des identifiants supports.
valeur
Une valeur stocker dans l'objet descripteur. Cela peut tre une constante SQL ou une variable hte.

Exemples
EXEC
EXEC
EXEC
EXEC
EXEC

SQL
SQL
SQL
SQL
SQL

SET
SET
SET
SET
SET

DESCRIPTOR
DESCRIPTOR
DESCRIPTOR
DESCRIPTOR
DESCRIPTOR

indesc
indesc
indesc
indesc
indesc

COUNT
VALUE
VALUE
VALUE
VALUE

=
1
1
2
2

1;
DATA = 2;
DATA = :val1;
INDICATOR = :val1, DATA = 'some string';
INDICATOR = :val2null, DATA = :val2;

Compatibilit
SET DESCRIPTOR est spcifi dans le standard SQL.

Voyez aussi
ALLOCATE DESCRIPTOR, GET DESCRIPTOR

588

ECPG SQL embarqu en C

Nom
TYPE dfinit un nouveau type de donnes

Synopsis
TYPE nom_type IS ctype

Description
La commande TYPE dfinit un nouveau type C. C'est quivalent mettre un typedef dans une section declare.
Cette commande n'est reconnue que quand ecpg est excute avec l'option -c.

Paramtres
nom_type
Le nom du nouveau type. Ce doit tre un nom de type valide en C.
ctype
Une spcification de type C.

Exemples
EXEC SQL TYPE customer IS
struct
{
varchar name[50];
int
phone;
};
EXEC SQL TYPE cust_ind IS
struct ind
{
short
name_ind;
short
phone_ind;
};
EXEC
EXEC
EXEC
EXEC
EXEC

SQL
SQL
SQL
SQL
SQL

TYPE
TYPE
TYPE
TYPE
TYPE

c IS char reference;
ind IS union { int integer; short smallint; };
intarray IS int[AMOUNT];
str IS varchar[BUFFERSIZ];
string IS char[11];

Voici un programme de dmonstration qui utilise EXEC SQL TYPE:


EXEC SQL WHENEVER SQLERROR SQLPRINT;
EXEC SQL TYPE tt IS
struct
{
varchar v[256];
int
i;
};
EXEC SQL TYPE tt_ind IS
struct ind {
short
v_ind;
short
i_ind;
};
int
main(void)
{
589

ECPG SQL embarqu en C

EXEC SQL BEGIN DECLARE SECTION;


tt t;
tt_ind t_ind;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb AS con1;
EXEC SQL SELECT current_database(), 256 INTO :t:t_ind LIMIT 1;
printf("t.v = %s\n", t.v.arr);
printf("t.i = %d\n", t.i);
printf("t_ind.v_ind = %d\n", t_ind.v_ind);
printf("t_ind.i_ind = %d\n", t_ind.i_ind);
EXEC SQL DISCONNECT con1;
return 0;
}
La sortie de ce programme ressemble ceci:
t.v = testdb
t.i = 256
t_ind.v_ind = 0
t_ind.i_ind = 0

Compatibilit
La commande TYPE est une extension PostgreSQL.

590

ECPG SQL embarqu en C

Nom
VAR dfinit une variable

Synopsis
VAR nomvar IS ctype

Description
La commande VAR affecte un nouveau type de donnes C une variable hte. La variable de l'hte doit avoir t dfini pralablement dans une section declare.

Parameters
nomvar
Un nom de variable C.
ctype
Une spcification de type C.

Exemples
Exec sql begin declare section;
short a;
exec sql end declare section;
EXEC SQL VAR a IS int;

Compatibilit
La commande VAR est une extension PostgreSQL.

591

ECPG SQL embarqu en C

Nom
WHENEVER spcifie l'action effectuer quand un ordre SQL entrane le dclenchement d'une classe d'exception

Synopsis
WHENEVER { NOT FOUND | SQLERROR | SQLWARNING } action

Description
Dfinit un comportement qui sera appel dans des cas spciaux ( enregistrements non trouvs, avertissements ou erreurs SQL)
dans le rsultat de l'excution SQL.

Paramtres
Voyez Section 33.8.1, Mettre en Place des Callbacks pour une description des paramtres.

Exemples
EXEC
EXEC
EXEC
EXEC
EXEC
EXEC
EXEC
EXEC
EXEC
EXEC
EXEC

SQL
SQL
SQL
SQL
SQL
SQL
SQL
SQL
SQL
SQL
SQL

WHENEVER
WHENEVER
WHENEVER
WHENEVER
WHENEVER
WHENEVER
WHENEVER
WHENEVER
WHENEVER
WHENEVER
WHENEVER

NOT FOUND CONTINUE;


NOT FOUND DO BREAK;
SQLWARNING SQLPRINT;
SQLWARNING DO warn();
SQLERROR sqlprint;
SQLERROR CALL print2();
SQLERROR DO handle_error("select");
SQLERROR DO sqlnotice(NULL, NONO);
SQLERROR DO sqlprint();
SQLERROR GOTO error_label;
SQLERROR STOP;

Une application classique est l'utilisation de WHENEVER NOT FOUND BREAK pour grer le bouclage sur des jeux de rsultats:
int
main(void)
{
EXEC SQL
EXEC SQL
EXEC SQL
EXEC SQL

CONNECT TO testdb AS con1;


ALLOCATE DESCRIPTOR d;
DECLARE cur CURSOR FOR SELECT current_database(), 'hoge', 256;
OPEN cur;

/* quand la fin du jeu de rsultat est atteinte, sortir de la boucle */


EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH NEXT FROM cur INTO SQL DESCRIPTOR d;
...
}
EXEC SQL CLOSE cur;
EXEC SQL COMMIT;
EXEC SQL DEALLOCATE DESCRIPTOR d;
EXEC SQL DISCONNECT ALL;
return 0;
}

Compatibilit
WHENEVER est spcifi dans le standard SQL, mais la plupart des actions sont des extensions PostgreSQL.

592

ECPG SQL embarqu en C

33.15. Mode de Compatibilit Informix


ecpg peut tre excut dans un mode appel mode de compatibilit Informix. Si ce mode est actif, il essaye de se comport comme
s'il tait le prcompilateur Informix pour Informix E/SQL. En gros, cela va vous permettre d'utiliser le signe dollar au lieu de
la primitive EXEC SQL pour fournir des commandes SQL embarques:
$int j = 3;
$CONNECT TO :dbname;
$CREATE TABLE test(i INT PRIMARY KEY, j INT);
$INSERT INTO test(i, j) VALUES (7, :j);
$COMMIT;

Note
Il ne doit par y avoir d'espace entre le $ et la directive de prprocesseur qui le suit, c'est dire include, define,
ifdef, etc. Sinon, le prprocesseur comprendra le mot comme une variable hte.
Il y a deux modes de compatibilit: INFORMIX, INFORMIX_SE
Quand vous liez des programmes qui sont dans ce mode de compatibilit, rappelez vous de lier avec libcompat qui est fournie
avec ECPG.
En plus du sucre syntaxique expliqu prcdemment, le mode de compatibilit Informix porte d'ESQL vers ECPG quelques
fonctions pour l'entre, la sortie et la transformation des donnes, ainsi que pour le SQL embarqu.
Le mode de compatibilit Informix est fortement connect la librairie pgtypeslib d'ECPG. pgtypeslib met en correspondance
les types de donnes SQL et les types de donnes du programme hte C et la plupart des fonctions additionnelles du mode de
compatibilit Informix vous permettent de manipuler ces types C des programmes htes. Notez toutefois que l'tendue de cette
compatibilit est limite. Il n'essaye pas de copier le comportement d'Informix; il vous permet de faire plus ou mois les mmes
oprations et vou fournit des fonctions qui ont le mme nom et ont la base le mme comportement, mais ce n'est pas un produit
de remplacement transparent si vous utilisez Informix l'heure actuelle. De plus, certains types de donnes sont diffrents. Par
exemple, les types datetime et interval de PostgreSQL ne savent pas traiter des ranges comme par exemple YEAR TO
MINUTE, donc vous n'aurez pas de support pour cela dans ECPG non plus.

33.15.1. Additional Types


Le pseudo-type "string" spcifique Informix pour stocker des chanes de caractres ajustes droite est maintenant support
dans le mode Informix sans avoir besoin d'utiliser typedef. En fait, en mode Informix, ECPG refuse de traiter les fichiers
sources qui contiennent typedef untype string;
EXEC SQL BEGIN DECLARE SECTION;
string userid; /* cette variable contient des donnes ajustes */
EXEC SQL END DECLARE SECTION;
EXEC SQL FETCH MYCUR INTO :userid;

33.15.2. Ordres SQL Embarqus Supplmentaires/Manquants


CLOSE DATABASE
Cet ordre ferme la connexion courante. En fait, c'est un synonyme du DISCONNECT CURRENT d'ECPG:
$CLOSE DATABASE;
EXEC SQL CLOSE DATABASE;

/* ferme la connexion courante */

FREE nom_curseur
En raison des diffrences sur la faon dont ECPG fonctionne par rapport l'ESQL/C d'Informix (c'est dire quelles tapes
sont purement des transformations grammaticales et quelles tapes s'appuient sur la librairie sous-jacente), il n'y a pas d'ordre
FREE nom_curseur dans ECPG. C'est parce que, dans ECPG, DECLARE CURSOR ne gnre pas un appel de fonction
la librairie qui utilise le nom du curseur. Ce qui implique qu'il n'y a pas grer les curseurs SQL l'excution dans la librairie
ECPG, seulement dans le serveur PostgreSQL.
FREE nom_requete
593

ECPG SQL embarqu en C

FREE nom_requete est un synonyme de DEALLOCATE PREPARE nom_requete.

33.15.3. Zones de Descripteurs SQLDA Compatibles Informix


Le mode de compatibilit Informix supporte une structure diffrente de celle dcrite dans Section 33.7.2, Zones de Descripteurs
SQLDA . Voyez ci-dessous:
struct sqlvar_compat
{
short
sqltype;
int
sqllen;
char
*sqldata;
short *sqlind;
char
*sqlname;
char
*sqlformat;
short
sqlitype;
short
sqlilen;
char
*sqlidata;
int
sqlxid;
char
*sqltypename;
short
sqltypelen;
short
sqlownerlen;
short
sqlsourcetype;
char
*sqlownername;
int
sqlsourceid;
char
*sqlilongdata;
int
sqlflags;
void
*sqlreserved;
};
struct sqlda_compat
{
short sqld;
struct sqlvar_compat *sqlvar;
char
desc_name[19];
short desc_occ;
struct sqlda_compat *desc_next;
void *reserved;
};
typedef struct sqlvar_compat
typedef struct sqlda_compat

sqlvar_t;
sqlda_t;

Les proprits globales sont:


sqld
Le nombre de champs dans le descripteur SQLDA.
sqlvar
Un pointeur vers les proprits par champ.
desc_name
Inutilis, rempli d'octets zro.
desc_occ
La taille de la structure alloue.
desc_next
Un pointeur vers la structure SQLDA suivante si le jeu de rsultat contient plus d'un enregistrement.
reserved
Pointeur inutilis, contient NULL. Gard pour la compatibilit Informix.
Les proprits par champ sont ci-dessous, elles sont stockes dans le tableau sqlvar:
sqltype
Type du champ. Les constantes sont dans sqltypes.h
sqllen
594

ECPG SQL embarqu en C

La longueur du champ de donnes. Length of the field data.


sqldata
Un pointeur vers le champ de donnes. Ce pointeur est de type char*, la donne pointe par lui est en format binaire. Par
exemple:
int intval;
switch (sqldata->sqlvar[i].sqltype)
{
case SQLINTEGER:
intval = *(int *)sqldata->sqlvar[i].sqldata;
break;
...
}
sqlind
Un pointeur vers l'indicateur NULL. Si retourn par DESCRIBE ou FETCH alors c'est toujours un pointeur valide. Si utilis
comme valeur d'entre pour EXECUTE ... USING sqlda; alors une valeur de pointeur NULL signifie que la valeur
pour ce champ est non nulle. Sinon, un pointeur valide et sqlitype doivent tre positionns correctement. Par exemple:
if (*(int2 *)sqldata->sqlvar[i].sqlind != 0)
printf("value is NULL\n");
sqlname
Le nom du champ. Chane termine par 0.
sqlformat
Rserv dans Informix, valeurs de PQfformat() pour le champ.
sqlitype
Type de l'indicateur de donnes NULL. C'est toujours SQLSMINT quand les donnes sont retournes du serveur. Quand la
SQLDA est utilise pour une requte paramtrique, la donne est traite en fonction du type de donne positionn.
sqlilen
Longueur de l'indicateur de donnes NULL.
sqlxid
Type tendu du champ, rsultat de PQftype().
sqltypename, sqltypelen, sqlownerlen, sqlsourcetype, sqlownername, sqlsourceid, sqlflags, sqlreserved
Inutilis.
sqlilongdata
C'est gal sqldata si sqllen est plus grand que 32KB.
Par exemple:
EXEC SQL INCLUDE sqlda.h;
sqlda_t
embarque */

*sqlda; /* Ceci n'a pas besoin d'tre dans la DECLARE SECTION

EXEC SQL BEGIN DECLARE SECTION;


char *prep_stmt = "select * from table1";
int i;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL PREPARE mystmt FROM :prep_stmt;
EXEC SQL DESCRIBE mystmt INTO sqlda;
printf("# of fields: %d\n", sqlda->sqld);
for (i = 0; i < sqlda->sqld; i++)
printf("field %d: \"%s\"\n", sqlda->sqlvar[i]->sqlname);
595

ECPG SQL embarqu en C

EXEC SQL DECLARE mycursor CURSOR FOR mystmt;


EXEC SQL OPEN mycursor;
EXEC SQL WHENEVER NOT FOUND GOTO out;
while (1)
{
EXEC SQL FETCH mycursor USING sqlda;
}
EXEC SQL CLOSE mycursor;
free(sqlda); /* La structure principale doit tre totalement libre par free()
* sqlda and sqlda->sqlvar sont dans une seule zone alloue */
Pour
plus
d'informatinos,
voyez
l'entte
sqlda.h
faces/ecpg/test/compat_informix/sqlda.pgc.

et

le

test

de

non-rgression

src/inter-

33.15.4. Fonctions Additionnelles


decadd
Ajoute deux valeurs dcimales.
int decadd(decimal *arg1, decimal *arg2, decimal *sum);
La fonction reoit un poiteur sur la premire oprande de type decimal (arg1), un pointeur sur la seconde oprande de type
decimal (arg2) et un pointeur sur la valeur de type decimal qui contiendra la somme (sum). En cas de succs, la fonction retourne
0.
ECPG_INFORMIX_NUM_OVERFLOW
est
retourn
en
cas
de
dpassement
et
ECPG_INFORMIX_NUM_UNDERFLOW en cas de soupassement. -1 est retourn pour les autres checs et errno est positionn au nombre correspondant errno de pgtypeslib. pgtypeslib.
deccmp
Compare deux variables de type decimal.
int deccmp(decimal *arg1, decimal *arg2);
La fonction reoit un pointeur vers la premire valeur decimal (arg1), un pointeur vers la seconde valeur decimal (arg2) et
retourne une valeur entire qui indique quelle elle la plus grosse valeur.

1, si la valeur pointe par arg1 est plus grande que celle pointe par arg2.

-1 si la valeur pointe par arg1 est plus petite que la valeur pointe par arg2.

0 si les deux valeurs pointes par arg1 et arg2 sont gales.

deccopy
Copie une valeur decimal.
void deccopy(decimal *src, decimal *target);
La fonction reoin un pointeur vers la valeur decimal qui doit tre copie comme premier argument (src) et un pointeur vers
la structure de type decimale cible (target) comme second argument.
deccvasc
Convertit une valeur de sa reprsentation ASCII vers un type decimal.
int deccvasc(char *cp, int len, decimal *np);
La fonction reoit un pointeur vers une chane qui contient la reprsentation chane du nombre convertir (cp) ainsi que sa
longueur len. np est un pointeur vers la valeur decimal dans laquelle sauver le rsultat de l'opration.
Voici quelques formats valides: -2, .794, +3.44, 592.49E07 ou -32.84e-4.
La fonction retourne 0 en cas de succs. Si un dpassement ou un soupassement se produisent,
ECPG_INFORMIX_NUM_OVERFLOW ou ECPG_INFORMIX_NUM_UNDERFLOW est retourn. Si la reprsentation ASCII
n'a pas pu tre interprte, ECPG_INFORMIX_BAD_NUMERIC est retourn ou ECPG_INFORMIX_BAD_EXPONENT si le
596

ECPG SQL embarqu en C

problme s'est produit lors de l'analyse de l'exposant.


deccvdbl
Convertit une valeur de type double vers une valeur de type decimal.
int deccvdbl(double dbl, decimal *np);
La fonction reoit la variable de type double qui devrait tre convertie comme premier argument (dbl). Comme second argument (np), la fonction reoit un pointeur vers la variable decimal qui recevra le rsultat de l'opration.
La fonction retourne 0 en cas de succs et une valeur ngative si la conversion a chou.
deccvint
Convertit une valeur de type int vers une valeur de type decimal.
int deccvint(int in, decimal *np);
La fonction reoit la variable de type int convertir comme premier argument (in). Comme second argument (np), la fonction reoit un pointeur vers la variable decimal qui recevra le rsultat de l'opration.
La fonction retourne 0 en cas de succs et une valeur ngative si la conversion a chou.
deccvlong
Convertit une valeur de type long vers une valeur de type decimal. Convert a value of type long to a value of type decimal.
int deccvlong(long lng, decimal *np);
La fonction reoit la variable de type long convertir comme premier argument (lng). Comme second argument (np), la
fonction reoit un pointeur vers la variable decimal qui recevra le rsultat de l'opration.
La fonction retourne 0 en cas de succs et une valeur ngative si la conversion a chou.
decdiv
Divise deux variables de type decimal.
int decdiv(decimal *n1, decimal *n2, decimal *result);
La fonction reoit des pointeurs vers les deux variables qui sont le premier (n1) et le second (n2) oprandes et calcule n1/n2.
result est un pointeur vers la variable qui recevra le rsultat de l'opration.
En cas de succs, 0 est retourn, et une valeur ngative si la division choue. En cas de dpassement ou de soupassement, la
fonction retourne ECPG_INFORMIX_NUM_OVERFLOW ou ECPG_INFORMIX_NUM_UNDERFLOW respectivement. Si une
tentative de division par zro se produit, la fonction retourne ECPG_INFORMIX_NUM_OVERFLOW.
decmul
Multiplie deux valeurs decimal.
int decmul(decimal *n1, decimal *n2, decimal *result);
La fonction reoit des pointeurs vers les deux variables qui sont le premier (n1) et le second (n2) oprandes et calcule n1/n2.
result est un pointeur vers la variable qui recevra le rsultat de l'opration.
En cas de succs, 0 est retourn, et une valeur ngative si la division choue. En cas de dpassement ou de soupassement, la
fonction retourne ECPG_INFORMIX_NUM_OVERFLOW ou ECPG_INFORMIX_NUM_UNDERFLOW respectivement.
decsub
Soustrait une valeur decimal d'une autre.
int decsub(decimal *n1, decimal *n2, decimal *result);
La fonction reoit des pointeurs vers les deux variables qui sont le premier (n1) et le second (n2) oprandes et calcule n1/n2.
result est un pointeur vers la variable qui recevra le rsultat de l'opration.
En cas de succs, 0 est retourn, et une valeur ngative si la division choue. En cas de dpassement ou de soupassement, la
fonction retourne ECPG_INFORMIX_NUM_OVERFLOW ou ECPG_INFORMIX_NUM_UNDERFLOW respectivement.
dectoasc
Convertit une variable de type decimal vers sa reprsentation ASCII sous forme de chane C char*.

597

ECPG SQL embarqu en C

int dectoasc(decimal *np, char *cp, int len, int right)


La fonction reoit un pointeur vers une variable de type decimal (np) qu'elle convertit vers sa reprsentation textuelle. cp est
le tampon qui devra contenir le rsultat de l'opration. Le paramtre right spcifie combien de chiffers aprs la virgule
doivent tre inclus dans la sortie. Le rsultat sera arrondi ce nombre de chiffres dcimaux. Positionner right -1 indique
que tous les chiffres dcimaux disponibles devraient tre inclus dans la sortie. Si la longueur du tampon de sortie, qui est indique par len n'est pas suffisante pour contenir toute la reprsentation en incluant le caractre NUL final, seul un caractre
unique * est stock dans le rsultat, et -1 est retourn.
La fonction retourne -1 si le tampon cp tait trop petit ou ECPG_INFORMIX_OUT_OF_MEMORY si plus de mmoire n'tait
disponible.
dectodbl
Convertit une variable de type decimal vers un double.
int dectodbl(decimal *np, double *dblp);
La fonction reoit un pointeur vers la valeur decimal convertir (np) et un pointeur vers la variable double qui devra recevoir
le rsultat de l'opration (dblp).
La fonction retourne 0 en cas de succs et une valeur ngative si la conversion a chou.
dectoint
Convertit une variable de type decimal vers un integer.
int dectoint(decimal *np, int *ip);
La fonction reoit un pointeur vers la valeur decimal convertir (np) et un pointeur vers la variable integer qui devra recevoir
le rsultat de l'opration (ip).
La fonction retourne 0 en cas de succs et une valeur ngative si la conversion a chou. Si un dpassement s'est produit,
ECPG_INFORMIX_NUM_OVERFLOW est retourn.
Notez que l'implmentation d'ECPG diffre de celle d'Informix. Informix limite un integer entre -32767 et 32767, alors
que la limite de l'implmentation d'ECPG dpend de l'architecture (-INT_MAX .. INT_MAX).
dectolong
Convertit une variable de type decimal vers un long integer.
int dectolong(decimal *np, long *lngp);
La fonction reoit un pointeur vers la valeur decimal convertir (np) et un pointeur vers la variable long qui devra recevoir le
rsultat de l'opration (lngp).
La fonction retourne 0 en cas de succs et une valeur ngative si la conversion a chou. Si un dpassement s'est produit,
ECPG_INFORMIX_NUM_OVERFLOW est retourn.
Notez que l'implmentation d'ECPG diffre de celle d'Informix. Informix limite un integer entre --2,147,483,647
2,147,483,647 alors que la limite de l'implmentation d'ECPG dpend de l'architecture (-LONG_MAX .. LONG_MAX).
rdatestr
Convertit une date vers une chane char* C.
int rdatestr(date d, char *str);
La fonction reoit deux arguments, le premier est la date convertir (d) et le second est un pointeur vers la chane cible. Le
format de sortie est toujours yyyy-mm-dd, vous aurez donc allouer au moins 11 octets (en incluant le terminateur NUL)
pour la chane.
La fonction retourne 0 en cas de succs et une valeur ngative si la conversion a chou.
Notez que l'implmentation d'ECPG diffre de celle de Informix. Dans Informix le format peut tre modifi par le positionnement de variable d'enregistrement. Dans ECPG par contre, vous ne pouvez pas changer le format de sortie.
rstrdate
Convertit la reprsentation textuelle d'une date.
int rstrdate(char *str, date *d);

598

ECPG SQL embarqu en C

La fonction reoit la reprsentation textuelle d'une date convertir (str) et un pointeur vers une variable de type date (d).
Cette fonction ne vous permet pas de fournir un masque de formatage. Il utilise le format par dfaut d'Informix qui est mm/
dd/yyyy. En interne, cette fonction est implmente au travers de rdefmtdate. Par consquent, rstrdate n'est pas
plus rapide et si vous avez le choix, vous devriez opter pour rdefmtdate, qui vous permet de spcifier le masque de formatage explicitement.
La fonction retourne les mmes valeurs que rdefmtdate.
rtoday
Rcupre la date courante.
void rtoday(date *d);
La fonction reoit un poiteur vers une variable de type date (d) qu'elle positionne la date courante.
En interne, cette fonction utilise la fonction PGTYPESdate_today.
rjulmdy
Extrait les valeurs pour le jour, le mois et l'anne d'une variable de type date.
int rjulmdy(date d, short mdy[3]);
La fonction reoit la date d et un pointeur vers un tableau de 3 entiers courts mdy. Le nom de la variable indique l'ordre squentiel: mdy[0] contiendra le numro du mois, mdy[1] contiendra le numro du jour, et mdy[2] contiendra l'anne.
La fonction retourne toujours 0 pour le moment.
En interne, cette fonction utilise la fonction PGTYPESdate_julmdy.
rdefmtdate
Utilise un masque de formatage pour convertir une chane de caractre vers une valeur de type date.
int rdefmtdate(date *d, char *fmt, char *str);
La fonction reoit un pointeur vers une valeur date qui devra contenir le rsultat de l'opration (d), le masque de formatage
utiliser pour traiter la date (fmt) et la chane de caractre char* C qui contient la reprsentation textuelle de la date (str). La
reprsentation textuelle doit correspondre au masque de formatage. La fonction n'analyse qu'en ordre squentiel et recherche
les littraux yy ou yyyy qui indiquent la position de l'anne, mm qui indique la position du mois et dd qui indique la position
du jour.
La fonction retourne les valeurs suivantes:

0 - La fonction s'est termine avec succs.

ECPG_INFORMIX_ENOSHORTDATE - La date ne contient pas de dlimiteur entre le jour, le mois et l'anne. Dans ce
cas, la chane en entre doit faire exactement 6 ou 8 caractres, mais ce n'est pas le cas.

ECPG_INFORMIX_ENOTDMY - La chane de formatage n'indique pas correctement l'ordre squentiel de l'anne, du


mois, et du jour.

ECPG_INFORMIX_BAD_DAY - La chane d'entre ne contient pas de jour valide.

ECPG_INFORMIX_BAD_MONTH - La chane d'entre ne contient pas de mois valide.

ECPG_INFORMIX_BAD_YEAR - La chane d'entre ne contient pas d'anne valide.

En interne, cette fonction est implmente en utilisant la fonction PGTYPESdate_defmt_asc. Voyez la rfrence cet
endroi pour la table d'exemples.
rfmtdate
Convertit une variable de type date vers sa reprsentation textuelle en utilisant un masque de formatage.
int rfmtdate(date d, char *fmt, char *str);
La fonction reoin une date convertir (d), le masque de formatage (fmt) et la chane qui contiendra la reprsentation textuelle de la date (str).
La fonction retourne 0 en cas de succs et une valeur ngative
En interne, cette fonction utilise la fonction PGTYPESdate_fmt_asc, voyez la rfrence pour des exemples.
599

ECPG SQL embarqu en C

rmdyjul
Cre une valeur date partir d'un tableau de 3 entiers courts qui spcifient le jour, le mois et l'anne de la date.
int rmdyjul(short mdy[3], date *d);
La fonction reoit le tableau des 3 entiers courst (mdy) et un pointeur vers une variable de type date qui contiendra le rsultat
de l'opration.
La fonction retourne toujours 0 l'heure actuelle.
En interne la fonction est implmente en utilisante la fonction PGTYPESdate_mdyjul.
rdayofweek
Retourne un nombre reprsentant le jour de la semaine pour une valeur de date.
int rdayofweek(date d);
La fonction reoit la variable date d comme seul argument et retourne un entier qui indique le jour de la semaine pour cette
date.

0 - Dimanche

1 - Lundi

2 - Mardi

3 - Mercredi

4 - Jeudi

5 - Vendredi

6 - Samedi

En intere, cette fonction est implmente en utilisant la fonction PGTYPESdate_dayofweek.


dtcurrent
Rcupre le timestamp courant.
void dtcurrent(timestamp *ts);
La fonction rcupre le timestamp courant et l'enregistre dans la variable timestamp vers laquelle ts pointe.
dtcvasc
Convertit un timestamp de sa reprsentation textuelle vers une variable timestamp.
int dtcvasc(char *str, timestamp *ts);
La fonction reoit la chane traiter (str) et un pointeur vers la variable timestamp qui contiendra le rsultat de l'opration
(ts).
La fonction retourne 0 en cas de succs et une valeur ngative
En interne, cette fonction utilise la fonction PGTYPEStimestamp_from_asc. Voyez la rfrence pour un tableau avec
des exemples de formats.
dtcvfmtasc
Convertit un timestamp de sa reprsentation textuelle vers une variable timestamp en utilisant un masque de formatage.
dtcvfmtasc(char *inbuf, char *fmtstr, timestamp *dtvalue)
La fonction reoit la chane traiter (inbuf), le masque de formatage utiliser (fmtstr) et un pointeur vers la variable timestamp qui contiendra le rsultat de l'opration (dtvalue).
Cette fonction est implmente en utilisant la fonction PGTYPEStimestamp_defmt_asc. Voyez la documentation cet
endroit pour la liste des spcificateurs de formats qui peuvent tre utiliss.
La fonction retourne 0 en cas de succs et une valeur ngative
dtsub
600

ECPG SQL embarqu en C

Soustrait un timestamp d'un autre et retourne une variable de type interval.


int dtsub(timestamp *ts1, timestamp *ts2, interval *iv);
La fonction soustrait la variable timestamp vers laquelle ts2 pointe de la variable timestamp vers laquelle ts1 pointe et stockera le rsultat dans la variable intervalle vers laquelle iv pointe.
En cas de succs, la fonction retourne 0, et une valeur ngative si une erreur s'est produite.
dttoasc
Convertit une variable timestamp vers une chane char* C.
int dttoasc(timestamp *ts, char *output);
La fonction reoit un pointeur vers une variable timestamp convertir (ts) et la chane qui devra contenir le rsultat de
l'opration (output). Elle convertit ts vers sa reprsentation textuelle comme spcifi par le standard SQL, qui est YYYYMM-DD HH:MM:SS.
En cas de succs, la fonction retourne 0, et une valeur ngative si une erreur s'est produite.
dttofmtasc
Convertit une variable timestamp vers un char* C en utilisant un masque de formatage.
int dttofmtasc(timestamp *ts, char *output, int str_len, char *fmtstr);
La fonction reoit un pointeur vers le timestamp convertir comme premier argument (ts), un pointeur vers le tampon de
sortie (output), la longueur maximale qui a t alloue pour le tampon de sortie (str_len) et le masque de formatage
utiliser pour la conversion (fmtstr).
En cas de succs, la fonction retourne 0, et une valeur ngative si une erreur s'est produite.
En interne, cette fonction utilise la fonction PGTYPEStimestamp_fmt_asc. Voyez la rfrence pour des informations sur
les spcifications de masque de formatage qui sont utilisables.
intoasc
Convertit une variable interval en chane char* C.
int intoasc(interval *i, char *str);
La fonction reoit un pointeur vers la variable interval convertir (i) et la chane qui contiendra le rsultat de l'opration
(str). Elle convertit i vers sa reprsentation textuelle suivant le standard SQL, qui est YYYY-MM-DD HH:MM:SS.
En cas de succs, la fonction retourne 0, et une valeur ngative si une erreur s'est produite.
rfmtlong
Convertit une valeur long integer vers sa reprsentation textuelle en utilisant un masque de formatage.
int rfmtlong(long lng_val, char *fmt, char *outbuf);
La fonction reoit la valeur long lng_val, le masque de formatage fmt et un pointeur vers le tampon de sortie outbuf. Il
convertit la valeur long vers sa reprsentation textuelle en fonction du masque de formatage.
Le masque de formatage peut tre compos des caractres suivants de spcification:

* (asterisk) - si cette position tait blanc sans cela, mettez y un astrisque.

& (ampersand) - si cette position tait blanc sans cela, mettez y un zro.

# - transforme les zros initiaux en blancs.

< - justifie gauche le nombre dans la chane.

, (virgule) - Groupe les nombres de 4 chiffres ou plus en groupes de 3 chiffres spars par des virgules.

. (point) - Ce caractre spare la partie entire du nombre de sa partie fractionnaire.

- (moins) - le signe moins apparat si le nombre est ngatif.

+ (plus) - le signe plus apparat si le nombre est positif.

( - ceci remplace le signe moins devant une valeur ngative. Le signe moins n'apparatra pas.
601

ECPG SQL embarqu en C

) - Ce caractre remplace le signe moins et est affich aprs la valeur ngative.

$ - le symbole montaire.

rupshift
Passe une chane en majuscule.
void rupshift(char *str);
La fonction reoit un pointeur vers une chane et convertit tous ses caractres en majuscules.
byleng
Retourne le nombre de caracres dans une chane sans compter les blancs finaux.
int byleng(char *str, int len);
La fonction attend une chane de longueur fixe comme premier argument (str) et sa longueur comme second argument
(len). Elle retourne le nombre de caractres significatifs, c'est dire la longueur de la chane sans ses blancs finaux.
ldchar
Copie une chane de longueur fixe vers une chane termine par un NUL.
void ldchar(char *src, int len, char *dest);
La fonction reoit la chane de longueur fixe copier (src), sa longueur (len) et un pointeur vers la mmoire destinataire
(dest). Notez que vous aurez besoin de rserver au moins len+1 octets pour la chaine vers laquelle pointe dest. Cette
fonction copie au plus len octets vers le nouvel emplacement (moins si la chane source a des blancs finaux) et ajoute le terminateur NUL.
rgetmsg
int rgetmsg(int msgnum, char *s, int maxsize);
Cette fonction existe mais n'est pas implmente pour le moment!
rtypalign
int rtypalign(int offset, int type);
Cette fonction existe mais n'est pas implmente pour le moment!
rtypmsize
int rtypmsize(int type, int len);
Cette fonction existe mais n'est pas implmente pour le moment!
rtypwidth
int rtypwidth(int sqltype, int sqllen);
Cette fonction existe mais n'est pas implmente pour le moment!
rsetnull
Set a variable to NULL.
int rsetnull(int t, char *ptr);
La fonction reoit un entier qui indique le type de variable et un pointeur vers la variable elle mme, transtyp vers un pointeur char*.
The following types exist:

CCHARTYPE - Pour une variable de type char ou char*

CSHORTTYPE - Pour une variable de type short int

CINTTYPE - Pour une variable de type int


602

ECPG SQL embarqu en C

CBOOLTYPE - Pour une variable de type boolean

CFLOATTYPE - Pour une variable de type float

CLONGTYPE - Pour une variable de type long

CDOUBLETYPE - Pour une variable de type double

CDECIMALTYPE - Pour une variable de type decimal

CDATETYPE - Pour une variable de type date

CDTIMETYPE - Pour une variable de type timestamp

Voici un exemple d'appel cette fonction:


$char c[] = "abc
$short s = 17;
$int i = -74874;

";

rsetnull(CCHARTYPE, (char *) c);


rsetnull(CSHORTTYPE, (char *) &s);
rsetnull(CINTTYPE, (char *) &i);
risnull
Teste si une variable est NULL.
int risnull(int t, char *ptr);
Cette fonction reoit le type d'une variable tester (t) ainsi qu'un pointeur vers cette variable (ptr). Notez que ce dernier
doit tre transtyp vers un char*. Voyez la fonction rsetnull pour une liste de types de variables possibles.
Voici un exemple de comment utiliser cette fonction:
$char c[] = "abc
$short s = 17;
$int i = -74874;

";

risnull(CCHARTYPE, (char *) c);


risnull(CSHORTTYPE, (char *) &s);
risnull(CINTTYPE, (char *) &i);

33.15.5. Constantes Supplmentaires


Notez que toutes les constantes ici dcrivent des erreurs et qu'elles sont toutes dfinies pour reprsenter des valeurs ngatives.
Dans les descriptions des diffrentes constantes vous pouvez aussi trouver la valeur que les constantes reprsentent dans
l'implmentation actuelle. Toutefois, vous ne devriez pas vous fier ce nombre. Vous pouvez toutefois vous appuyer sur le faite
que toutes sont dfinies comme des valeurs ngatives. values.
ECPG_INFORMIX_NUM_OVERFLOW
Les fonctions retournent cette valeur si un dpassement s'est produit dans un calcul. En interne, elle est dfinie -1200 (la dfinition Informix).
ECPG_INFORMIX_NUM_UNDERFLOW
Les fonctions retournent cette valeur si un soupassement s'est produit dans un calcul. En interne, elle est dfinie -1201 (la
dfinition Informix).
ECPG_INFORMIX_DIVIDE_ZERO
Les fonctions retournent cette valeur si une division par zro a t tente. En interne, elle est dfinie -1202 (la dfinition Informix).
ECPG_INFORMIX_BAD_YEAR
Les fonctions retournent cette valeur si une mauvaise valeur pour une anne a t trouve lors de l'analyse d'une date. En interne elle est dfinie -1204 (la dfinition Informix).
603

ECPG SQL embarqu en C

ECPG_INFORMIX_BAD_MONTH
Les fonctions retournent cette valeur si une mauvaise valeur pour un mois a t trouve lors de l'analyse d'une date. En interne
elle est dfinie -1205 (la dfinition Informix).
ECPG_INFORMIX_BAD_DAY
Les fonctions retournent cette valeur si une mauvaise valeur pour un jour a t trouve lors de l'analyse d'une date. En interne
elle est dfinie -1206 (la dfinition Informix).
ECPG_INFORMIX_ENOSHORTDATE
Les fonctions retournent cette valeur si une routine d'analyse a besoin d'une reprsentation courte de date mais que la chane
passe n'tait pas de la bonne longueur. En interne elle est dfinie -1206 (la dfinition Informix).
ECPG_INFORMIX_DATE_CONVERT
Les fonctions retournent cette valeur si une erreur s'est produite durant un formatage de date. En interne, elle est dfinie 1210 (la dfinition Informix).
ECPG_INFORMIX_OUT_OF_MEMORY
Les fonctions retournent cette valeur si elles se sont retrouves court de mmoire durant leur fonctionnement. En interne,
elle est dfinie -1211 (la dfinition Informix).
ECPG_INFORMIX_ENOTDMY
Les fonctions retournent cette valeur si la routine d'analyse devait recevoir un masque de formatage (comme mmddyy) mai
que tous les champs n'taient pas lists correctement. En interne, elle est dfinie -1212 (la dfinition Informix).
ECPG_INFORMIX_BAD_NUMERIC
Les fonctions retournent cette valeur soit parce qu'une routine d'analyse ne peut pas analyser la reprsentation textuelle d'une
valeur numrique parce qu'elle contient des erreurs, soit parce qu'une routine ne peut pas terminer un calcul impliquant des
variables numeric parce qu'au moins une des variables numeric est invalide. En interne, elle est dfinie -1213 (la dfinition
Informix).
ECPG_INFORMIX_BAD_EXPONENT
Les fonctions retournent cette valeur si elles n'ont pas russi analyser l'exposant de la reprsentation textuelle d'une valeur
numrique. En interne, elle est dfinie -1216 (la dfinition Informix).
ECPG_INFORMIX_BAD_DATE
Les fonctions retournent cette valeur si une chane de date invalide leur a t passe. En interne, elle est dfinie -1218 (la dfinition Informix).
ECPG_INFORMIX_EXTRA_CHARS
Les fonctions retournent cette valeur si trop de caractres ont t trouvs dans la reprsentation textuelle d'un format date. En
interne, elle est dfinie -1264 (la dfinition Informix).

33.16. Fonctionnement Interne


Cette section explique comment ECPG fonctionne en interne. Cette information peut tre utile pour comprendre comment utiliser
ECPG.
Les quatre premires lignes crites sur la sortie par ecpg sont des lignes fixes. Deux sont des commentaires et deux sont des lignes
d'inclusion ncessaires pour s'interfacer avec la librairie. Puis le prprocesseur lit le fichier et crit la sortie. La plupart du temps, il
rpte simplement tout dans la sortie.
Quand il voit un ordre EXEC SQL, il intervient et le modifie. La commande dbute par EXEC SQL et se termine par ;. Tout ce
qui se trouve entre deux est trait comme un ordre SQL et analys pour substitution de variables.
Une substitution de variable se produit quand un symbole commence par un deux-points (:). La variable dont c'est le nom est recherche parmi les variables qui ont t prcdemment dclares dans une section EXEC SQL DECLARE.
La fonction la plus importante de la librairie est ECPGdo, qui s'occupe de l'excution de la plupart des commandes. Elle prend un
nombre variable d'arguments. Le nombre de ces arguments peut rapidement dpasser la cinquantaine, et nous esprons que cela ne
posera de problme sur aucune plateforme.
Les arguments sont:
Un numro de ligne
C'est le numro de la ligne originale; c'est utilis uniquement pour les messages d'erreu.
Une chane
C'est la commande SQL excuter. Elle est modifie par les variables d'entre, c'est dire les variables qui n'taient pas
604

ECPG SQL embarqu en C

connues au moment de la compilation mais qui doivent tout de mme faire partie de la commande. Aux endroits o ces variables doivent tre positionnes, la chane contient des ?.
Variables d'Entre
Chaque variable d'entre entrane la cration de dix arguments. (Voir plus bas.)
ECPGt_EOIT
Un enum annonant qu'il n'y a pas de variable d'entres supplmentaires.
Variables de Sortie
Chaque variable de sortie entrane la cration de dix arguments. (Voir plus bas.) Ces variables sont renseignes par la fonction.
ECPGt_EORT
Un enum annonant qu'il n'y a plus de variables.
Pour chaque variable qui fait partie d'une commande SQL, la fonction reoit dix arguments:
1. Le type sous forme de symbole spcial.
2. Un pointeur vers la valeur ou un pointeur vers le pointeur.
3. La taille de la variable si elle est char ou varchar.
4. Le nombre d'lments du tableau (pour les fetch sur tableau).
5. Le dcalage vers le prochain lment du tableau (pour les fetch sur tableau).
6. Le type de la variable indicateur sous forme de symbole special.
7. Un pointeur vers la variable indicateur.
8. 0
9. Le nombre d'lments du tableau d'indicateurs (pour les fetch sur tableau).
10 Le dcalage vers le prochain lment du tableau d'indicateurs (pour les fetch sur tableau).
.
Notez que toutes les commandes SQL ne sont pas traites de cette faon. Par exemple, un ordre d'ouverture de curseur comme:
Notez que toutes les commandes SQL ne sont pas traites de cette faon. Par exemple, un ordre d'ouverture de curseur comme:
EXEC SQL OPEN cursor;
n'est pas copi vers la sortie. la place, la commande de curseur DECLARE est utilise l'endroit de la commande OPEN parce
qu'elle ouvre effectivement le curseur.
Voici un exemple complet expliquant la sortie du prprocesseur sur un fichier foo.pgc (quelques dtails pourraient changer en
fonction de la version exacte du prprocesseur):
EXEC SQL BEGIN DECLARE SECTION;
int index;
int result;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index;
is translated into:
/* Processed by ecpg (2.6.0) */
/* These two include files are added by the preprocessor */
#include <ecpgtype.h>;
#include <ecpglib.h>;
/* exec sql begin declare section */
#line 1 "foo.pgc"
int index;
int result;
/* exec sql end declare section */
605

ECPG SQL embarqu en C

...
ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ?
ECPGt_int,&(index),1L,1L,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_int,&(result),1L,1L,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 147 "foo.pgc"

",

(L'indentation est ajoute ici pour amliorer la lisibilit et n'est pas quelque chose que le prprocesseur effectue).

606

Chapitre 34. Schma d'information


Le schma d'information consiste en un ensemble de vues contenant des informations sur les objets dfinis dans la base de donnes courante. Le schma d'information est dfini dans le standard SQL et, donc suppos portable et stable -- contrairement aux
catalogues systme qui sont spcifiques PostgreSQL et models suivant l'implantation. Nanmoins, les vues du schma
d'information ne contiennent pas d'informations sur les fonctionnalits spcifiques PostgreSQL ; pour cela, on utilise catalogues systme et autres vues spcifiques PostgreSQL.

Note
En demandant des informations sur les contraintes dans la base de donnes, il est possible qu'une requte
conforme au standard s'attendant ne rcuprer qu'une ligne en rcupre en fait plusieurs. Ceci est d au fait que
le standard SQL requiert que les noms des contraintes soient uniques dans un mme schma mais PostgreSQL
ne force pas cette restriction. Les noms de contraintes crs automatiquement par PostgreSQL vitent les doublons dans le le mme schma mais les utilisateurs peuvent spcifier explicitement des noms existant dj.
Ce problme peut apparatre lors de la consultation de vues du schma d'informations, comme par exemple
check_constraint_routine_usage, check_constraints, domain_constraints et referential_constraints. Certaines autres vues ont des problmes similaires mais contiennent le nom de la
table pour aider distinguer les lignes dupliques, par exemple constraint_column_usage,
constraint_table_usage, table_constraints.

34.1. Le schma
Le schma d'information est lui-mme un schma nomm information_schema. Ce schma existe automatiquement dans
toutes les bases de donnes. Le propritaire de ce schma est l'utilisateur initial du cluster. Il a naturellement tous les droits sur
ce schma, dont la possibilit de le supprimer (mais l'espace gagn ainsi sera minuscule).
Par dfaut, le schma d'information n'est pas dans le chemin de recherche des schmas. Il est donc ncessaire d'accder tous
les objets qu'il contient via des noms qualifis. Comme les noms de certains objets du schma d'information sont des noms gnriques pouvant survenir dans les applications utilisateur, il convient d'tre prudent avant de placer le schma d'information
dans le chemin.

34.2. Types de donnes


Les colonnes des vues du schma d'information utilisent des types de donnes spciaux, dfinis dans le schma d'information.
Ils sont dfinis comme des domaines simples sur des types internes. Vous normal, il est prfrable de ne pas utiliser ces types en
dehors du schma d'information, mais les applications doivent pouvoir les utiliser si des slections sont faites dans le schma
d'information.
Ces types sont :
cardinal_number
Un entier non ngatif.
character_data
Une chane de caractres (sans longueur maximale indique).
sql_identifier
Une chane de caractres. Elle est utilise pour les identifiants SQL, le type de donnes character_data est utilis pour tout
autre type de donnes texte.
time_stamp
Un domaine au-dessus du type timestamp with time zone
yes_or_no
Un domaine dont le type correspond une chane de caractres, qui contient soit YES soit NO. C'est utilis pour reprsenter
des donnes boolennes (true/false) dans le schma d'informations. (Le schma d'informations tait invent avant l'ajout du
type boolean dans le standard SQL, donc cette convention est ncessaire pour conserver la compatibilit avec le schma
d'informations.)
Chaque colonne du schma d'information est de l'un des ces cinq types.

607

Schma d'information

34.3. information_schema_catalog_name
information_schema_catalog_name est une table qui contient en permanence une ligne et une colonne contenant le nom
de la base de donnes courante (catalogue courant dans la terminologie SQL).
Tableau 34.1. Colonnes de information_schema_catalog_name

Nom

Type de donnes

Description

catalog_name

sql_identifier

Nom de la base de donnes contenant ce schma


d'informations

34.4. administrable_role_authorizations
La vue administrable_role_authorizations identifie tous les rles pour lesquelles l'utilisateur courant possde
l'option ADMIN.
Tableau 34.2. Colonnes de administrable_role_authorizations

Nom

Type de donnes

Description

grantee

sql_identifier

Nom du rle pour lequel cette appartenance de rle a t donne (peut tre
l'utilisateur courant ou un rle diffrent
dans le cas d'appartenances de rles imbriques).

role_name

sql_identifier

Nom d'un rle

is_grantable

yes_or_no

Toujours YES

34.5. applicable_roles
La vue applicable_roles identifie tous les rles dont l'utilisateur courant peut utiliser les droits. Cela signifie qu'il y a certaines chanes de donnation des droits de l'utilisateur courant au rle en question. L'utilisateur lui-mme est un rle applicable.
L'ensemble de rles applicables est habituellement utilis pour la vrification des droits.
Tableau 34.3. Colonnes de applicable_roles

Nom

Type de donnes

Description

grantee

sql_identifier

Nom du rle qui cette appartenance a t donne (peut


tre l'utilisateur courant ou un rle diffrent dans le cas
d'appartenances de rles imbriques)

role_name

sql_identifier

Nom d'un rle

is_grantable

yes_or_no

YES si le bnficiaire a l'option ADMIN sur le rle, NO


dans le cas contraire

34.6. attributes
La vue attributes contient des informations sur les attributs des types de donnes composites dfinis dans la base. (La vue ne
donne pas d'informations sur les colonnes de table, qui sont quelque fois appeles attributs dans le contexte de PostgreSQL.)
Tableau 34.4. Colonnes de attributes

Nom

Type de donnes

Description

udt_catalog

sql_identifier

Nom de la base contenant le type de donnes (toujours la base courante)

udt_schema

sql_identifier

Nom du schma contenant le type de donnes


608

Schma d'information

Nom

Type de donnes

Description

udt_name

sql_identifier

Nom du type de donnes

attribute_name

sql_identifier

Nom de l'attribut

ordinal_position

cardinal_number

Position de l'attribut dans le type de donnes (le dcompte commence 1)

attribute_default

character_data

Expression par dfaut de l'attribut

is_nullable

yes_or_no

YES si l'attribut peut tre NULL, NO dans


le cas contraire.

data_type

character_data

Type de donnes de l'attribut s'il s'agit


d'un type interne ou ARRAY s'il s'agit d'un
tableau (dans ce cas, voir la vue element_types), sinon USER-DEFINED
(dans ce cas, le type est identifi dans
attribute_udt_name et les colonnes
associes).

character_maximum_length

cardinal_number

Si data_type identifie un caractre ou


une chane de bits, la longueur maximale
dclare ; NULL pour tous les autres
types de donnes ou si aucune longueur
maximale n'a t dclare.

character_octet_length

cardinal_number

Si data_type identifie un type caractre, la longueur maximale en octets


(bytes) d'un datum ; NULL pour tous les
autres types de donnes. La longueur
maximale en octets dpend de la longueur
maximum dclare en caractres (voir cidessus) et l'encodage du serveur.

character_set_catalog

sql_identifier

S'applique une fonctionnalit non disponible avec PostgreSQL

character_set_schema

sql_identifier

S'applique une fonctionnalit non disponible avec PostgreSQL

character_set_name

sql_identifier

S'applique une fonctionnalit non disponible avec PostgreSQL

collation_catalog

sql_identifier

Pas encore implment

collation_schema

sql_identifier

Pas encore implment

collation_name

sql_identifier

Pas encore implment

numeric_precision

cardinal_number

Si data_type identifie un type numrique, cette colonne contient la prcision


(dclare ou implicite) du type pour cet
attribut. La prcision indique le nombre
de chiffres significatifs. Elle peut tre exprime en dcimal (base 10) ou en binaire
(base 2) comme le prcise la colonne numeric_precision_radix. Pour tous
les autres types de donnes, cette colonne
vaut NULL.

numeric_precision_radix

cardinal_number

Si data_type identifie un type numrique, cette colonne indique la base


d'expression des colonnes numeric_precision
et
numeric_scale. La valeur est soit 2
soit 10. Pour tous les autres types de donnes, cette colonne est NULL.

numeric_scale

cardinal_number

Si data_type identifie un type numrique exact, cette colonne contient


l'chelle (dclare ou implicite) du type
609

Schma d'information

Nom

Type de donnes

Description
pour cet attribut. L'chelle indique le
nombre de chiffres significatifs droite du
point dcimal. Elle peut tre exprime en
dcimal (base 10) ou en binaire (base 2)
comme le prcise la colonne numeric_precision_radix. Pour tous
les autres types de donnes, cette colonne
est NULL.

datetime_precision

cardinal_number

Si data_type identifie une date, une


heure, un horodatage ou un interval, cette
colonne contient la prcision en secondes
(dclare ou implicite) pour cet attribut,
c'est--dire le nombre de chiffres dcimaux suivant le point dcimal de la valeur
en secondes. Pour tous les autres types de
donnes, cette colonne est NULL.

interval_type

character_data

Pas encore implant

interval_precision

character_data

Pas encore implant

attribute_udt_catalog

sql_identifier

Nom de la base dans laquelle le type de


donnes de l'attribut est dfini (toujours la
base courante)

attribute_udt_schema

sql_identifier

Nom du schma dans lequel le type de


donnes de l'attribut est dfini

attribute_udt_name

sql_identifier

Nom du type de donnes de l'attribut

scope_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

scope_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

scope_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

maximum_cardinality

cardinal_number

Toujours NULL car les tableaux ont toujours une cardinalit maximale dans PostgreSQL

dtd_identifier

sql_identifier

Un identifiant du descripteur du type de


donnes de la colonne, unique parmi les
descripteurs de types de donnes de la
table. Ceci est principalement utile pour
des jointures avec d'autres instances de
tels identifiants. (Le format spcifique de
l'identifiant n'est pas dfini et il n'est pas
garanti qu'il reste identique dans les versions futures.)

is_derived_reference_attribu yes_or_no
te

S'applique une fonctionnalit non disponible dans PostgreSQL

Voir aussi dans Section 34.15, columns , une vue structure de faon similaire, pour plus d'informations sur certaines colonnes.

34.7. character_sets
La vue character_sets identifie les jeux de caractres disponibles pour la base de donnes courante. Comme PostgreSQL ne
supporte pas plusieurs jeux de caractres dans une base de donnes, cette vue n'en affiche qu'une, celle qui correspond
l'encodage de la base de donnes.
Les termes suivants sont utiliss dans le standard SQL :

610

Schma d'information

rpertoire de caractres (character repertoire


Un ensemble abstrait de caractres, par exemple UNICODE, UCS ou LATIN1. Non expos en tant qu'objet SQL mais visible
dans cette vue.
forme d'encodage de caractres (character encoding form)
Un encodage d'un certain rpertoire de caractres. La plupart des anciens rpertoires de caractres utilisent seulement un encodage. Du coup, il n'y a pas de noms spars pour eux (par exemple LATIN1 est une forme d'encodage applicable au rpertoire LATIN1). Par contre, Unicode dispose des formats d'encodage UTF8, UTF16, etc. (ils ne sont pas tous supports par
PostgreSQL). Les formes d'encodage ne sont pas exposs comme un objet SQL mais ils sont visibles dans cette vue.
jeu de caractres (character set)
Un objet SQL nomm qui identifie un rpertoire de caractres, un encodage de caractres et un collationnement par dfaut.
Un jeu de caractres prdfini aura gnralement le mme nom qu'une forme d'endodage mais les utilisateurs peuvent dfinir
d'autres noms. Par exemple, le jeu de caractres UTF8 identifiera typiquement le rpertoire des caractres UCS, la forme
d'encodage UTF8 et un collationnement par dfaut.
Dans PostgreSQL, un encodage peut tre vu comme un jeu de caractres ou une forme d'encodage des caractres. Ils auront le
mme nom et il n'y en a qu'un dans une base de donnes.
Tableau 34.5. Colonnes de character_sets

Nom

Type de donnes

Description

character_set_catalog

sql_identifier

Les jeux de caractres ne sont pas actuellement implments comme des objets du
schma, donc cette colonne est NULL.

character_set_schema

sql_identifier

Les jeux de caractres ne sont pas actuellement implments comme des objets du
schma, donc cette colonne est NULL.

character_set_name

sql_identifier

Nom du jeu de caractres, mais affiche actuellement le nom de l'encodage de la


base de donnes

character_repertoire

sql_identifier

Rpertoire des caractres, affichant UCS


si l'encodage est UTF8, et le nom de
l'encodage sinon

form_of_use

sql_identifier

Forme d'encodage des caractres, identique l'encodage de la base de donnes

default_collate_catalog

sql_identifier

Nom de la base de donnes contenant le


collationnement par dfaut (toujours la
base de donnes courante si un collationnement est identifi)

default_collate_schema

sql_identifier

Nom du schma contenant le collationnement par dfaut

default_collate_name

sql_identifier

Nom du collationnement par dfaut. Il est


identifi comme le collationnement qui
correspond aux paramtres COLLATE et
CTYPE pour la base de donnes courante.
S'il n'y a pas de collationnement, cette colonne, le schma associ et les colonnes
du catalogue sont NULL.

34.8. check_constraint_routine_usage
La vue check_constraint_routine_usage identifie les routines (fonctions et procdures) utilises par une contrainte de
vrification. Seules sont prsentes les routines qui appartiennent un rle couramment actif.
Tableau 34.6. Colonnes de check_constraint_routine_usage

611

Schma d'information

Nom

Type de donnes

Description

constraint_catalog

sql_identifier

Nom de la base contenant la contrainte


(toujours la base courante)

constraint_schema

sql_identifier

Nom du schma contenant la contrainte

constraint_name

sql_identifier

Nom de la contrainte

specific_catalog

sql_identifier

Nom de la base contenant la fonction


(toujours la base courante)

specific_schema

sql_identifier

Nom du schma contenant la fonction

specific_name

sql_identifier

Le nom spcifique de la fonction. Voir


Section 34.38, routines pour plus
d'informations.

34.9. check_constraints
La vue check_constraints contient toutes les contraintes de vrification dfinies sur une table ou un domaine, possdes par
un rle couramment actif (le propritaire d'une table ou d'un domaine est le propritaire de la contrainte).
Tableau 34.7. Colonnes de check_constraints

Nom

Type de donnes

Description

constraint_catalog

sql_identifier

Nom de la base de donnes contenant la contrainte (toujours


la base de donnes courante)

constraint_schema

sql_identifier

Nom du schma contenant la contrainte

constraint_name

sql_identifier

Nom de la contrainte

check_clause

character_data

L'expression de vrification de la contrainte

34.10. collations
La vue collations contient les collationnements disponibles dans la base de donnes courante.
Tableau 34.8. Colonnes de collations

Nom

Type de donnes

Description

collation_catalog

sql_identifier

Nom de la base de donnes contenant le


collationnement (toujours la base de donnes courante)

collation_schema

sql_identifier

Nom du schma contenant le collationnement

collation_name

sql_identifier

Nom du collationnement par dfaut

pad_attribute

character_data

Toujours NO PAD (l'alternative PAD


SPACE n'est pas supporte par PostgreSQL.)

34.11. collation_character_set_applicability
La vue collation_character_set_applicability identifie les jeux de caractres applicables aux collationnements
disponibles. Avec PostgreSQL, il n'existe qu'un jeu de caractres par base de donnes (voir les explications dans Section 34.7,
character_sets ), donc cette vue ne fournit pas beaucoup d'informations utiles.
Tableau 34.9. Colonnes de collation_character_set_applicability

Nom

Type de donnes

Description

collation_catalog

sql_identifier

Nom de la base de donnes contenant le

612

Schma d'information

Nom

Type de donnes

Description
collationnement (toujours la base de donnes courante)

collation_schema

sql_identifier

Nom du schma contenant le collationnement

collation_name

sql_identifier

Nom du collationnement par dfaut

character_set_catalog

sql_identifier

Les jeux de caractres ne sont pas actuellement implments comme des objets du
schma, donc cette colonne est NULL.

character_set_schema

sql_identifier

Les jeux de caractres ne sont pas actuellement implments comme des objets du
schma, donc cette colonne est NULL.

character_set_name

sql_identifier

Nom du jeu de caractres

34.12. column_domain_usage
La vue column_domain_usage identifie toutes les colonnes (d'une table ou d'une vue) utilisant un domaine dfini dans la
base de donnes courante et possd par un rle couramment actif.
Tableau 34.10. Colonnes de column_domain_usage

Nom

Type de donnes

Description

domain_catalog

sql_identifier

Nom de la base de donnes contenant le domaine (toujours


la base de donnes courante)

domain_schema

sql_identifier

Nom du schma contenant le domaine

domain_name

sql_identifier

Nom du domaine

table_catalog

sql_identifier

Nom de la base de donnes contenant la table (toujours la


base de donnes courante)

table_schema

sql_identifier

Nom du schma contenant la table

table_name

sql_identifier

Nom de la table

column_name

sql_identifier

Nom de la colonne

34.13. column_privileges
La vue column_privileges identifie tous les droits octroys sur les colonnes un rle couramment actif ou par un rle couramment actif. Il existe une ligne pour chaque combinaison colonne, donneur (grantor) et receveur (grantee).
Si un droit a t donn sur une table entire, il s'affichera dans cette vue comme un droit sur chaque colonne, mais seulement pour
les types de droits o la granularit par colonne est possible : SELECT, INSERT, UPDATE, REFERENCES.
Tableau 34.11. Colonnes de column_privileges

Nom

Type de donnes

Description

grantor

sql_identifier

Nom du rle ayant accord le privilge

grantee

sql_identifier

Nom du rle receveur

table_catalog

sql_identifier

Nom de la base de donnes qui contient la table qui contient


la colonne (toujours la base de donnes courante)

table_schema

sql_identifier

Nom du schma qui contient la table qui contient la colonne

table_name

sql_identifier

Nom de la table qui contient la colonne

column_name

sql_identifier

Nom de la colonne

privilege_type

character_data

Type de privilge : SELECT, INSERT, UPDATE ou REFERENCES


613

Schma d'information

Nom

Type de donnes

Description

is_grantable

yes_or_no

YES si le droit peut tre accord, NO sinon

34.14. column_udt_usage
La vue column_udt_usage identifie toutes les colonnes qui utilisent les types de donnes possds par un rle actif. Avec
PostgreSQL, les types de donnes internes se comportent comme des types utilisateur, ils apparaissent aussi ici. Voir aussi la
Section 34.15, columns pour plus de dtails.
Tableau 34.12. Colonnes de column_udt_usage

Nom

Type de donnes

Description

udt_catalog

sql_identifier

Nom de la base de donnes dans laquelle le type de donne


de la colonne (le type sous-jacent du domaine, si applicable) est dfini (toujours la base de donnes courante).

udt_schema

sql_identifier

Nom du schma dans lequel le type de donne de la colonne


(le type sous-jacent du domaine, si applicable) est dfini.

udt_name

sql_identifier

Nom du type de donnes de la colonne (le type sous-jacent


du domaine, si applicable).

table_catalog

sql_identifier

Nom de la base de donnes contenant la table (toujours la


base de donnes courante).

table_schema

sql_identifier

Nom du schma contenant la table.

table_name

sql_identifier

Nom de la table.

column_name

sql_identifier

Nom de la colonne.

34.15. columns
La vue columns contient des informations sur toutes les colonnes de table (et colonnes de vue) de la base. Les colonnes systme
(oid, etc.) ne sont pas incluses. Seules les colonnes auxquelles l'utilisateur a accs (par proprit ou par privilges) sont affiches.
Tableau 34.13. Colonnes de columns

Nom

Type de donnes

Description

table_catalog

sql_identifier

Nom de la base de donnes contenant la table (toujours la


base de donnes courante)

table_schema

sql_identifier

Nom du schma contenant la table

table_name

sql_identifier

Nom de la table

column_name

sql_identifier

Nom de la colonne

ordinal_position

cardinal_number

Position de la colonne dans la table (la numrotation commenant 1)

column_default

character_data

Expression par dfaut de la colonne

is_nullable

yes_or_no

YES si la colonne est NULLable (elle admet une absence de


valeur), NO dans le cas contraire. La contrainte NOT NULL
n'est pas la seule faon de dfinir qu'une colonne n'est pas
NULLable.

data_type

character_data

Le type de donnes de la colonne, s'il s'agit d'un type interne ou ARRAY s'il s'agit d'un tableau (dans ce cas, voir la
vue element_types), USER-DEFINED dans les autres
cas (le type est alors identifi dans udt_name et colonnes
associes). Si la colonne est fonde sur un domaine, cette
colonne est une rfrence au type sous-jacent du domaine
(et le domaine est identifi dans domain_name et colonnes associes).

character_maximum_length

cardinal_number

Si data_type identifie un type chane de caractres ou


614

Schma d'information

Nom

Type de donnes

Description
chane de bits, la longueur maximale dclare ; NULL pour
tous les autres types de donnes ou si aucune longueur
maximale n'a t dclare.

character_octet_length

cardinal_number

Si data_type identifie un type caractre, la longueur


maximale en octets (bytes) d'un datum ; NULL pour tous
les autres types de donnes. La longueur maximale en octets dpend de la longueur maximum dclare en caractres
(voir ci-dessus) et l'encodage du serveur.

numeric_precision

cardinal_number

Si data_type identifie un type numrique, cette colonne


contient la prcision (dclare ou implicite) du type pour ce
domaine. La prcision indique le nombre de chiffres significatifs. Elle peut tre exprime en dcimal (base 10) ou en
binaire (base 2) comme indiqu dans la colonne numeric_precision_radix. Pour tous les autres types de
donnes, la colonne est NULL.

numeric_precision_radix

cardinal_number

Si data_type identifie un type numrique, cette colonne


indique dans quelle base les valeurs des colonnes numeric_precision et numeric_scale sont exprimes.
La valeur est 2 ou 10. Pour tous les autres types de donnes,
cette colonne est NULL.

numeric_scale

cardinal_number

Si data_type identifie un type numeric exact, cette colonne contient l'chelle (dclare ou implicite) du type pour
ce domaine. L'chelle indique le nombre de chiffres significatifs la droite du point dcimal. Elle peut tre exprime
en dcimal (base 10) ou en binaire (base 2), comme indiqu
dans la colonne numeric_precision_radix. Pour
tous les autres types de donnes, cette colonne est NULL.

datetime_precision

cardinal_number

Si data_type identifie une date, une heure, un horodatage ou un interval, cette colonne contient la prcision en
secondes (dclare ou implicite) pour cet attribut,
c'est--dire le nombre de chiffres dcimaux suivant le point
dcimal de la valeur en secondes. Pour tous les autres types
de donnes, cette colonne est NULL.

interval_type

character_data

Pas encore implant

interval_precision

character_data

Pas encore implant

character_set_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

collation_catalog

sql_identifier

Pas encore implment.

collation_schema

sql_identifier

Pas encore implment.

collation_name

sql_identifier

Pas encore implment.

domain_catalog

sql_identifier

Si la colonne a un type domaine, le nom de la base de donnes o le type est dfini (toujours la base de donnes courante), sinon NULL.

domain_schema

sql_identifier

Si la colonne a un type domaine, le nom du schma o le


domaine est dfini, sinon NULL.

domain_name

sql_identifier

Si la colonne a un type de domaine, le nom du domaine, sinon NULL.

udt_catalog

sql_identifier

Nom de la base de donnes o le type de donnes de la colonne (le type sous-jacent du domaine, si applicable) est dfini (toujours la base de donnes courante).

udt_schema

sql_identifier

Nom du schma o le type de donnes de la colonne (le


615

Schma d'information

Nom

Type de donnes

Description
type sous-jacent du domaine, si applicable) est dfini.

udt_name

sql_identifier

Nom du type de donnes de la colonne (le type sous-jacent


du domaine, si applicable).

scope_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

scope_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

scope_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

maximum_cardinality

cardinal_number

Toujours NULL car les tableaux ont toujours une cardinalit maximale illimite avec PostgreSQL.

dtd_identifier

sql_identifier

Un identifiant du descripteur du type de donnes de la colonne, unique parmi les descripteurs de type de donnes
contenus dans la table. Ceci est principalement utile pour
joindre d'autres instances de ces identifiants. (Le format
spcifique de l'identifiant n'est pas dfini et rien ne permet
d'assurer qu'il restera inchang dans les versions futures.)

is_self_referencing

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

is_identity

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

identity_generation

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

identity_start

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

identity_increment

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

identity_maximum

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

identity_minimum

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

identity_cycle

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

is_generated

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

generation_expression

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

is_updatable

yes_or_no

YES si la colonne est actualisable, NO dans le cas contraire


(les colonnes des tables sont toujours modifiables, les colonnes des vues ne le sont pas ncessairement).

Puisqu'en SQL les possibilits de dfinir les types de donnes sont nombreuses, et que PostgreSQL offre des possibilits supplmentaires, leur reprsentation dans le schma d'information peut s'avrer complexe.
La colonne data_type est suppose identifier le type de donnes interne sous-jacent de la colonne. Avec PostgreSQL, cela
signifie que le type est dfini dans le schma du catalogue systme pg_catalog. Cette colonne est utile si l'application sait grer
les types internes (par exemple, formater les types numriques diffremment ou utiliser les donnes dans les colonnes de prcision). Les colonnes udt_name, udt_schema et udt_catalog identifient toujours le type de donnes sous-jacent de la colonne mme si la colonne est base sur un domaine.
Puisque PostgreSQL traite les types internes comme des types utilisateur, les types internes apparaissent aussi ici. Il s'agit d'une
extension du standard SQL.
Toute application conue pour traiter les donnes en fonction du type peut utiliser ces colonnes, car, dans ce cas, il importe peu de
savoir si la colonne est effectivement fonde sur un domaine. Si la colonne est fonde sur un domaine, l'identit du domaine est
616

Schma d'information

stocke dans les colonnes domain_name, domain_schema et domain_catalog. Pour assembler les colonnes avec leurs
types de donnes associs et traiter les domaines comme des types spars, on peut crire coalesce(domain_name,
udt_name), etc.

34.16. constraint_column_usage
La vue constraint_column_usage identifie toutes les colonnes de la base de donnes courante utilises par des contraintes.
Seules sont affiches les colonnes contenues dans une table possde par un rle connect. Pour une contrainte de vrification,
cette vue identifie les colonnes utilises dans l'expression de la vrification. Pour une contrainte de cl trangre, cette vue identifie les colonnes que la cl trangre rfrence. Pour une contrainte d'unicit ou de cl primaire, cette vue identifie les colonnes
contraintes.
Tableau 34.14. Colonnes de constraint_column_usage

Nom

Type de donnes

Description

table_catalog

sql_identifier

Nom de la base de donnes contenant la table contenant la


colonne utilise par certaines contraintes (toujours la base
de donnes courante)

table_schema

sql_identifier

Nom du schma contenant la table contenant la colonne utilise par certaines contraintes

table_name

sql_identifier

Nom de la table contenant la colonne utilise par certaines


contraintes

column_name

sql_identifier

Nom de la colonne utilise par certaines contraintes

constraint_catalog

sql_identifier

Nom de la base de donnes contenant la contrainte (toujours


la base de donnes courante)

constraint_schema

sql_identifier

Nom du schma contenant la contrainte

constraint_name

sql_identifier

Nom de la contrainte

34.17. constraint_table_usage
La vue constraint_table_usage identifie toutes les tables de la base de donnes courante utilises par des contraintes et
possdes par un rle actuellement activ. (Cela diffre de la vue table_constraints qui identifie toutes les contraintes et la
table o elles sont dfinies.) Pour une contrainte de cl trangre, cette vue identifie la table que la cl trangre rfrence. Pour
une contrainte d'unicit ou de cl primaire, cette vue identifie simplement la table laquelle appartient la contrainte. Les
contraintes de vrification et les contraintes de non nullit (NOT NULL) ne sont pas incluses dans cette vue.
Tableau 34.15. Colonnes de constraint_table_usage

Nom

Type de donnes

Description

table_catalog

sql_identifier

Nom de la base de donnes contenant la table utilise par


quelques contraintes (toujours la base de donnes courante)

table_schema

sql_identifier

Nom du schma contenant la table utilise par quelque


contrainte

table_name

sql_identifier

Nom de la table utilise par quelque contrainte

constraint_catalog

sql_identifier

Nom de la base de donnes contenant la contrainte (toujours


la base de donnes courante)

constraint_schema

sql_identifier

Nom du schma contenant la contrainte

constraint_name

sql_identifier

Nom de la contrainte

34.18. data_type_privileges
La vue data_type_privileges identifie tous les descripteurs de type de donnes auxquels l'utilisateur a accs, parce qu'il en
est le propritaire ou parce qu'il dispose de quelque droit sur le descripteur. Un descripteur de type de donnes est cr lorsqu'un
type de donnes est utilis dans la dfinition d'une colonne de table, d'un domaine ou d'une fonction (en tant que paramtre ou
617

Schma d'information

code de retour). Il stocke alors quelques informations sur l'utilisation du type de donnes (par exemple la longueur maximale dclare, si applicable). Chaque descripteur de type de donnes se voit affecter un identifiant unique parmi les descripteurs de type
de donnes affects un objet (table, domaine, fonction). Cette vue n'est probablement pas utile pour les applications, mais elle est
utilise pour dfinir d'autres vues dans le schma d'information.
Tableau 34.16. Colonnes de data_type_privileges

Nom

Type de donnes

Description

object_catalog

sql_identifier

Nom de la base de donnes contenant l'objet dcrit (toujours


la base de donnes courante)

object_schema

sql_identifier

Nom du schma contenant l'objet dcrit

object_name

sql_identifier

Nom de l'objet dcrit

object_type

character_data

Le type d'objet dcrit : fait partie de TABLE (le descripteur


de type de donnes concerne une colonne de cette table),
DOMAIN (le descripteur concerne ce domaine), ROUTINE
(le descripteur est li un type de paramtre ou de code de
retour de cette fonction).

dtd_identifier

sql_identifier

L'identifiant du descripteur de type de donnes, unique parmi les descripteurs de type de donnes pour le mme objet.

34.19. domain_constraints
La vue domain_constraints contient toutes les contraintes appartenant aux domaines dfinis dans la base courante.
Tableau 34.17. Colonnes de domain_constraints

Nom

Type de donnes

Description

constraint_catalog

sql_identifier

Nom de la base de donnes contenant la contrainte (toujours


la base de donnes courante)

constraint_schema

sql_identifier

Nom du schma contenant la contrainte

constraint_name

sql_identifier

Nom de la contrainte

domain_catalog

sql_identifier

Nom de la base de donnes contenant le domaine (toujours


la base de donnes courante)

domain_schema

sql_identifier

Nom du schma contenant le domaine

domain_name

sql_identifier

Nom du domaine

is_deferrable

yes_or_no

YES si la vrification de la contrainte peut tre diffre, NO


sinon

initially_deferred

yes_or_no

YES si la vrification de la contrainte, qui peut tre diffre,


est initialement diffre, NO sinon

34.20. domain_udt_usage
La vue domain_udt_usage identifie tous les domaines utilisant les types de donnes possds par un rle actif. Sous PostgreSQL, les types de donnes internes se comportent comme des types utilisateur. Ils sont donc inclus ici.
Tableau 34.18. Colonnes de domain_udt_usage

Nom

Type de donnes

Description

udt_catalog

sql_identifier

Nom de la base de donnes de dfinition du type de donnes domaine (toujours la base de donnes courante)

udt_schema

sql_identifier

Nom du schma de dfinition du type de donnes domaine

udt_name

sql_identifier

Nom du type de donnes domaine

domain_catalog

sql_identifier

Nom de la base de donnes contenant le domaine (toujours


la base de donnes courante)
618

Schma d'information

Nom

Type de donnes

Description

domain_schema

sql_identifier

Nom du schma contenant le domaine

domain_name

sql_identifier

Nom du domaine

34.21. domains
La vue domains contient tous les domaines dfinis dans la base de donnes courante.
Tableau 34.19. Colonnes de domains

Nom

Type de donnes

Description

domain_catalog

sql_identifier

Nom de la base de donnes contenant le domaine (toujours


la base de donnes courante)

domain_schema

sql_identifier

Nom du schma contenant le domaine

domain_name

sql_identifier

Nom du domaine

data_type

character_data

Type de donnes du domaine s'il s'agit d'un type interne, ou


ARRAY s'il s'agit d'un tableau (dans ce cas, voir la vue
element_types), sinon USER-DEFINED (dans ce cas,
le type est identifi dans udt_name et comprend des colonnes associes).

character_maximum_length

cardinal_number

Si le domaine a un type caractre ou chane de bits, la longueur maximale dclare ; NULL pour tous les autres types
de donnes ou si aucune longueur maximale n'a t dclare.

character_octet_length

cardinal_number

Si le domaine a un type caractre, la longueur maximale en


octets (bytes) d'un datum ; NULL pour tous les autres types
de donnes. La longueur maximale en octets dpend de la
longueur maximum dclare en caractres (voir ci-dessus)
et l'encodage du serveur.

character_set_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

collation_catalog

sql_identifier

Pas encore implment.

collation_schema

sql_identifier

Pas encore implment.

collation_name

sql_identifier

Pas encore implment.

numeric_precision

cardinal_number

Si le domaine a un type numrique, cette colonne contient


la prcision (dclare ou implicite) du type de cette colonne. Cette prcision indique le nombre de chiffres significatifs. Elle peut tre exprime en dcimal (base 10) ou en
binaire (base 2), comme indiqu dans la colonne numeric_precision_radix. Pour les autres types de donnes, cette colonne est NULL.

numeric_precision_radix

cardinal_number

Si le domaine a un type numrique, cette colonne indique la


base des valeurs des colonnes numeric_precision et
numeric_scale. La valeur est soit 2 soit 10. Pour tous
les autres types de donnes, cette colonne est NULL.

numeric_scale

cardinal_number

Si le domaine contient un type numeric, cette colonne


contient l'chelle (dclare ou implicite) du type pour cette
colonne. L'chelle indique le nombre de chiffres significatifs droite du point dcimal. Elle peut tre exprime en dcimal (base 10) ou en binaire (base 2), comme indiqu dans
la colonne numeric_precision_radix. Pour tous les
619

Schma d'information

Nom

Type de donnes

Description
autres types de donnes, cette colonne est NULL.

datetime_precision

cardinal_number

Si le domaine contient un type date, heure ou intervalle, la


prcision dclare ; NULL pour les autres types de donnes
ou si la prcision n'a pas t dclare.

interval_type

character_data

Pas encore implant

interval_precision

character_data

Pas encore implant

domain_default

character_data

Expression par dfaut du domaine

udt_catalog

sql_identifier

Nom de la base de donnes dans laquelle est dfini le type


de donnes domaine (toujours la base de donnes courante)

udt_schema

sql_identifier

Nom du schma o le type de donnes domaine est dfini

udt_name

sql_identifier

Nom du type de donnes domaine

scope_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

scope_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

scope_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

maximum_cardinality

cardinal_number

Toujours NULL car les tableaux n'ont pas de limite maximale de cardinalit dans PostgreSQL

dtd_identifier

sql_identifier

Un identifiant du descripteur de type de donnes du domaine, unique parmi les descripteurs de type de donnes
restant dans le domaine (ce qui est trivial car un domaine
contient seulement un descripteur de type de donnes). Ceci
est principalement utile pour joindre d'autres instances de
tels identifiants (le format spcifique de l'identifiant n'est
pas dfini et il n'est pas garanti qu'il restera identique dans
les versions futures).

34.22. element_types
La vue element_types contient les descripteurs de type de donnes des lments de tableaux. Lorsqu'une colonne de table,
domaine, paramtre de fonction ou code de retour de fonction est dfinie comme un type tableau, la vue respective du schma
d'information contient seulement ARRAY dans la colonne data_type. Pour obtenir des informations sur le type d'lment du tableau, il est possible de joindre la vue respective avec cette vue. Par exemple, pour afficher les colonnes d'une table avec les types
de donnes et les types d'lment de tableau, si applicable, on peut crire :
SELECT c.column_name, c.data_type, e.data_type AS element_type
FROM information_schema.columns c LEFT JOIN information_schema.element_types e
ON ((c.table_catalog, c.table_schema, c.table_name, 'TABLE', c.dtd_identifier)
= (e.object_catalog, e.object_schema, e.object_name, e.object_type,
e.collection_type_identifier))
WHERE c.table_schema = '...' AND c.table_name = '...'
ORDER BY c.ordinal_position;
Cette vue n'inclut que les objets auxquels l'utilisateur courant a accs, parce que propritaire ou disposant de quelque privilge.
Tableau 34.20. Colonnes de element_types

Nom

Type de donnes

Description

object_catalog

sql_identifier

Nom de la base de donnes contenant l'objet qui utilise le


tableau dcrit (toujours la base de donnes courante)

object_schema

sql_identifier

Nom du schma contenant l'objet utilisant le tableau dcrit

object_name

sql_identifier

Nom de l'objet utilisant le tableau dcrit

object_type

character_data

Le type de l'objet utilisant le tableau dcrit : il fait partie de


TABLE (le tableau est utilis par une colonne de cette
table), DOMAIN (le tableau est utilis par ce domaine),
620

Schma d'information

Nom

Type de donnes

Description
ROUTINE (le tableau est utilis par un paramtre ou le type
du code de retour de cette fonction).

collection_type_identifier

sql_identifier

L'identifiant du descripteur de type de donnes du tableau


dcrit. Utilisez cette colonne pour faire une jointure avec les
colonnes dtd_identifier des autres vues du schma
d'informations.

data_type

character_data

Le type de donnes des lments du tableau s'il s'agit d'un


type interne, sinon USER-DEFINED (dans ce cas, le type
est identifi comme udt_name et dispose de colonnes associes).

character_maximum_length

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes d'lments de tableau dans PostgreSQL

character_octet_length

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes d'lments de tableau dans PostgreSQL

character_set_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

collation_catalog

sql_identifier

Pas encore implment.

collation_schema

sql_identifier

Pas encore implment.

collation_name

sql_identifier

Pas encore implment.

numeric_precision

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes d'lments de tableau dans PostgreSQL

numeric_precision_radix

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes d'lments de tableau dans PostgreSQL

numeric_scale

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes d'lments de tableau dans PostgreSQL

datetime_precision

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes d'lments de tableau dans PostgreSQL

interval_type

character_data

Toujours NULL car cette information n'est pas applique


aux types de donnes d'lments de tableau dans PostgreSQL

interval_precision

character_data

Toujours NULL car cette information n'est pas applique


aux types de donnes d'lments de tableau dans PostgreSQL

domain_default

character_data

Pas encore implant

udt_catalog

sql_identifier

Nom de la base de donnes pour lequel le type de donnes


est dfini (toujours la base de donnes courante)

udt_schema

sql_identifier

Nom du schma dans lequel est dfini le type de donnes


des lments

udt_name

sql_identifier

Nom du type de donnes des lments

scope_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

scope_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.


621

Schma d'information

Nom

Type de donnes

Description

scope_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

maximum_cardinality

cardinal_number

Toujours NULL car les tableaux n'ont pas de limite maximale de cardinalit dans PostgreSQL

dtd_identifier

sql_identifier

Un identifiant du descripteur de type de donnes pour cet


lment. Ceci n'est actuellement pas utile.

34.23. enabled_roles
La vue enabled_roles identifie les rles actuellement actifs . Les rles actifs sont dfinis rcursivement comme
l'utilisateur courant avec tous les rles qui ont t donns aux rles activs avec l'hritage automatique. En d'autres termes, ce sont
les rles dont l'utilisateur courant est automatiquement membre, par hritage direct ou indirect.
Pour la vrification des permissions, l'ensemble des rles applicables est appliqu, ce qui peut tre plus large que l'ensemble
des rles actifs. Il est, de ce fait, gnralement prfrable d'utiliser la vue applicable_roles la place de celle-ci ; voir aussi
l.
Tableau 34.21. Colonnes de enabled_roles

Nom

Type de donnes

Description

role_name

sql_identifier

Nom d'un rle

34.24. foreign_data_wrapper_options
La vue foreign_data_wrapper_options contient toutes les options dfinies par les wrappers de donnes distantes dans la
base de donnes en cours. Seuls les wrappers accessibles par l'utilisateur connect sont affichs (qu'il soit propritaire ou qu'il ait
des droits dessus).
Tableau 34.22. Colonnes de foreign_data_wrapper_options

Nom

Type de donnes

Description

foreign_data_wrapper_catalog sql_identifier

Nom de la base de donnes dans laquelle


est dfini le wrapper de donnes distantes
(toujours la base de connexion)

foreign_data_wrapper_name

sql_identifier

Nom du wrapper

option_name

sql_identifier

Nom d'une option

option_value

character_data

Valeur de l'option

34.25. foreign_data_wrappers
La vue foreign_data_wrappers contient tous les wrappers de donnes distantes dfinis dans le base de donnes en cours.
Seuls sont affichs les wrappers pour lesquels l'utilisateur connect a accs (qu'il soit propritaire ou qu'il ait des droits dessus).
Tableau 34.23. Colonnes de foreign_data_wrappers

Nom

Type de donnes

Description

foreign_data_wrapper_catalog sql_identifier

Nom de la base de donnes contenant le


wrapper de donnes distantes (toujours la
base de donnes en cours)

foreign_data_wrapper_name

sql_identifier

Nom du wrapper

authorization_identifier

sql_identifier

Nom du propritaire du serveur distant

library_name

character_data

Nom du fichier de la bibliothque implmentant ce wrapper


622

Schma d'information

Nom

Type de donnes

Description

foreign_data_wrapper_language

character_data

Langage utilis pour implmenter ce


wrapper

34.26. foreign_server_options
La vue foreign_server_options contient toutes les options dfinies pour les serveurs distants de la base de donnes en
cours. Ne sont affichs que les serveurs distants pour lesquels l'utilisateur connect a des droits (qu'il soit propritaire ou qu'il ait
quelques droits dessus).
Tableau 34.24. Colonnes de foreign_server_options

Nom

Type de donnes

Description

foreign_server_catalog

sql_identifier

Nom de la base de donnes contenant le


serveur distant (toujours la base de donnes en cours)

foreign_server_name

sql_identifier

Nom du serveur distant

option_name

sql_identifier

Nom d'une option

option_value

character_data

Valeur de l'option

34.27. foreign_servers
La vue foreign_servers contient tous les serveurs distants dfinis dans la base en cours. Ne sont affichs que les serveurs
distants pour lesquels l'utilisateur connect a des droits (qu'il soit propritaire ou qu'il ait quelques droits dessus).
Tableau 34.25. Colonnes de foreign_servers

Nom

Type de donnes

Description

foreign_server_catalog

sql_identifier

Nom de la base de donnes dans laquelle


ce serveur distant est dfini (toujours la
base de donnes en cours)

foreign_server_name

sql_identifier

Nom du serveur distant

foreign_data_wrapper_catalog sql_identifier

Nom de la base de donnes qui contient le


wrapper de donnes distantes utilis par le
serveur distant (toujours la base de donnes en cours)

foreign_data_wrapper_name

sql_identifier

Nom du wrapper de donnes distantes utilis par le serveur distant

foreign_server_type

character_data

Information sur le type de serveur distant,


si indiqu lors de la cration

foreign_server_version

character_data

Information sur la version de serveur distant, si indiqu lors de la cration

authorization_identifier

sql_identifier

Nom du propritaire du serveur distant

34.28. foreign_table_options
La vue foreign_table_options contient toutes les options dfinies pour les tables distantes de la base de donnes courante.
Seules sont affiches les tables distantes accessibles par l'utilisateur courant (soit parce qu'il en est le propritaire soit parce qu'il
dispose de droits particuliers).
Tableau 34.26. Colonnes de foreign_table_options

Nom

Type de donnes

Description

foreign_table_catalog

sql_identifier

Nom de la base de donnes qui contient la


623

Schma d'information

Nom

Type de donnes

Description
table distante (toujours la base de donnes
courante)

foreign_table_schema

sql_identifier

Nom du schma contenant la table distante

foreign_table_name

sql_identifier

Nom de la table distante

foreign_server_catalog

sql_identifier

Nom de la base de donnes o le serveur


distant est dfini (toujours la base de donnes courante)

foreign_server_name

sql_identifier

Nom du serveur distant

option_name

sql_identifier

Nom d'une option

option_value

character_data

Valeur de l'option

34.29. foreign_tables
La vue foreign_tables contient toutes les tables distantes dfinies dans la base de donnes courantes. Seules sont affiches
les tables distantes accessibles par l'utilisateur courant (soit parce qu'il en est le propritaire soit parce qu'il dispose de droits particuliers).
Tableau 34.27. Colonnes de foreign_tables

Nom

Type de donnes

Description

foreign_table_catalog

sql_identifier

Nom de la base de donnes qui contient la


table distante (toujours la base de donnes
courante)

foreign_table_schema

sql_identifier

Nom du schma contenant la table distante

foreign_table_name

sql_identifier

Nom de la table distante

foreign_server_catalog

sql_identifier

Nom de la base de donnes o le serveur


distant est dfini (toujours la base de donnes courante)

foreign_server_name

sql_identifier

Nom du serveur distant

34.30. key_column_usage
La vue key_column_usage identifie toutes les colonnes de la base de donnes courante restreintes par une contrainte unique,
cl primaire ou cl trangre. Les contraintes de vrification ne sont pas incluses dans cette vue. Seules sont affiches les colonnes
auxquelles l'utilisateur a accs, parce qu'il est le propritaire de la table ou qu'il dispose de quelque privilge.
Tableau 34.28. Colonnes de key_column_usage

Nom

Type de donnes

Description

constraint_catalog

sql_identifier

Nom de la base de donnes contenant la contrainte (toujours


la base de donnes courante)

constraint_schema

sql_identifier

Nom du schma contenant la contrainte

constraint_name

sql_identifier

Nom de la contrainte

table_catalog

sql_identifier

Nom de la base de donnes contenant la table contenant la


colonne contrainte (toujours la base de donnes courante)

table_schema

sql_identifier

Nom du schma contenant la table contenant la colonne


contrainte

table_name

sql_identifier

Nom de la table contenant la colonne contrainte

column_name

sql_identifier

Nom de la colonne contrainte


624

Schma d'information

Nom

Type de donnes

Description

ordinal_position

cardinal_number

Position ordinale de la colonne dans la cl de contrainte (la


numrotation commence 1)

position_in_unique_constraint cardinal_number

Pour une contrainte de type cl trangre, la position ordinale de la colonne rfrence dans sa contrainte d'unicit (la
numrotation commence 1) ; sinon null

34.31. parameters
La vue parameters contient des informations sur les paramtres (arguments) de toutes les fonctions de la base de donnes courante. Seules sont affiches les fonctions auxquelles l'utilisateur courant a accs, parce qu'il en est le propritaire ou qu'il dispose
de quelque privilge.
Tableau 34.29. Colonnes de parameters

Nom

Type de donnes

Description

specific_catalog

sql_identifier

Nom de la base de donnes contenant la fonction (toujours


la base de donnes courante)

specific_schema

sql_identifier

Nom du schma contenant la fonction

specific_name

sql_identifier

Le nom spcifique de la fonction. Voir la Section 34.38,


routines pour plus d'informations.

ordinal_position

cardinal_number

Position ordinale du paramtre dans la liste des arguments


de la fonction (la numrotation commence 1)

parameter_mode

character_data

IN pour les paramtres en entre, OUT pour les paramtres


en sortie ou INOUT pour les paramtres en entre/sortie.

is_result

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

as_locator

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

parameter_name

sql_identifier

Nom du paramtre ou NULL si le paramtre n'a pas de nom

data_type

character_data

Type de donnes du paramtre s'il s'agit d'un type interne,


ou ARRAY s'il s'agit d'un tableau (dans ce cas, voir la vue
element_types), sinon USER-DEFINED (dans ce cas,
le type est identifi dans udt_name et dispose de colonnes
associes).

character_maximum_length

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes dans PostgreSQL

character_octet_length

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes dans PostgreSQL

character_set_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

collation_catalog

sql_identifier

Toujours NULL car cette information n'est pas applique


pour configurer les types de donnes dans PostgreSQL

collation_schema

sql_identifier

Toujours NULL car cette information n'est pas applique


pour configurer les types de donnes dans PostgreSQL

collation_name

sql_identifier

Toujours NULL car cette information n'est pas applique


pour configurer les types de donnes dans PostgreSQL

numeric_precision

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes dans PostgreSQL
625

Schma d'information

Nom

Type de donnes

Description

numeric_precision_radix

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes dans PostgreSQL

numeric_scale

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes dans PostgreSQL

datetime_precision

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes dans PostgreSQL

interval_type

character_data

Toujours NULL car cette information n'est pas applique


aux types de donnes dans PostgreSQL

interval_precision

character_data

Toujours NULL car cette information n'est pas applique


aux types de donnes dans PostgreSQL

udt_catalog

sql_identifier

Nom de la base de donnes sur laquelle est dfini le paramtre (toujours la base de donnes courante)

udt_schema

sql_identifier

Nom du schma dans lequel est dfini le type de donnes du


paramtre

udt_name

sql_identifier

Nom du type de donnes du paramtre

scope_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

scope_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

scope_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

maximum_cardinality

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes dans PostgreSQL

dtd_identifier

sql_identifier

Un identifiant du descripteur de type de donnes du paramtre, unique parmi les descripteurs de type de donnes
restant dans la fonction. Ceci est principalement utile pour
raliser une jointure avec les autres instances de tels identifiants (le format spcifique de l'identifiant n'est pas dfini et
il n'est pas garanti qu'il reste identique dans les prochaines
versions).

34.32. referential_constraints
La vue referential_constraints contient toutes les contraintes rfrentielles (cls trangres) au sein de la base de donnes courante. Seuls sont affichs les contraintes pour lesquelles l'utilisateur connect a accs en criture sur la table rfrenante
(parce qu'il est le propritaire ou qu'il a d'autres droits que SELECT).
Tableau 34.30. Colonnes de referential_constraints

Nom

Type de donnes

Description

constraint_catalog

sql_identifier

Nom de la base de donnes contenant la contrainte (toujours


la base de donnes courante)

constraint_schema

sql_identifier

Nom du schma contenant la contrainte

constraint_name

sql_identifier

Nom de la contrainte

unique_constraint_catalog

sql_identifier

Nom de la base de donnes contenant la contrainte d'unicit


ou de cl primaire que la contrainte de cl trangre rfrence (toujours la base de donnes courante)

unique_constraint_schema

sql_identifier

Nom du schma contenant la contrainte d'unicit ou de cl


primaire que la contrainte de cl trangre rfrence

unique_constraint_name

sql_identifier

Nom de la contrainte d'unicit ou de cl primaire que la


contrainte de cl trangre rfrence

match_option

character_data

Correspondances de la contrainte de cl trangre : FULL,


PARTIAL ou NONE.

626

Schma d'information

Nom

Type de donnes

Description

update_rule

character_data

Rgle de mise jour associe la contrainte de cl trangre : CASCADE, SET NULL, SET DEFAULT, RESTRICT ou NO ACTION.

delete_rule

character_data

Rgle de suppression associe la contrainte de cl trangre : CASCADE, SET NULL, SET DEFAULT, RESTRICT ou NO ACTION.

34.33. role_column_grants
La vue role_column_grants identifie tous les privilges de colonne octroys pour lesquels le donneur ou le bnficiaire est
un rle actuellement actif. Plus d'informations sous column_privileges. La seule diffrence relle entre cette vue et column_privileges est que cette vue omet les colonnes qui ont t rendues accessibles l'utilisateur actuel en utilisant la commande GRANT pour PUBLIC.
Tableau 34.31. Colonnes de role_column_grants

Nom

Type de donnes

Description

grantor

sql_identifier

Nom du rle qui a octroy le privilge

grantee

sql_identifier

Nom du rle bnficiaire

table_catalog

sql_identifier

Nom de la base de donnes qui contient la table qui contient


la colonne (toujours la base de donnes courante)

table_schema

sql_identifier

Nom du schma qui contient la table qui contient la colonne

table_name

sql_identifier

Nom de la table qui contient la colonne

column_name

sql_identifier

Nom de la colonne

privilege_type

character_data

Type de privilge : SELECT, INSERT, UPDATE, DELETE,


TRUNCATE, REFERENCES ou TRIGGER

is_grantable

yes_or_no

YES si le droit peut tre transmis, NO sinon

34.34. role_routine_grants
La vue role_routine_grants identifie tous les privilges de routine octriys lorsque le donneur ou le bnficiaire est un
rle actif. Plus d'informations sous routine_privileges. La seule diffrence relle entre cette vue et routine_privileges est que cette vue omet les colonnes qui ont t rendues accessibles l'utilisateur actuel en utilisant la commande GRANT pour PUBLIC.
Tableau 34.32. Colonnes de role_routine_grants

Nom

Type de donnes

Description

grantor

sql_identifier

Nom du rle qui a octroy le privilge

grantee

sql_identifier

Nom du rle bnficiaire

specific_catalog

sql_identifier

Nom de la base de donnes qui contient la fonction


(toujours la base de donnes courante)

specific_schema

sql_identifier

Nom du schma qui contient la fonction

specific_name

sql_identifier

Le nom spcifique de la fonction. Voir la Section 34.38,


routines pour plus d'informations.

routine_catalog

sql_identifier

Nom de la base de donnes qui contient la fonction


(toujours la base de donnes courante)

routine_schema

sql_identifier

Nom du schma qui contient la fonction

routine_name

sql_identifier

Nom de la fonction (peut tre dupliqu en cas de surcharge)

privilege_type

character_data

Toujours EXECUTE (seul type de privilge sur les fonctions)


627

Schma d'information

Nom

Type de donnes

Description

is_grantable

yes_or_no

YES si le droit peut tre transmis, NO sinon

34.35. role_table_grants
La vue role_table_grants identifie tous les privilges de tables octroys lorsque le donneur ou le bnficiaire est un rle
actif. Plus d'informations sous table_privileges. La seule diffrence relle entre cette vue et table_privileges est
que cette vue omet les colonnes qui ont t rendues accessibles l'utilisateur actuel en utilisant la commande GRANT pour PUBLIC.
Tableau 34.33. Colonnes de role_table_grants

Nom

Type de donnes

Description

grantor

sql_identifier

Nom du rle qui a octroy le privilge

grantee

sql_identifier

Nom du rle bnficiaire

table_catalog

sql_identifier

Nom de la base de donnes qui contient la table (toujours la


base de donnes courante)

table_schema

sql_identifier

Nom du schma qui contient la table

table_name

sql_identifier

Nom de la table

privilege_type

character_data

Type du privilge : SELECT, DELETE, INSERT, UPDATE,


REFERENCES ou TRIGGER

is_grantable

yes_or_no

YES si le droit peut tre transmis, NO sinon

with_hierarchy

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

34.36. role_usage_grants
La vue role_usage_grants identifie les privilges d'USAGE sur diffrents types d'objets o le donneur ou le receveur des
droits est un rle actuellement activ. Plus d'informations sous usage_privileges. Dans le futur, cette vue pourrait contenir
des informations plus utiles. La seule diffrence relle entre cette vue et usage_privileges est que cette vue omet les colonnes qui ont t rendues accessibles l'utilisateur actuel en utilisant la commande GRANT pour PUBLIC.
Tableau 34.34. Colonnes de role_usage_grants

Nom

Type de donnes

Description

grantor

sql_identifier

Nom du rle qui a octroy le privilge

grantee

sql_identifier

Nom du rle bnficiaire

object_catalog

sql_identifier

Nom de la base de donnes qui contient l'objet (toujours la


base de donnes courante)

object_schema

sql_identifier

Nom du schma qui contient l'objet, if applicable, sinon une


chane vide

object_name

sql_identifier

Nom de l'objet

object_type

character_data

COLLATION, DOMAIN, FOREIGN DATA WRAPPER ou


FOREIGN SERVER

privilege_type

character_data

Toujours USAGE

is_grantable

yes_or_no

YES si le droit peut tre transmis, NO sinon

34.37. routine_privileges
La vue routine_privileges identifie tous les droits sur les fontions un rle actuellement activ ou par un rle actuellement activ. Il existe une ligne pour chaque combinaison fonction, donneur, bnficiaire.

628

Schma d'information

Tableau 34.35. Colonnes de routine_privileges

Nom

Type de donnes

Description

grantor

sql_identifier

Nom du rle qui a accord le privilge

grantee

sql_identifier

Nom du rle bnficiaire

specific_catalog

sql_identifier

Nom de la base de donnes qui contient la fonction


(toujours la base de donnes courante)

specific_schema

sql_identifier

Nom du schma qui contient la fonction

specific_name

sql_identifier

Le nom spcifique de la fonction. Voir la Section 34.38,


routines pour plus d'informations.

routine_catalog

sql_identifier

Nom de la base de donnes qui contient la fonction


(toujours la base de donnes courante)

routine_schema

sql_identifier

Nom du schma qui contient la fonction

routine_name

sql_identifier

Nom de la fonction (peut tre dupliqu en cas de surcharge)

privilege_type

character_data

Toujours EXECUTE (seul priilge de fonctions)

is_grantable

yes_or_no

YES si le droit peut tre transmis, NO sinon

34.38. routines
La vue routines contient toutes les fonctions de la base de donnes courante. Seules sont affiches les fonctions auxquelles
l'utilisateur courant a accs (qu'il en soit le propritaire ou dispose de de privilges).
Tableau 34.36. Colonnes de routines

Nom

Type de donnes

Description

specific_catalog

sql_identifier

Nom de la base de donnes qui contient la fonction


(toujours la base de donnes courante)

specific_schema

sql_identifier

Nom du schma qui contient la fonction

specific_name

sql_identifier

Le nom spcifique de la fonction. Ce nom identifie de


faon unique la fonction dans le schma, mme si le nom
rel de la fonction est surcharg. Le format du nom spcifique n'est pas dfini, il ne devrait tre utilis que dans un
but de comparaison avec d'autres instances de noms spcifiques de routines.

routine_catalog

sql_identifier

Nom de la base de donnes qui contient la fonction


(toujours la base de donnes courante)

routine_schema

sql_identifier

Nom du schma qui contient la fonction

routine_name

sql_identifier

Nom de la fonction (peut tre dupliqu en cas de surcharge)

routine_type

character_data

Toujours FUNCTION (dans le futur, il pourrait y avoir


d'autres types de routines)

module_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

module_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

module_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

udt_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

udt_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

udt_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.


629

Schma d'information

Nom

Type de donnes

Description

data_type

character_data

Type de donnes de retour de la fonction s'il est interne,


ARRAY s'il s'agit d'un tableau (dans ce cas, voir la vue
element_types), sinon USER-DEFINED (dans ce cas,
le type est identifi dans type_udt_name et dispose de
colonnes associes).

character_maximum_length

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes renvoyes sous PostgreSQL

character_octet_length

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes renvoyes sous PostgreSQL

character_set_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

character_set_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

collation_catalog

sql_identifier

Toujours NULL car cette information n'est pas applique


pour configurer les types de donnes dans PostgreSQL

collation_schema

sql_identifier

Toujours NULL car cette information n'est pas applique


pour configurer les types de donnes dans PostgreSQL

collation_name

sql_identifier

Toujours NULL car cette information n'est pas applique


pour configurer les types de donnes dans PostgreSQL

numeric_precision

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes renvoyes sous PostgreSQL

numeric_precision_radix

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes renvoyes sous PostgreSQL

numeric_scale

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes renvoyes sous PostgreSQL

datetime_precision

cardinal_number

Toujours NULL car cette information n'est pas applique


aux types de donnes renvoyes sous PostgreSQL

interval_type

character_data

Toujours NULL car cette information n'est pas applique


aux types de donnes renvoyes sous PostgreSQL

interval_precision

character_data

Toujours NULL car cette information n'est pas applique


aux types de donnes renvoyes sous PostgreSQL

type_udt_catalog

sql_identifier

Nom de la base de donnes dans laquelle est dfini le type


de donnes de retour de la fonction (toujours la base de
donnes courante)

type_udt_schema

sql_identifier

Nom du schma dans lequel est dfini le type de donnes de


retour de la fonction

type_udt_name

sql_identifier

Nom du type de donnes de retour de la fonction

scope_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

scope_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

scope_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

maximum_cardinality

cardinal_number

Toujours NULL car il n'y a pas de limite maximale la cardinalit des tableaux dans PostgreSQL

dtd_identifier

sql_identifier

Un identifiant du descripteur de type de donnes du type de


donnes retour, unique parmi les descripteurs de type de
donnes de la fonction. Ceci est principalement utile pour la
jointure avec d'autres instances de tels identifiants (le format spcifique de l'identifiant n'est pas dfini et il n'est pas
certain qu'il restera identique dans les versions futures).
630

Schma d'information

Nom

Type de donnes

Description

routine_body

character_data

Si la fonction est une fonction SQL, alors SQL, sinon EXTERNAL.

routine_definition

character_data

Le texte source de la fonction (NULL si la fonction


n'appartient pas un rle actif). (Le standard SQL prcise
que cette colonne n'est applicable que si routine_body
est SQL, mais sous PostgreSQL ce champ contient tout
texte source prcis la cration de la fonction.)

external_name

character_data

Si la fonction est une fonction C, le nom externe (link symbol) de la fonction ; sinon NULL. (Il s'agit de la mme valeur que celle affiche dans routine_definition).

external_language

character_data

Le langage d'criture de la fonction

parameter_style

character_data

Toujours GENERAL (le standard SQL dfinit d'autres styles


de paramtres qui ne sont pas disponibles avec
PostgreSQL).

is_deterministic

yes_or_no

Si la fonction est dclare immuable (dterministe dans le


standard SQL), alors YES, sinon NO. (Les autres niveaux de
volatilit disponibles dans PostgreSQL ne peuvent tre
rcuprs via le schma d'informations).

sql_data_access

character_data

Toujours MODIFIES, ce qui signifie que la fonction peut


modifier les donnes SQL. Cette information n'est pas utile
sous PostgreSQL.

is_null_call

yes_or_no

Si la fonction renvoie automatiquement NULL si un de ces


arguments est NULL, alors YES, sinon NO.

sql_path

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

schema_level_routine

yes_or_no

Toujours YES. (L'oppos serait une mthode d'un type utilisateur, fonctionnalit non disponible dans PostgreSQL).

max_dynamic_result_sets

cardinal_number

S'applique une fonctionnalit non disponible dans PostgreSQL.

is_user_defined_cast

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

is_implicitly_invocable

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

security_type

character_data

Si la fonction est excute avec les droits de l'utilisateur


courant, alors INVOKER. Si la fonction est excute avec
les droits de l'utilisateur l'ayant dfinie, alors DEFINER.

to_sql_specific_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

to_sql_specific_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

to_sql_specific_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

as_locator

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

created

time_stamp

S'applique une fonctionnalit non disponible dans PostgreSQL

last_altered

time_stamp

S'applique une fonctionnalit non disponible dans PostgreSQL

new_savepoint_level

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL

is_udt_dependent

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_from_data_type

character_data

S'applique une fonctionnalit non disponible dans Post631

Schma d'information

Nom

Type de donnes

Description
greSQL

result_cast_as_locator

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_char_max_length

cardinal_number

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_char_octet_length character_data

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_char_set_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_char_set_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_char_set_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_collation_catalog sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_collation_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_collation_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_numeric_precision cardinal_number

S'applique une fonctionnalit non disponible dans PostgreSQL

recardinal_number
sult_cast_numeric_precision_r
adix

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_numeric_scale

cardinal_number

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_datetime_precision

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_interval_type

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_interval_precision

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_type_udt_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_type_udt_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_type_udt_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_scope_catalog

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_scope_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

result_cast_scope_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

recardinal_number
sult_cast_maximum_cardinality
result_cast_dtd_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

34.39. schemata
632

Schma d'information

La vue schemata contient tous les schmas de la base de donnes courante dont un rle actif est propritaire.
Tableau 34.37. Colonnes de schemata

Nom

Type de donnes

Description

catalog_name

sql_identifier

Nom de la base de donnes dans laquelle se trouve le schma (toujours la base de donnes courante)

schema_name

sql_identifier

Nom du schma

schema_owner

sql_identifier

Nom du propritaire du schma

default_character_set_catalog sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

default_character_set_schema

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

default_character_set_name

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

sql_path

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

34.40. sequences
La vue sequences contient toutes les squences dfinies dans la base courante. Seules sont affiches les squences auxquelles
l'utilisateur courant a accs (qu'il en soit le propritaire ou dispose de privilges).
Tableau 34.38. Colonnes de sequences

Nom

Type de donnes

Description

sequence_catalog

sql_identifier

Nom de la base qui contient la squence


(toujours la base en cours)

sequence_schema

sql_identifier

Nom du schma qui contient la squence

sequence_name

sql_identifier

Nom de la squence

data_type

character_data

Type de donnes de la squence. Dans


PostgreSQL, c'est toujours bigint.

numeric_precision

cardinal_number

Cette colonne contient la prcision


(dclare ou implicite) du type de donnes
de la squence (voir ci-dessus). La prcision indique le nombre de chiffres significatifs. Elle peut tre exprime en dcimal
(base 10) ou en binaire (base 2), suivant
ce qui est indiqu dans la colonne numeric_precision_radix.

numeric_precision_radix

cardinal_number

Cette colonne indique dans quelle base les


valeurs
de
la
colonne
numeric_precision et numeric_scale
sont exprimes, 2 ou 10.

numeric_scale

cardinal_number

Cette colonne contient l'chelle (dclare


ou implicite) du type de donnes de la squence (voir ci-dessus). L'chelle indique
le nombre de chiffres significatifs droite
du point dcimale. Elle peut tre exprime
en dcimal (base 10) ou en binaire (base
2), suivant ce qui est indiqu dans la colonne numeric_precision_radix.

start_value

character_data

La valeur de dmarrage de la squence

minimum_value

character_data

la valeur minimale de la squence


633

Schma d'information

Nom

Type de donnes

Description

maximum_value

character_data

La valeur maximale de la squence

increment

character_data

L'incrment de la squence

cycle_option

yes_or_no

YES si la squence est cyclique, NO dans


le cas contraire

Notez qu'en accord avec le standard SQL, les valeurs de dmarrage, minimale, maximale et d'incrment sont renvoyes en tant
que chanes de caractres.

34.41. sql_features
La table sql_features contient des informations sur les fonctionnalits officielles dfinies dans le standard SQL et supportes
par PostgreSQL. Ce sont les mmes informations que celles prsentes dans l'Annexe D, Conformit SQL. D'autres informations de fond y sont disponibles.
Tableau 34.39. Colonnes de sql_features

Nom

Type de donnes

Description

feature_id

character_data

Chane identifiant la fonctionnalit

feature_name

character_data

Nom descriptif de la fonctionnalit

sub_feature_id

character_data

Chane identifiant la sous-fonctionnalit ou chane de longueur NULL s'il ne s'agit pas d'une sous-fonctionnalit

sub_feature_name

character_data

Nom descriptif de la sous-fonctionnalit ou chane de longueur NULL s'il ne s'agit pas d'une sous-fonctionnalit

is_supported

yes_or_no

YES si la fonctionnalit est compltement supporte par la


version actuelle de PostgreSQL, NO sinon

is_verified_by

character_data

Toujours NULL car le groupe de dveloppement PostgreSQL ne ralise pas de tests formels sur la conformit des
fonctionnalits

comments

character_data

Un commentaire ventuel sur le statut du support de la


fonctionnalit

34.42. sql_implementation_info
La table sql_inplementation_info contient des informations sur diffrents aspects que le standard SQL laisse la discrtion de l'implantation. Ces informations n'ont de rel intrt que dans le contexte de l'interface ODBC ; les utilisateurs des autres
interfaces leur trouveront certainement peu d'utilit. Pour cette raison, les lments dcrivant l'implantation ne sont pas dcrits ici ;
ils se trouvent dans la description de l'interface ODBC.
Tableau 34.40. Colonnes de sql_implementation_info

Nom

Type de donnes

Description

implementation_info_id

character_data

Chane identifiant l'lment d'information d'implantation

implementation_info_name

character_data

Nom descriptif de l'lment d'information d'implantation

integer_value

cardinal_number

Valeur de l'lment d'information d'implantation, ou NULL


si la valeur est contenue dans la colonne character_value

character_value

character_data

Valeur de l'lment d'information d'implantation, ou NULL


si la valeur est contenue dans la colonne integer_value

comments

character_data

Un commentaire ventuel de l'lment d'information


d'implantation

34.43. sql_languages
634

Schma d'information

La table sql_languages contient une ligne par langage li au SQL support par PostgreSQL. PostgreSQL supporte le
SQL direct et le SQL intgr dans le C ; cette table ne contient pas d'autre information.
Cette table a t supprime du standard SQL dans SQL:2008, donc il n'y a pas d'enregistrements faisant rfrence aux standards
ultrieurs SQL:2003.
Tableau 34.41. Colonnes de sql_languages

Nom

Type de donnes

Description

sql_language_source

character_data

Le nom de la source de dfinition du langage ; toujours ISO 9075, c'est--dire le


standard SQL

sql_language_year

character_data

L'anne de l'approbation du standard dans


sql_language_source

sql_language_conformance

character_data

Le niveau de conformit au standard pour


le langage. Pour ISO 9075:2003, c'est toujours CORE.

sql_language_integrity

character_data

Toujours NULL (cette valeur n'a d'intrt


que pour les versions prcdentes du standard SQL).

sql_language_implementation

character_data

Toujours NULL

sql_language_binding_style

character_data

Le style de lien du langage, soit DIRECT


soit EMBEDDED

sql_language_programming_language

character_data

Le langage de programmation si le style


de lien est EMBEDDED, sinon NULL.
PostgreSQL ne supporte que le langage
C.

34.44. sql_packages
La table sql_packages contient des informations sur les paquets de fonctionnalits dfinis dans le standard SQL supports par
PostgreSQL. On se rfrera l'Annexe D, Conformit SQL pour des informations de base sur les paquets de fonctionnalits.
Tableau 34.42. Colonnes de sql_packages

Nom

Type de donnes

Description

feature_id

character_data

Chane identifiant le paquet

feature_name

character_data

Nom descriptif du paquet

is_supported

yes_or_no

YES si le paquet est compltement support par la version


actuelle, NO sinon

is_verified_by

character_data

Toujours NULL car le groupe de dveloppement de PostgreSQL ne ralise pas de tests formels pour la conformit
des fonctionnalits

comments

character_data

Un commentaire ventuel sur l'tat de support du paquet

34.45. sql_parts
La table sql_parts contient des informations sur les parties du standard SQL supportes par PostgreSQL.
Tableau 34.43. Colonnes de sql_parts

Nom

Type de donnes

Description

feature_id

character_data

Une chane d'identification contenant le


numro de la partie

feature_name

character_data

Nom descriptif de la partie


635

Schma d'information

Nom

Type de donnes

Description

is_supported

yes_or_no

YES si cette partie est compltement supporte par la version actuelle de PostgreSQL, NO dans le cas contraire

is_verified_by

character_data

Toujours NULL, car les dveloppeurs


PostgreSQL ne testent pas officiellement la conformit des fonctionnalits

comments

character_data

Commentaires sur le statut du support de


la partie

34.46. sql_sizing
La table sql_sizing contient des informations sur les diffrentes limites de tailles et valeurs maximales dans PostgreSQL.
Ces informations ont pour contexte principal l'interface ODBC ; les utilisateurs des autres interfaces leur trouveront probablement
peu d'utilit. Pour cette raison, les lments de taille individuels ne sont pas dcrits ici ; ils se trouvent dans la description de
l'interface ODBC.
Tableau 34.44. Colonnes de sql_sizing

Nom

Type de donnes

Description

sizing_id

cardinal_number

Identifiant de l'lment de taille

sizing_name

character_data

Nom descriptif de l'lment de taille

supported_value

cardinal_number

Valeur de l'lment de taille, ou 0 si la taille est illimite ou


ne peut pas tre dtermine, ou NULL si les fonctionnalits
pour lesquelles l'lment de taille est applicable ne sont pas
supportes

comments

character_data

Un commentaire ventuel de l'lment de taille

34.47. sql_sizing_profiles
La table sql_sizing_profiles contient des informations sur les valeurs sql_sizing requises par diffrents profils du
standard SQL. PostgreSQL ne garde pas trace des profils SQL, donc la table est vide.
Tableau 34.45. Colonnes de sql_sizing_profiles

Nom

Type de donnes

Description

sizing_id

cardinal_number

Identifiant de l'lment de taille

sizing_name

character_data

Nom descriptif de l'lment de taille

profile_id

character_data

Chane identifiant un profil

required_value

cardinal_number

La valeur requise par le profil SQL pour l'lment de taille,


ou 0 si le profil ne place aucune limite sur l'lment de
taille, ou NULL si le profil ne requiert aucune fonctionnalit pour laquelle l'lment de style est applicable

comments

character_data

Un commentaire ventuel sur l'lment de taille au sein du


profil

34.48. table_constraints
La vue table_constraints contient toutes les contraintes appartenant aux tables possdes par l'utilisateur courant ou pour
lesquelles l'utilisateur courant dispose de certains droits diffrents de SELECT.
Tableau 34.46. Colonnes de table_constraints

636

Schma d'information

Nom

Type de donnes

Description

constraint_catalog

sql_identifier

Nom de la base de donnes qui contient la contrainte


(toujours la base de donnes courante)

constraint_schema

sql_identifier

Nom du schma qui contient la contrainte

constraint_name

sql_identifier

Nom de la contrainte

table_catalog

sql_identifier

Nom de la base de donnes qui contient la table (toujours la


base de donnes courante)

table_schema

sql_identifier

Nom du schma qui contient la table

table_name

sql_identifier

Nom de la table

constraint_type

character_data

Type de contrainte : CHECK, FOREIGN KEY, PRIMARY


KEY ou UNIQUE

is_deferrable

yes_or_no

YES si la contrainte peut tre diffre, NO sinon

initially_deferred

yes_or_no

YES si la contrainte, qui peut tre diffre, est initialement


diffre, NO sinon

34.49. table_privileges
La vue table_privileges identifie tous les privilges accords, un rle actif ou par une rle actif, sur des tables ou vues. Il
y a une ligne par combinaison table, donneur, bnficiaire.
Tableau 34.47. Colonnes de table_privileges

Nom

Type de donnes

Description

grantor

sql_identifier

Nom du rle qui a accord le privilge

grantee

sql_identifier

Nom du rle bnficiaire

table_catalog

sql_identifier

Nom de la base de donnes qui contient la table (toujours la


base de donnes courante)

table_schema

sql_identifier

Nom du schma qui contient la table

table_name

sql_identifier

Nom de la table

privilege_type

character_data

Type de privilge : SELECT, INSERT, UPDATE, DELETE,


TRUNCATE, REFERENCES ou TRIGGER

is_grantable

yes_or_no

YES si le droit peut tre transmis, NO sinon

with_hierarchy

yes_or_no

S'applique une fonctionnalit non disponible dans PostgreSQL.

34.50. tables
La vue tables contient toutes les tables et vues dfinies dans la base de donnes courantes. Seules sont affiches les tables et
vues auxquelles l'utilisateur courant a accs (parce qu'il en est le propritaire ou qu'il possde certains privilges).
Tableau 34.48. Colonnes de tables

Nom

Type de donnes

Description

table_catalog

sql_identifier

Nom de la base de donnes qui contient la table (toujours la


base de donnes courante)

table_schema

sql_identifier

Nom du schma qui contient la table

table_name

sql_identifier

Nom de la table

table_type

character_data

Type de table : BASE TABLE pour une table de base persistante (le type de table normal), VIEW pour une vue, FOREIGN TABLE pour une table distante ou LOCAL TEMPORARY pour une table temporaire

self_referencing_column_name

sql_identifier

S'applique une fonctionnalit non disponible dans Post637

Schma d'information

Nom

Type de donnes

Description
greSQL.

reference_generation

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

user_defined_type_catalog

sql_identifier

Si la table est une table type, le nom de la base de donnes


qui contient le type de donnes sous-jacent (toujours la base
de donnes actuel), sinon NULL.

user_defined_type_schema

sql_identifier

Si la table est une table type, le nom du schma qui


contient le type de donnes sous-jacent, sinon NULL.

user_defined_type_name

sql_identifier

Si la table est une table type, le nom du type de donnes


sous-jacent, sinon NULL.

is_insertable_into

yes_or_no

YES s'il est possible d'insrer des donnes dans la table, NO


dans le cas contraire. (Il est toujours possible d'insrer des
donnes dans une table de base, pas forcment dans les
vues.)

is_typed

yes_or_no

YES si la table est une table type, NO dans le cas contraire

commit_action

character_data

Si la table est temporaire, alors PRESERVE, sinon NULL.


(Le standard SQL dfinit d'autres actions de validation pour
les tables temporaires, actions qui ne sont pas supportes
par PostgreSQL.)

34.51. triggered_update_columns
Pour les triggers de la base de donnes actuelle qui spcifient une liste de colonnes (comme UPDATE OF colonne1, colonne2), la vue triggered_update_columns identifie ces colonnes. Les triggers qui ne spcifient pas une liste de colonnes ne sont pas inclus dans cette vue. Seules sont affiches les colonnes que l'utilisateur actuel possde ou que l'utilisateur a des
droits autre que SELECT.
Tableau 34.49. Colonnes de triggered_update_columns

Nom

Type de donnes

Description

trigger_catalog

sql_identifier

Nom de la base de donnes qui contient le dclencheur


(toujours la base de donnes courante)

trigger_schema

sql_identifier

Nom du schma qui contient le dclencheur

trigger_name

sql_identifier

Nom du dclencheur

event_object_catalog

sql_identifier

Nom de la base de donnes qui contient la table sur laquelle


est dfini le dclencheur (toujours la base de donnes courante)

event_object_schema

sql_identifier

Nom du schma qui contient la table sur laquelle est dfini


le dclencheur

event_object_table

sql_identifier

Nom de la table sur laquelle est dfini le dclencheur

event_object_column

sql_identifier

Name of the column that the trigger is defined on

34.52. triggers
La vue triggers contient tous les triggers dfinis dans la base de donnes actuelles sur les tables et vues que l'utilisateur actuel
possde ou sur lesquels il a d'autres droits que le SELECT.
Tableau 34.50. Colonnes de triggers

Nom

Type de donnes

Description

trigger_catalog

sql_identifier

Nom de la base contenant le trigger


(toujours la base de donnes actuelle)

trigger_schema

sql_identifier

Nom du schma contenant le trigger


638

Schma d'information

Nom

Type de donnes

Description

trigger_name

sql_identifier

Nom du trigger

event_manipulation

character_data

vnement qui dclenche le trigger (INSERT, UPDATE ou DELETE)

event_object_catalog

sql_identifier

Nom de la base contenant la table o le


trigger est dfini (toujours la base de donnes actuelle)

event_object_schema

sql_identifier

Nom du schma qui contient la table o le


trigger est dfini

event_object_table

sql_identifier

Nom de la table o le trigger est dfini

action_order

cardinal_number

Pas encore implant

action_condition

character_data

La condition WHEN du trigger, NULL si


aucun (NULL aussi si la table n'appartient
pas un rle actuellement activ)

action_statement

character_data

Instruction excute par le dclencheur


(actuellement toujours EXECUTE PROCEDURE function(...))

action_orientation

character_data

Indique si le dclencheur est excut une


fois par ligne traite ou une fois par instruction (ROW ou STATEMENT)

action_timing

character_data

Moment o le trigger se dclenche (BEFORE, AFTER ou INSTEAD OF)

action_reference_old_table

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

action_reference_new_table

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL.

action_reference_old_row

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

action_reference_new_row

sql_identifier

S'applique une fonctionnalit non disponible dans PostgreSQL

created

time_stamp

S'applique une fonctionnalit non disponible dans PostgreSQL

Les dclencheurs dans PostgreSQL ont deux incompatibilits avec le standard SQL qui affectent leur reprsentation dans le
schma d'information.
Premirement, les noms des dclencheurs sont locaux chaque table sous PostgreSQL, et ne sont pas des objets du schma indpendants. De ce fait, il peut exister des dclencheurs de mme noms au sein d'un schma, pour peu qu'ils s'occupent de tables
diffrentes. (trigger_catalog et trigger_schema sont les champs qui dcrivent effectivement la table sur laquelle est
dfini le dclencheur.)
Deuximement, les dclencheurs peuvent tre dfinis pour s'excuter sur plusieurs vnements sous PostgreSQL (c'est--dire
ON INSERT OR UPDATE) alors que le standard SQL n'en autorise qu'un. Si un dclencheur est dfini pour s'excuter sur plusieurs vnements, il est reprsent sur plusieurs lignes dans le schma d'information, une pour chaque type d'vnement.
En consquence, la cl primaire de la vue triggers est en fait (trigger_catalog, trigger_schema,
event_object_table, trigger_name, event_manipulation) et non (trigger_catalog, trigger_schema, trigger_name) comme le spcifie le standard SQL. Nanmoins, si les dclencheurs sont dfinis de manire
conforme au standard SQL (des noms de dclencheurs uniques dans le schma et un seul type d'vnement par dclencheur), il n'y
a pas lieu de se proccuper de ces deux incompatibilits.

Note
Avant PostgreSQL 9.1, les colonnes action_timing, action_reference_old_table, action_reference_new_table, action_reference_old_row et action_reference_new_row de
cette vue taient nommes respectivement condition_timing, condition_reference_old_table,
condition_reference_new_table,
condition_reference_old_row
et
condi639

Schma d'information

tion_reference_new_row. Cela refltaient leur nommage dans le standard SQL:1999. Le nouveau nommage
est conforme SQL:2003 et les versions ultrieures.

34.53. usage_privileges
La vue usage_privileges identifie les privilges d'USAGE accords sur diffrents objets un rle actif ou par un rle actif.
Sous PostgreSQL, cela s'applique aux domaines. Puisqu'il n'y a pas de rels privilges sur les domaines sous PostgreSQL,
cette vue est affiche les privilges USAGE implicitement octroys PUBLIC pour tous les collationnements, domaines, wrappers
de donnes distantes et serveurs distants. Il y a une ligne pour chaque combinaison d'objet, de donneur et de receveur.
Comme les collations et les domaines n'ont pas de vrais droits dans PostgreSQL, cette vue affiche des droits USAGE implicites,
non donnables d'autres, et donns par le propritaire PUBLIC pour tous les collationnements et tous les domaines. Les autres
types d'objets affichent nanmoins de vrais droits.
Tableau 34.51. Colonnes de usage_privileges

Nom

Type de donnes

Description

grantor

sql_identifier

Nom du rle qui a donn ce droit

grantee

sql_identifier

Name of the role that the privilege was granted to

object_catalog

sql_identifier

Nom de la base de donnes qui contient l'objet (toujours la


base de donnes courante)

object_schema

sql_identifier

Nom du schma qui contient l'objet, if applicable, sinon une


chane vide

object_name

sql_identifier

Nom de l'objet

object_type

character_data

COLLATION, DOMAIN, FOREIGN DATA WRAPPER ou


FOREIGN SERVER

privilege_type

character_data

Toujours USAGE

is_grantable

yes_or_no

YES si le droit peut tre donn, NO dans le cas contraire

34.54. user_mapping_options
La vue user_mapping_options contient toutes les options dfinies pour les correspondances d'utilisateur dfinies dans la
base de donnes en cours. Seules sont affiches les correspondances pour lesquelles le serveur distant correspondant peut tre accd par l'utilisateur connect (qu'il en soit le propritaire ou qu'il ait quelques droits dessus).
Tableau 34.52. Colonnes de user_mapping_options

Nom

Type de donnes

Description

authorization_identifier

sql_identifier

Nom de l'utilisateur, ou PUBLIC si la correspondance est publique

foreign_server_catalog

sql_identifier

Nom de la base de donnes dans laquelle


est dfini le serveur distant correspondant
(toujours la base de donnes en cours)

foreign_server_name

sql_identifier

Nom du serveur distant utilis par cette


correspondance

option_name

sql_identifier

Nom d'une option

option_value

character_data

Valeur de l'option. Cette colonne


s'affichera comme NULL sauf si
l'utilisateur connect est l'utilisateur en
cours de correspondance ou si la correspondance est pour PUBLIC et que
l'utilisateur connect est le propritaire de
la base de donnes ou un superutilisateur.
Le but est de protger les informations de
mot de passe stockes comme option.
640

Schma d'information

34.55. user_mappings
La vue user_mappings contient toutes les correspondances utilisateurs dfinies dans la base de donnes en cours. Seules sont
affiches les correspondances pour lesquelles le serveur distant correspondant peut tre accd par l'utilisateur connect (qu'il en
soit le propritaire ou qu'il ait quelques droits dessus).
Tableau 34.53. Colonnes de user_mappings

Nom

Type de donnes

Description

authorization_identifier

sql_identifier

Nom de l'utilisateur en cours de correspondance ou PUBLIC si la correspondance est publique

foreign_server_catalog

sql_identifier

Nom de la base de donnes dans laquelle


est dfini le serveur distant correspondant
(toujours la base de donnes en cours)

foreign_server_name

sql_identifier

Nom du serveur distant utilis par cette


correspondance

34.56. view_column_usage
La vue view_column_usage identifie toutes les colonnes utilises dans l'expression de la requte d'une vue (l'instruction SELECT dfinissant la vue). Une colonne n'est incluse que si la table contenant la colonne appartient un rle actif.

Note
Les colonnes des tables systme ne sont pas incluses. Cela sera probablement corrig un jour.
Tableau 34.54. Colonnes de view_column_usage

Nom

Type de donnes

Description

view_catalog

sql_identifier

Nom de la base de donnes qui contient la vue (toujours la


base de donnes courante)

view_schema

sql_identifier

Nom du schma qui contient la vue

view_name

sql_identifier

Nom de la vue

table_catalog

sql_identifier

Nom de la base de donnes qui contient la table qui contient


la colonne utilise par la vue (toujours la base de donnes
courante)

table_schema

sql_identifier

Nom du schma qui contient la table qui contient la colonne


utilise par la vue

table_name

sql_identifier

Nom de la table qui contient la colonne utilise par la vue

column_name

sql_identifier

Nom de la colonne utilise par la vue

34.57. view_routine_usage
La vue view_routine_usage identifie toutes les routines (fonctions et procdures) utilises dans la requte d'une vue
(l'instruction SELECT qui dfinit la vue). Une routine n'est incluse que si la routine appartient un rle actif.
Tableau 34.55. Colonnes de view_routine_usage

Nom

Type de donnes

Description

table_catalog

sql_identifier

Nom de la base qui contient la vue


(toujours la base en cours)

table_schema

sql_identifier

Nom du schma qui contient la vue

table_name

sql_identifier

Nom de la vue

641

Schma d'information

Nom

Type de donnes

Description

specific_catalog

sql_identifier

Nom de la base qui contient la fonction


(toujours la base en cours)

specific_schema

sql_identifier

Nom du schma qui contient la fonction

specific_name

sql_identifier

Le nom spcifique de la fonction. Voir


Section 34.38, routines pour plus
d'informations.

34.58. view_table_usage
La vue view_table_usage identifie toutes les tables utilises dans l'expression de la requte d'une vue (l'instruction SELECT
dfinissant la vue). Une table n'est incluse que son propritaire est un rle actif.

Note
Les tables systme ne sont pas incluses. Cela sera probablement corrig un jour.
Tableau 34.56. Colonnes de view_table_usage

Nom

Type de donnes

Description

view_catalog

sql_identifier

Nom de la base de donnes qui contient la vue (toujours la


base de donnes courante)

view_schema

sql_identifier

Nom du schma qui contient la vue

view_name

sql_identifier

Nom de la vue

table_catalog

sql_identifier

Nom de la base de donnes qui contient la table utilise par


la vue (toujours la base de donnes courante)

table_schema

sql_identifier

Nom du schma qui contient la table utilise par la vue

table_name

sql_identifier

Nom de la table utilise par la vue

34.59. views
La vue views contient toutes les vues dfinies dans la base de donnes courantes. Seules sont affiches les vues auxquelles
l'utilisateur a accs (parce qu'il en est le propritaire ou qu'il dispose de privilges).
Tableau 34.57. Colonnes de views

Nom

Type de donnes

Description

table_catalog

sql_identifier

Nom de la base de donnes qui contient la vue (toujours la


base de donnes courante)

table_schema

sql_identifier

Nom du schma qui contient la vue

table_name

sql_identifier

Nom de la vue

view definition

character_data

Expression de la requte dfinissant la vue (NULL si la vue


n'appartient pas un rle actif)

check_option

character_data

S'applique une fonctionnalit non disponible dans PostgreSQL.

is_updatable

yes_or_no

YES si la vue est actualisable (autorise UPDATE et DELETE), NO dans le cas contraire

is_insertable_into

yes_or_no

YES s'il est possible d'insrer des donnes dans la vue


(autorise INSERT), NO dans le cas contraire

is_trigger_updatable

yes_or_no

YES si la vue dispose d'un trigger INSTEAD OF pour


l'opration UPDATE, NO dans le cas contraire

is_trigger_deletable

yes_or_no

YES si la vue dispose d'un trigger INSTEAD OF pour


642

Schma d'information

Nom

Type de donnes

Description
l'opration DELETE, NO dans le cas

is_trigger_insertable_into

yes_or_no

YES si la vue dispose d'un trigger INSTEAD OF pour


l'opration INSERT, NO dans le cas

643

Partie V. Programmation serveur


Cette partie traite des possibilits d'extension des fonctionnalits du serveur par l'ajout de fonctions utilisateur, de types de donnes, de dclencheurs (triggers), etc. Il est prfrable de n'aborder ces sujets, avancs, qu'aprs avoir compris tous les autres.
Les derniers chapitres dcrivent les langages de programmation serveur disponibles avec PostgreSQL ainsi que les problmes
de ces langages en gnral. Il est essentiel de lire au minimum les premires sections du Chapitre 35, tendre SQL (qui traitent des
fonctions) avant de se plonger dans les langages de programmation serveur.

Chapitre 35. tendre SQL


Les sections qui suivent prsentent les possibilits d'tendre le langage SQL de requtage de PostgreSQL par l'ajout :

de fonctions (Section 35.3, Fonctions utilisateur ) ;


d'agrgats (Section 35.10, Agrgats utilisateur ) ;
de types de donnes (Section 35.11, Types utilisateur ) ;
d'oprateurs (Section 35.12, Oprateurs dfinis par l'utilisateur ) ;
de classes d'oprateurs pour les index (Section 35.14, Interfacer des extensions d'index ).
d'extensions permettant de crer un paquetage d'objets qui disposent d'un point commun (voir Section 35.15, Empaqueter
des objets dans une extension )

35.1. L'extensibilit
PostgreSQL est extensible parce qu'il opre grce un systme de catalogues. Quiconque est familier des systmes de bases
de donnes relationnelles standard sait que les informations concernant les bases, les tables, les colonnes, etc. y sont stockes
dans ce qu'on nomme communment des catalogues systmes (certains systmes appellent cela le dictionnaire de donnes). Pour
l'utilisateur, les catalogues ressemblent des tables ordinaires, mais le SGBD y enregistre ses registres internes. la diffrence
des autres systmes, PostgreSQL enregistre beaucoup d'informations dans ses catalogues : non seulement l'information
concernant les tables et les colonnes, mais aussi l'information concernant les types de donnes, les fonctions, les mthodes
d'accs, etc.
Ces tables peuvent tre modifies par l'utilisateur. Qui plus est, puisque PostgreSQL fonde ses oprations sur ces tables, il
peut tre tendu par les utilisateurs. En comparaison, les systmes de bases de donnes conventionnels ne peuvent tre tendus
qu'en modifiant les procdures dans le code source ou en installant des modules spcifiquement crits par le vendeur de SGBD.
De plus, le serveur PostgreSQL peut incorporer du code utilisateur par chargement dynamique. C'est--dire que l'utilisateur
peut indiquer un fichier de code objet (par exemple une bibliothque partage) qui code un nouveau type ou une nouvelle fonction et PostgreSQL le charge au besoin. Il est encore plus facile d'ajouter au serveur du code crit en SQL. La possibilit de
modifier son fonctionnement la vole fait de PostgreSQL un outil unique pour le prototypage rapide de nouvelles applications et de structures de stockage.

35.2. Le systme des types de PostgreSQL


Les types de donnes de PostgreSQL sont rpartis en types de base, types composites, domaines et pseudo-types.

35.2.1. Les types de base


Les types de base sont ceux qui, comme int4, sont implants sous le niveau du langage SQL (typiquement dans un langage de
bas niveau comme le C). Ils correspondent gnralement ce que l'on appelle les types de donnes abstraits. PostgreSQL ne
peut oprer sur de tels types qu'au moyen de fonctions utilisateur et n'en comprend le fonctionnement que dans la limite de la
description qu'en a fait l'utilisateur. Les types de base sont diviss en types scalaires et types tableaux. Pour chaque type scalaire,
un type tableau est automatiquement cr destin contenir des tableaux de taille variable de ce type scalaire.

35.2.2. Les types composites


Les types composites, ou types lignes, sont crs chaque fois qu'un utilisateur cre une table. Il est galment possible de dfinir
un type composite autonome sans table associe. Un type composite n'est qu'une simple liste de types de base avec des noms de
champs associs. Une valeur de type composite est une ligne ou un enregistrement de valeurs de champ. L'utilisateur peut accder ces champs partir de requtes SQL. La Section 8.15, Types composites fournit de plus amples informations sur ces
types.

35.2.3. Les domaines


Un domaine est fond sur un type de base particulier. Il est, dans de nombreux cas, interchangeable avec ce type. Mais un domaine peut galement possder des contraintes qui restreignent ses valeurs un sous-ensemble des valeurs autorises pour le
type de base.
Les domaines peuvent tre crs l'aide de la commande SQL CREATE DOMAIN(7). Leurs cration et utilisation n'est pas
l'objet de ce chapitre.

35.2.4. Pseudo-types
645

tendre SQL

Il existe quelques pseudo-types pour des besoins particuliers. Les pseudo-types ne peuvent pas apparatre comme champs de
table ou comme attributs de types composites, mais ils peuvent tre utiliss pour dclarer les types des arguments et des rsultats
de fonctions. Dans le systme de typage, ils fournissent un mcanisme d'identification des classes spciales de fonctions. La Tableau 8.24, Pseudo-Types donne la liste des pseudo-types qui existent.

35.2.5. Types et fonctions polymorphes


Quatre pseudo-types sont particulirement intressants : anyelement, anyarray, anynonarray et anyenum, collectivement appels
types polymorphes. Toute fonction dclare utiliser ces types est dite fonction polymorphe. Une fonction polymorphe peut oprer
sur de nombreux types de donnes diffrents, les types de donnes spcifiques tant dtermins par les types des donnes rellement passs lors d'un appel particulier de la fonction.
Les arguments et rsultats polymorphes sont lis entre eux et sont rsolus dans un type de donnes spcifique quand une requte
faisant appel une fonction polymorphe est analyse. Chaque occurrence (argument ou valeur de retour) dclare comme anyelement peut prendre n'importe quel type rel de donnes mais, lors d'un appel de fonction donn, elles doivent toutes avoir le mme
type rel. Chaque occurrence dclare comme anyarray peut prendre n'importe quel type de donnes tableau mais, de la mme
faon, elles doivent toutes tre du mme type. Si des occurrences sont dclares comme anyarray et d'autres comme anyelement, le
type rel de tableau des occurrences anyarray doit tre un tableau dont les lments sont du mme type que ceux apparaissant dans
les occurrences de type anyelement. anynonarray est trait de la mme faon que anyelement mais ajoute une contrainte supplmentaire. Le type rel ne doit pas tre un tableau. anyenum est trait de la mme faon que anyelement mais ajoute une contrainte
supplmentaire. Le type doit tre un type enumr.
Ainsi, quand plusieurs occurrences d'argument sont dclares avec un type polymorphe, seules certaines combinaisons de types
rels d'argument sont autorises. Par exemple, une fonction dclare comme foo(anyelement, anyelement) peut prendre
comme arguments n'importe quelles valeurs condition qu'elles soient du mme type de donnes.
Quand la valeur renvoye par une fonction est dclare de type polymorphe, il doit exister au moins une occurrence d'argument
galement polymorphe, et le type rel de donne pass comme argument dtermine le type rel de rsultat renvoy lors de cet appel la fonction. Par exemple, s'il n'existe pas dj un mcanisme d'indexation d'lments de tableau, on peut dfinir une fonction
qui code ce mcanisme : indice(anyarray, integer) returns anyelement. La dclaration de fonction contraint le
premier argument rel tre de type tableau et permet l'analyseur d'infrer le type correct de rsultat partir du type rel du premier argument. Une fonction dclare de cette faon f(anyarray) returns anyenum n'accepte que des tableaux contenant des valeurs de type enum.
anynonarray et anyenum ne reprsentent pas des variables de type spar ; elles sont du mme type que anyelement, mais avec une
contrainte supplmentaire. Par exemple, dclarer une fonction f(anyelement, anyenum) est quivalent la dclarer
f(anyenum, anyenum) : les deux arguments rels doivent tre du mme type enum.
Une fonction variadic (c'est--dire une fonction acceptant un nombre variable d'arguments, comme dans Section 35.4.5,
Fonctions SQL avec un nombre variables d'arguments ) peut tre polymorphique : cela se fait en dclarant son dernier paramtre VARIADIC anyarray. Pour s'assurer de la correspondance des arguments et dterminer le type de la valeur en retour, ce
type de fonction se comporte de la mme faon que si vous aviez crit le nombre appropri de paramtres anynonarray.

35.3. Fonctions utilisateur


PostgreSQL propose quatre types de fonctions :

fonctions en langage de requte (fonctions crites en SQL, Section 35.4, Fonctions en langage de requtes (SQL) )

fonctions en langage procdural (fonctions crites, par exemple, en PL/pgSQL ou PL/Tcl, Section 35.7, Fonctions en langage de procdures )

fonctions internes (Section 35.8, Fonctions internes )

fonctions en langage C (Section 35.9, Fonctions en langage C )

Chaque type de fonction peut accepter comme arguments (paramtres) des types de base, des types composites ou une combinaison de ceux-ci. De plus, chaque sorte de fonction peut renvoyer un type de base ou un type composite. Les fonctions pourraient
aussi tre dfinies pour renvoyer des ensembles de valeurs de base ou de valeurs composites.
De nombreuses sortes de fonctions peuvent accepter ou renvoyer certains pseudo-types (comme les types polymorphes) mais avec
des fonctionnalits varies. Consultez la description de chaque type de fonction pour plus de dtails.
Il est plus facile de dfinir des fonctions SQL aussi allons-nous commencer par celles-ci. La plupart des concepts prsents pour
les fonctions SQL seront aussi grs par les autres types de fonctions.
Lors de la lecture de ce chapitre, il peut tre utile de consulter la page de rfrence de la commande CREATE FUNCTION(7)
646

tendre SQL

pour mieux comprendre les exemples. Quelques exemples extraits de ce chapitre peuvent tre trouvs dans les fichiers
funcs.sql et funcs.c du rpertoire du tutoriel de la distribution source de PostgreSQL.

35.4. Fonctions en langage de requtes (SQL)


Les fonctions SQL excutent une liste arbitraire d'instructions SQL et renvoient le rsultat de la dernire requte de cette liste.
Dans le cas d'un rsultat simple (pas d'ensemble), la premire ligne du rsultat de la dernire requte sera renvoye (gardez
l'esprit que la premire ligne d'un rsultat multiligne n'est pas bien dfinie moins d'utiliser ORDER BY). Si la dernire requte de la liste ne renvoie aucune ligne, la valeur NULL est renvoye.
Une fonction SQL peut tre dclare de faon renvoyer un ensemble (set) en spcifiant le type renvoy par la fonction comme
SETOF un_type, ou de faon quivalente en la dclarant comme RETURNS TABLE(colonnes). Dans ce cas, toutes les
lignes de la dernire requte sont renvoyes. Des dtails supplmentaires sont donns plus loin dans ce chapitre.
Le corps d'une fonction SQL doit tre constitu d'une liste d'une ou de plusieurs instructions SQL spares par des points-virgule.
Un point-virgule aprs la dernire instruction est optionnel. Sauf si la fonction dclare renvoyer void, la dernire instruction doit
tre un SELECT ou un INSERT, UPDATE ou un DELETE qui a une clause RETURNING.
Toute collection de commandes dans le langage SQL peut tre assemble et dfinie comme une fonction. En plus des requtes SELECT, les commandes peuvent inclure des requtes de modification des donnes (INSERT, UPDATE et DELETE) ainsi que
d'autres commandes SQL (sans toutefois pouvoir utiliser les commandes de contrle de transaction, telles que COMMIT, SAVEPOINT, et certaines commandes utilitaires, comme VACUUM, dans les fonctions SQL). Nanmoins, la commande finale doit tre
un SELECT ou doit avoir une clause RETURNING qui renvoie ce qui a t spcifi comme type de retour de la fonction. Autrement, si vous voulez dfinir une fonction SQL qui ralise des actions mais n'a pas de valeur utile renvoyer, vous pouvez la dfinir comme renvoyant void. Par exemple, cette fonction supprime les lignes avec des salaires ngatifs depuis la table emp :
CREATE FUNCTION nettoie_emp() RETURNS void AS '
DELETE FROM emp WHERE salaire < 0;
' LANGUAGE SQL;
SELECT nettoie_emp();
nettoie_emp
----------(1 row)
La syntaxe de la commande CREATE FUNCTION requiert que le corps de la fonction soit crit comme une constante de type
chane. Il est habituellement plus agrable d'utiliser les guillemets dollar (voir la Section 4.1.2.4, Constantes de chanes avec
guillemet dollar ) pour cette constante. Si vous choisissez d'utiliser la syntaxe habituelle avec des guillemets simples, vous devez
doubler les marques de guillemet simple (') et les antislashs (\), en supposant que vous utilisez la syntaxe d'chappement de
chanes, utiliss dans le corps de la fonction (voir la Section 4.1.2.1, Constantes de chanes ).
Les arguments de la fonction SQL sont rfrencs dans le corps de la fonction en utilisant la syntaxe suivante. $n:$1 se rfre au
premier argument, $2 au second et ainsi de suite. Si un argument est de type composite, on utilisera la notation par point, par
exemple $1.name, pour accder aux attributs de l'argument. Les arguments peuvent seulement tre utiliss comme valeurs des
donnes, pas comme des identifieurs. Du coup, par exemple, ceci est correct :
INSERT INTO matable VALUES ($1);
mais ceci ne fonctionnera pas :
INSERT INTO $1 VALUES (42);

35.4.1. Fonctions SQL sur les types de base


La fonction SQL la plus simple possible n'a pas d'argument et retourne un type de base tel que integer :
CREATE FUNCTION un() RETURNS integer AS $$
SELECT 1 AS resultat;
$$ LANGUAGE SQL;
-- Autre syntaxe pour les chanes littrales :
CREATE FUNCTION un() RETURNS integer AS '
SELECT 1 AS resultat;
' LANGUAGE SQL;
SELECT un();
647

tendre SQL

un
---1
Notez que nous avons dfini un alias de colonne avec le nom resultat dans le corps de la fonction pour se rfrer au rsultat de
la fonction mais cet alias n'est pas visible hors de la fonction. En effet, le rsultat est nomm un au lieu de resultat.
Il est presque aussi facile de dfinir des fonctions SQL acceptant des types de base comme arguments. Dans l'exemple suivant, remarquez comment nous faisons rfrence aux arguments dans le corps de la fonction avec $1 et $2.
CREATE FUNCTION ajoute(integer, integer) RETURNS integer AS $$
SELECT $1 + $2;
$$ LANGUAGE SQL;
SELECT ajoute(1, 2) AS reponse;
reponse
--------3
Voici une fonction plus utile, qui pourrait tre utilise pour dbiter un compte bancaire :
CREATE FUNCTION tf1 (integer, numeric) RETURNS integer AS $$
UPDATE banque
SET balance = balance - $2
WHERE no_compte = $1;
SELECT 1;
$$ LANGUAGE SQL;
Un utilisateur pourrait excuter cette fonction pour dbiter le compte 17 de 100 000 euros ainsi :
SELECT tf1(17, 100.000);
Dans la pratique, on prfrera vraisemblablement un rsultat plus utile que la constante 1. Une dfinition plus probable est :
CREATE FUNCTION tf1 (integer, numeric) RETURNS numeric AS $$
UPDATE banque
SET balance = balance - $2
WHERE no_compte = $1;
SELECT balance FROM banque WHERE no_compte = $1;
$$ LANGUAGE SQL;
qui ajuste le solde et renvoie sa nouvelle valeur. La mme chose peut se faire en une commande en utilisant la clause RETURNING :
CREATE FUNCTION tf1 (integer, numeric) RETURNS numeric AS $$
UPDATE banque
SET balance = balance - $2
WHERE no_compte = $1
RETURNING balance;
$$ LANGUAGE SQL;

35.4.2. Fonctions SQL sur les types composites


Quand nous crivons une fonction avec des arguments de type composite, nous devons non seulement spcifier l'argument utilis
(comme nous l'avons fait prcdemment avec $1 et $2), mais aussi spcifier l'attribut dsir de cet argument (champ). Par
exemple, supposons que emp soit le nom d'une table contenant des donnes sur les employs et donc galement le nom du type
composite correspondant chaque ligne de la table. Voici une fonction double_salaire qui calcule ce que serait le salaire de
quelqu'un s'il tait doubl :
CREATE TABLE emp (
nom
text,
salaire
numeric,
age
integer,
cubicle
point
);
INSERT INTO emp VALUES ('Bill', 4200, 45, '(2,1)');

648

tendre SQL

CREATE FUNCTION double_salaire(emp) RETURNS numeric AS $$


SELECT $1.salaire * 2 AS salaire;
$$ LANGUAGE SQL;
SELECT nom, double_salaire(emp.*) AS reve
FROM emp
WHERE emp.cubicle ~= point '(2,1)';
name | reve
------+------Bill | 8400
Notez l'utilisation de la syntaxe $1.salaire pour slectionner un champ dans la valeur de la ligne argument. Notez galement
comment la commande SELECT utilise * pour slectionner la ligne courante entire de la table comme une valeur composite
(emp). La ligne de la table peut aussi tre rfrence en utilisant seulement le nom de la table ainsi :
SELECT nom, double_salaire(emp) AS reve
FROM emp
WHERE emp.cubicle ~= point '(2,1)';
mais cette utilisation est obsolte car elle est facilement obscure.
Quelque fois, il est pratique de construire une valeur d'argument composite en direct. Ceci peut se faire avec la construction ROW.
Par exemple, nous pouvons ajuster les donnes passes la fonction :
SELECT nom, double_salaire(ROW(nom, salaire*1.1, age, cubicle)) AS reve
FROM emp;
Il est aussi possible de construire une fonction qui renvoie un type composite. Voici un exemple de fonction renvoyant une seule
ligne de type emp :
CREATE FUNCTION nouvel_emp() RETURNS emp AS $$
SELECT text 'Aucun' AS nom,
1000.0 AS salaire,
25 AS age,
point '(2,2)' AS cubicle;
$$ LANGUAGE SQL;
Dans cet exemple, nous avons spcifi chacun des attributs avec une valeur constante, mais un quelconque calcul aurait pu tre
substitu ces valeurs.
Notez deux aspects importants propos de la dfinition de fonction :

L'ordre de la liste du SELECT doit tre exactement le mme que celui dans lequel les colonnes apparaissent dans la table associe au type composite (donner des noms aux colonnes dans le corps de la fonction, comme nous l'avons fait dans l'exemple,
n'a aucune interaction avec le systme).

Vous devez transtyper les expressions pour concorder avec la dfinition du type composite ou bien vous aurez l'erreur suivante :
ERROR:

function declared to return emp returns varchar instead of text at column 1

Une autre faon de dfinir la mme fonction est :


CREATE FUNCTION nouveau_emp() RETURNS emp AS $$
SELECT ROW('Aucun', 1000.0, 25, '(2,2)')::emp;
$$ LANGUAGE SQL;
Ici, nous crivons un SELECT qui renvoie seulement une colonne du bon type composite. Ceci n'est pas vraiment meilleur dans
cette situation mais c'est une alternative pratique dans certains cas -- par exemple, si nous avons besoin de calculer le rsultat en
appelant une autre fonction qui renvoie la valeur composite dsire.
Nous pourrions appeler cette fonction directement de deux faons :
SELECT nouveau_emp();
nouveau_emp
-------------------------(None,1000.0,25,"(2,2)")
SELECT * FROM nouveau_emp();
649

tendre SQL

nom | salaire | age | cubicle


-------+---------+-----+--------Aucun | 1000.0 | 25 | (2,2)
La deuxime faon est dcrite plus compltement dans la Section 35.4.7, Fonctions SQL comme sources de table .
Quand vous utilisez une fonction qui renvoie un type composite, vous pourriez vouloir seulement un champ (attribut) depuis ce rsultat. Vous pouvez le faire avec cette syntaxe :
SELECT (nouveau_emp()).nom;
nom
-----None
Les parenthses supplmentaires sont ncessaires pour viter une erreur de l'analyseur. Si vous essayez de le faire sans, vous obtiendrez quelque chose comme ceci :
SELECT nouveau_emp().nom;
ERROR: syntax error at or near "."
LINE 1: SELECT nouveau_emp().nom;
^
Une autre option est d'utiliser la notation fonctionnelle pour extraire un attribut. Une manire simple d'expliquer cela est de dire
que nous pouvons changer les notations attribut(table) et table.attribut.
SELECT nom(nouveau_emp());
name
-----None
-- C'est la mme chose que
-- SELECT emp.nom AS leplusjeune FROM emp WHERE emp.age < 30;
SELECT nom(emp) AS leplusjeune FROM emp WHERE age(emp) < 30;
leplusjeune
------------Sam
Andy

Astuce
L'quivalence entre la notation fonctionnelle et la notation d'attribut rend possible l'utilisation de fonctions sur des
types composites pour muler les champs calculs . Par exemple, en utilisant la dfinition prcdente pour
double_salaire(emp), nous pouvons crire
SELECT emp.nom, emp.double_salaire FROM emp;
Une application utilisant ceci n'aurait pas besoin d'tre consciente directement que double_salaire n'est pas
une vraie colonne de la table (vous pouvez aussi muler les champs calculs avec des vues).
En raison de ce comportement, il est dconseill de nommer une fonction prenant un unique argument de type composite avec l'identifiant de l'un des champs de ce type composite.
Une autre faon d'utiliser une fonction renvoyant un type composite est de l'appeler comme une fonction de table, comme dcrit
dans la Section 35.4.7, Fonctions SQL comme sources de table .

35.4.3. Fonctions SQL avec des paramtres nomms


Il est possible d'attacher des noms aux paramtres d'une fonction, par exemple :
CREATE FUNCTION tf1 (acct_no integer, debit numeric) RETURNS numeric AS $$
UPDATE bank
SET balance = balance - $2
650

tendre SQL

WHERE no_compte = $1
RETURNING balance;
$$ LANGUAGE SQL;
Dans cet exemple, le premier paramtre a comme nom acct_no, et le second paramtre debit. En ce qui concerne la fonction
SQL, ces noms sont de la dcoration. Vous devez toujours faire rfrence aux paramtres avec la notation $1, $2, etc dans le
corps de la fonction. (Certains langages de procdure vous autorisent utiliser les noms des paramtres la place.) Nanmoins, les
noms des paramtres peuvent tre utiles dans un but de documentation. Quand une fonction a beaucoup de paramtres, il est aussi
utile d'utiliser les noms lors de l'appel la fonction, comme dcrit dans Section 4.3, Fonctions appelantes .

35.4.4. Fonctions SQL avec des paramtres en sortie


Une autre faon de dcrire les rsultats d'une fonction est de la dfinir avec des paramtres en sortie comme dans cet exemple :
CREATE FUNCTION ajoute (IN x int, IN y int, OUT sum int)
AS 'SELECT $1 + $2'
LANGUAGE SQL;
SELECT ajoute(3,7);
ajoute
-------10
(1 row)
Ceci n'est pas vraiment diffrent de la version d'ajoute montre dans la Section 35.4.1, Fonctions SQL sur les types de base .
La vraie valeur des paramtres en sortie est qu'ils fournissent une faon agrable de dfinir des fonctions qui renvoient plusieurs
colonnes. Par exemple,
CREATE FUNCTION ajoute_n_produit (x int, y int, OUT sum int, OUT product int)
AS 'SELECT $1 + $2, $1 * $2'
LANGUAGE SQL;
SELECT * FROM sum_n_product(11,42);
sum | product
-----+--------53 |
462
(1 row)
Ce qui est arriv ici est que nous avons cr un type composite anonyme pour le rsultat de la fonction. L'exemple ci-dessus a le
mme rsultat final que
CREATE TYPE produit_ajoute AS (somme int, produit int);
CREATE FUNCTION ajoute_n_produit (int, int) RETURNS produit_ajoute
AS 'SELECT $1 + $2, $1 * $2'
LANGUAGE SQL;
mais ne pas avoir s'embter avec la dfinition spare du type composite est souvent agrable. Notez que les noms attachs aux
paramtres de sortie ne sont pas juste dcoratif, mais dterminent le nom des colonnes du type composite anonyme. (Si vous omettez un nom pour un paramtre en sortie, le systme choisira un nom lui-mme.)
Notez que les paramtres en sortie ne sont pas inclus dans la liste d'arguments lors de l'appel d'une fonction de ce type en SQL.
Ceci parce que PostgreSQL considre seulement les paramtres en entre pour dfinir la signature d'appel de la fonction. Cela
signifie aussi que seuls les paramtres en entre sont importants lors de rfrences de la fonction pour des buts comme sa suppression. Nous pouvons supprimer la fonction ci-dessus avec l'un des deux appels ci-dessous :
DROP FUNCTION ajoute_n_produit (x int, y int, OUT somme int, OUT produit int);
DROP FUNCTION ajoute_n_produit (int, int);
Les paramtres peuvent tre marqus comme IN (par dfaut), OUT ou INOUT ou VARIADIC. Un paramtre INOUT sert la fois
de paramtre en entre (il fait partie de la liste d'arguments en appel) et comme paramtre de sortie (il fait partie du type
d'enregistrement rsultat). Les paramtres VARIADIC sont des paramtres en entres, mais sont traits spcifiquement comme indiqu ci-dessous.

35.4.5. Fonctions SQL avec un nombre variables d'arguments


Les fonctions SQL peuvent accepter un nombre variable d'arguments condition que tous les arguments optionnels sont du
mme type. Les arguments optionnels seront passs la fonction sous forme d'un tableau. La fonction est dclare en marquant le
dernier paramtre comme VARIADIC ; ce paramtre doit tre dclar de type tableau. Par exemple :
651

tendre SQL

CREATE FUNCTION mleast(VARIADIC arr numeric[]) RETURNS numeric AS $$


SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i);
$$ LANGUAGE SQL;
SELECT mleast(10, -1, 5, 4.4);
mleast
--------1
(1 row)
En fait, tous les arguments la position ou aprs la position de l'argument VARIADIC sont emballs dans un tableau une dimension, comme si vous aviez crit
SELECT mleast(ARRAY[10, -1, 5, 4.4]);

-- doesn't work

Vous ne pouvez pas vraiment crire cela, ou tout du moins cela ne correspondra pas la dfinition de la fonction. Un paramtre
marqu VARIADIC correspond une ou plusieurs occurrences de son type d'lment, et non pas de son propre type.
Quelque fois, il est utile de pouvoir passer un tableau dj construit une fonction variadic ; ceci ets particulirement intressant
quand une fonction variadic veut passer son paramtre tableau une autre fonction. Vous pouvez faire cela en spcifiant VARIADIC dans l'appel :
SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]);
Ceci empche l'expansion du paramtre variadic de la fonction dans le type des lments, ce qui permet la valeur tableau de correspondre. VARIADIC peut seulement tre attach au dernier argument d'un appel de fonction.
Les paramtres de l'lment tableau gnrs partir d'un paramtre variadic sont traits comme n'ayant pas de noms propres. Cela
signifie qu'il n'est pas possible d'appeler une fonction variadic en utilisant des arguments nomms (Section 4.3, Fonctions appelantes ), sauf quand vous spcifiez VARIADIC. Par exemple, ceci fonctionnera :
SELECT mleast(VARIADIC arr := ARRAY[10, -1, 5, 4.4]);
mais pas cela :
SELECT mleast(arr := 10);
SELECT mleast(arr := ARRAY[10, -1, 5, 4.4]);

35.4.6. Fonctions SQL SQL avec des valeurs par dfaut pour les arguments
Les fonctions peuvent tre dclares avec des valeurs par dfaut pour certains des paramtres en entre ou pour tous. Les valeurs
par dfaut sont insres quand la fonction est appele avec moins d'arguments que priori ncessaires. Comme les arguments
peuvent seulement tre omis partir de la fin de la liste des arguments, tous les paramtres aprs un paramtres disposant d'une
valeur par dfaut disposeront eux-aussi d'une valeur par dfaut. (Bien que l'utilisation de la notation avec des arguments nomms
pourrait autoriser une relche de cette restriction, elle est toujours force pour que la notation des arguments de position fonctionne correctement.)
Par exemple :
CREATE FUNCTION foo(a int, b int DEFAULT 2, c int DEFAULT 3)
RETURNS int
LANGUAGE SQL
AS $$
SELECT $1 + $2 + $3;
$$;
SELECT foo(10, 20, 30);
foo
----60
(1 row)
SELECT foo(10, 20);
foo
----652

tendre SQL

33
(1 row)
SELECT foo(10);
foo
----15
(1 row)
SELECT foo(); -- chec car il n'y a pas de valeur par dfaut pour le premier argument
ERROR: function foo() does not exist
Le signe = peut aussi tre utilis la place du mot cl DEFAULT,

35.4.7. Fonctions SQL comme sources de table


Toutes les fonctions SQL peuvent tre utilises dans la clause FROM d'une requte mais ceci est particulirement utile pour les
fonctions renvoyant des types composite. Si la fonction est dfinie pour renvoyer un type de base, la fonction table produit une
table d'une seule colonne. Si la fonction est dfinie pour renvoyer un type composite, la fonction table produit une colonne pour
chaque attribut du type composite.
Voici un exemple :
CREATE
INSERT
INSERT
INSERT

TABLE foo (fooid int, foosousid int, foonom text);


INTO foo VALUES (1, 1, 'Joe');
INTO foo VALUES (1, 2, 'Ed');
INTO foo VALUES (2, 1, 'Mary');

CREATE FUNCTION recupfoo(int) RETURNS foo AS $$


SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
SELECT *, upper(foonom) FROM recupfoo(1) AS t1;
fooid | foosubid | foonom | upper
-------+----------+--------+------1 |
1 | Joe
| JOE
(1 row)
Comme le montre cet exemple, nous pouvons travailler avec les colonnes du rsultat de la fonction comme s'il s'agissait des colonnes d'une table normale.
Notez que nous n'obtenons qu'une ligne comme rsultat de la fonction. Ceci parce que nous n'avons pas utilis l'instruction
SETOF. Cette instruction est dcrite dans la prochaine section.

35.4.8. Fonctions SQL renvoyant un ensemble


Quand une fonction SQL est dclare renvoyer un SETOF un_type, la requte finale de la fonction est compltement excute
et chaque ligne extraite est renvoye en tant qu'lment de l'ensemble rsultat.
Cette caractristique est normalement utilise lors de l'appel d'une fonction dans une clause FROM. Dans ce cas, chaque ligne renvoye par la fonction devient une ligne de la table vue par la requte. Par exemple, supposons que la table foo ait le mme contenu que prcdemment et crivons :
CREATE FUNCTION recupfoo(int) RETURNS SETOF foo AS $$
SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
SELECT * FROM recupfoo(1) AS t1;
Alors nous obtenons :
fooid | foosousid | foonom
-------+-----------+-------1 |
1 | Joe
1 |
2 | Ed
(2 rows)
Il est aussi possible de renvoyer plusieurs lignes avec les colonnes dfinies par des paramtres en sortie, comme ceci :

653

tendre SQL

CREATE TABLE tab (y int, z int);


INSERT INTO tab VALUES (1, 2), (3, 4), (5, 6), (7, 8);
CREATE FUNCTION sum_n_product_with_tab (x int, OUT sum int, OUT product int)
RETURNS SETOF record
AS $$
SELECT $1 + tab.y, $1 * tab.y FROM tab;
$$ LANGUAGE SQL;
SELECT * FROM sum_n_product_with_tab(10);
sum | product
-----+--------11 |
10
13 |
30
15 |
50
17 |
70
(4 rows)
Le point cl ici est que vous devez crire RETURNS SETOF record pour indiquer que la fonction renvoie plusieurs lignes et
non pas une seule. S'il n'y a qu'un paramtre en sortie, indiquez le type de paramtre plutt que record.
Actuellement, les fonctions renvoyant des ensembles peuvent aussi tre appeles dans la liste du select d'une requte. Pour chaque
ligne gnre par la requte, la fonction renvoyant un ensemble est appele et une ligne est gnre pour chaque lment de
l'ensemble rsultat. Notez cependant que cette fonctionnalit est dconseille et pourra tre supprime dans une version future.
Voici un exemple de fonction renvoyant un ensemble partir de la liste d'un SELECT :
CREATE FUNCTION listeenfant(text) RETURNS SETOF text AS $$
SELECT nom FROM noeuds WHERE parent = $1
$$ LANGUAGE SQL;
SELECT * FROM noeuds;
nom
| parent
--------------+-------Haut
|
Enfant1
| Haut
Enfant2
| Haut
Enfant3
| Haut
Sous-Enfant1 | Enfant1
Sous-Enfant2 | Enfant1
(6 rows)
SELECT listeenfant('Haut');
listeenfant
-------------Enfant1
Enfant2
Enfant3
(3 rows)
SELECT nom, listeenfant(nom) FROM noeuds;
nom
| listeenfant
---------+-------------Haut
| Enfant1
Haut
| Enfant2
Haut
| Enfant3
Enfant1 | Sous-Enfant1
Enfant1 | Sous-Enfant2
(5 rows)
Notez, dans le dernier SELECT, qu'aucune ligne n'est renvoye pour Enfant2, Enfant3, etc. C'est parce que la fonction listeenfant renvoie un ensemble vide pour ces arguments et ainsi aucune ligne n'est gnre.

Note
Si la dernire commande d'une fonction est INSERT, UPDATE ou DELETE avec une clause RETURNING, cette
commande sera toujours excute jusqu' sa fin, mme si la fonction n'est pas dclare avec SETOF ou que la requte appelante ne renvoie pas toutes les lignes rsultats. Toutes les lignes supplmentaires produites par la clause
RETURNING sont silencieusement abandonnes mais les modifications de table sont pris en compte (et sont toutes
termines avant que la fonction ne se termine).
654

tendre SQL

35.4.9. Fonctions SQL renvoyant TABLE


Il existe une autre faon de dclarer une fonction comme renvoyant un ensemble de donnes. Cela passe par la syntaxe RETURNS
TABLE(colonnes). C'est quivalent utiliser un ou plusieurs paramtres OUT et marquer la fonction comme renvoyant un
SETOF record (ou SETOF d'un type simple en sortie, comme appropri). Cette notation est indique dans les versions rcentes
du standard SQL et, du coup, devrait tre plus portable que SETOF.
L'exemple prcdent, sum-and-product, peut se faire aussi de la faon suivante :
CREATE FUNCTION sum_n_product_with_tab (x int)
RETURNS TABLE(sum int, product int) AS $$
SELECT $1 + tab.y, $1 * tab.y FROM tab;
$$ LANGUAGE SQL;
Il n'est pas autoris d'utiliser explicitement des paramtres OUT ou INOUT avec la notation RETURNS TABLE -- vous devez indiquer toutes les colonnes en sortie dans la liste TABLE.

35.4.10. Fonctions SQL polymorphes


Les fonctions SQL peuvent tre dclares pour accepter et renvoyer les types polymorphe anyelement, anyarray, anynonarray
et anyenum. Voir la Section 35.2.5, Types et fonctions polymorphes pour une explication plus approfondie. Voici une fonction
polymorphe cree_tableau qui construit un tableau partir de deux lments de type arbitraire :
CREATE FUNCTION cree_tableau(anyelement, anyelement) RETURNS anyarray AS $$
SELECT ARRAY[$1, $2];
$$ LANGUAGE SQL;
SELECT cree_tableau(1, 2) AS tableau_entier, cree_tableau('a'::text, 'b') AS
tableau_texte;
tableau_entier | tableau_texte
----------------+--------------{1,2}
| {a,b}
(1 row)
Notez l'utilisation du transtypage 'a'::text pour spcifier le type text de l'argument. Ceci est ncessaire si l'argument est une
chane de caractres car, autrement, il serait trait comme un type unknown, et un tableau de type unknown n'est pas un type valide. Sans le transtypage, vous obtiendrez ce genre d'erreur :
ERROR:

could not determine polymorphic type because input is UNKNOWN

Il est permis d'avoir des arguments polymorphes avec un type de renvoi fixe, mais non l'inverse. Par exemple :
CREATE FUNCTION est_plus_grand(anyelement, anyelement) RETURNS bool AS $$
SELECT $1 > $2;
$$ LANGUAGE SQL;
SELECT est_plus_grand(1, 2);
est_plus_grand
---------------f
(1 row)
CREATE FUNCTION fonction_invalide() RETURNS anyelement AS $$
SELECT 1;
$$ LANGUAGE SQL;
ERROR: cannot determine result datatype
DETAIL: A function returning a polymorphic type must have at least one
polymorphic argument.
Le polymorphisme peut tre utilis avec les fonctions qui ont des arguments en sortie. Par exemple :
CREATE FUNCTION dup (f1 anyelement, OUT f2 anyelement, OUT f3 anyarray)
AS 'select $1, array[$1,$1]' LANGUAGE SQL;
SELECT * FROM dup(22);
f2 |
f3
----+--------22 | {22,22}
(1 row)
655

tendre SQL

Le polymorphisme peut aussi tre utilis avec des fonctions variadic. Par exemple :
CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$
SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i);
$$ LANGUAGE SQL;
SELECT anyleast(10, -1, 5, 4);
anyleast
----------1
(1 row)
SELECT anyleast('abc'::text, 'def');
anyleast
---------abc
(1 row)
CREATE FUNCTION concat_values(text, VARIADIC anyarray) RETURNS text AS $$
SELECT array_to_string($2, $1);
$$ LANGUAGE SQL;
SELECT concat_values('|', 1, 4, 2);
concat_values
--------------1|4|2
(1 row)

35.4.11. Fonctions SQL et collationnement


Lorsqu'une fonction SQL dispose d'un ou plusieurs paramtres d'un type de de donnes collationnable, le collationnement applicable est dtermin pour chacun des appels la fonction afin de correspondre au collationnement assign aux arguments, tel que
dcrit la section Section 22.2, Support des collations . Si un collationnement peut tre correctement identifi (c'est--dire qu'il
ne subsiste aucun conflit entre les collationnements implicites des arguments), alors l'ensemble des paramtres collationnables sera trait en fonction de ce collationnement. Ce comportement peut donc avoir une incidence sur les oprations sensibles aux collationnements se trouvant dans le corps de la fonction. Par exemple, en utilisant la fonction anyleast dcrite ci-dessus, le rsultat
de
SELECT anyleast('abc'::text, 'ABC');
dpendra du collationnement par dfaut de l'instance. Ainsi, pour la locale C, le rsultat sera ABC, alors que pour de nombreuses
autres locales, la fonction retournera abc. L'utilisation d'un collationnement particulier peut tre forc lors de l'appel de la fonction en spcifiant la clause COLLATE pour chacun des arguments, par exemple
SELECT anyleast('abc'::text, 'ABC' COLLATE "C");
Par ailleurs, si vous souhaitez qu'une fonction opre avec un collationnement particulier, sans tenir compte du collationnement des
paramtres qui lui seront fournis, il faudra alors spcifier la clause COLLATE souhaite lors de la dfinition de la fonction. Cette
version de la fonction anyleast utilisera systmatiquement la locale fr_FR pour la comparaison des chaines de caractres :
CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$
SELECT min($1[i] COLLATE "fr_FR") FROM generate_subscripts($1, 1) g(i);
$$ LANGUAGE SQL;
Mais il convient de bien noter que cette modification risque d'entraner une erreur si des donnes d'un type non sensible au collationnement lui sont fournies.
Si aucun collationnement commun ne peut tre dtermin entre les arguments fournis, la fonction SQL appliquera aux paramtres
le collationnement par dfaut de leur type de donne (qui correspond gnralement au collationnement par dfaut de l'instance,
mais qui peut diffrer entre des domaines diffrents).
Le comportement des paramtres collationnables peut donc tre assimil une forme limite de polymorphisme, uniquement applicable aux types de donnes textuels.

656

tendre SQL

35.5. Surcharge des fonctions


Plusieurs fonctions peuvent tre dfinies avec le mme nom SQL condition que les arguments soient diffrents. En d'autres
termes, les noms de fonction peuvent tre surchargs. Quand une requte est excute, le serveur dterminera la fonction appeler
partir des types de donnes des arguments et du nombre d'arguments. La surcharge peut aussi tre utilise pour simuler des fonctions avec un nombre variable d'arguments jusqu' un nombre maximum fini.
Lors de la cration d'une famille de fonctions surcharges, vous devriez tre attentif ne pas crer d'ambiguts. Par exemple, avec
les fonctions :
CREATE FUNCTION test(int, real) RETURNS ...
CREATE FUNCTION test(smallint, double precision) RETURNS ...
Savoir quelle fonction sera appele avec une entre triviale comme test(1, 1.5) n'est pas immdiatement clair. Les rgles de
rsolution actuellement implmentes sont dcrites dans le Chapitre 10, Conversion de types mais il est dconseill de concevoir
un systme qui serait bas subtilement sur ce comportement.
Une fonction qui prend un seul argument d'un type composite devrait gnralement ne pas avoir le mme nom que tout attribut
(champ) de ce type. Rappellez-vous que attribut(table) est considr comme quivalent table.attribut. Dans le
cas o il existe une ambigut entre une fonction sur un type composite et sur un attribut d'un type composite, l'attribut sera toujours utilis. Il est possible de contourner ce choix en qualifiant le nom de la fonction avec celui du schma (c'est--dire schema.fonction(table)) mais il est prfrable d'viter le problme en ne choisissant aucun nom conflictuel.
Un autre conflit possible se trouve entre les fonctions variadic et les autres. En fait, il est possible de crer la fois
foo(numeric) et foo(VARIADIC numeric[]). Dans ce cas, il n'est pas simple de savoir lequel sera slectionn lors d'un
appel avec un seul argument numrique, par exemple foo(10.1). La rgle est que la fonction apparaissant plsu tt dans le chemin des schmas est utilis. De mme, si les deux fonctions sont dans le mme schma, la non variadic est prfr.
Lors de la surcharge de fonctions en langage C, il existe une contrainte supplmentaire : le nom C de chaque fonction dans la famille des fonctions surcharges doit tre diffrent des noms C de toutes les autres fonctions, soit internes soit charges dynamiquement Si cette rgle est viole, le comportement n'est pas portable. Vous pourriez obtenir une erreur de l'diteur de lien ou une des
fonctions sera appele (habituellement l'interne). L'autre forme de clause AS pour la commande SQL CREATE FUNCTION dcouple le nom de la fonction SQL partir du nom de la fonction dans le code source C. Par exemple :
CREATE FUNCTION test(int) RETURNS int
AS 'filename', 'test_1arg'
LANGUAGE C;
CREATE FUNCTION test(int, int) RETURNS int
AS 'filename', 'test_2arg'
LANGUAGE C;
Les noms des fonctions C refltent ici une des nombreuses conventions possibles.

35.6. Catgories de volatilit des fonctions


Chaque fonction a une classification de volatilit (volatility) comprenant VOLATILE, STABLE ou IMMUTABLE. VOLATILE est
la valeur par dfaut si la commande CREATE FUNCTION(7) ne spcifie pas de catgorie. La catgorie de volatilit est une promesse l'optimiseur sur le comportement de la fonction :

Une fonction VOLATILE peut tout faire, y compris modifier la base de donnes. Elle peut renvoyer diffrents rsultats sur des
appels successifs avec les mmes arguments. L'optimiseur ne fait aucune supposition sur le comportement de telles fonctions.
Une requte utilisant une fonction volatile r-valuera la fonction chaque ligne o sa valeur est ncessaire.

Une fonction STABLE ne peut pas modifier la base de donnes et est garantie de renvoyer les mmes rsultats si elle est appele avec les mmes arguments pour toutes les lignes l'intrieur d'une mme instruction. Cette catgorie permet l'optimiseur
d'optimiser plusieurs appels de la fonction dans une seule requte. En particulier, vous pouvez utiliser en toute scurit une expression contenant une telle fonction dans une condition de parcours d'index (car un parcours d'index valuera la valeur de la
comparaison une seule fois, pas une fois pour chaque ligne, utiliser une fonction VOLATILE dans une condition de parcours
d'index n'est pas valide).

Une fonction IMMUTABLE ne peut pas modifier la base de donnes et est garantie de toujours renvoyer les mmes rsultats si
elle est appele avec les mmes arguments. Cette catgorie permet l'optimiseur de pr-valuer la fonction quand une requte
l'appelle avec des arguments constants. Par exemple, une requte comme SELECT ... WHERE x = 2 + 2 peut tre simplifie pour obtenir SELECT ... WHERE x = 4 car la fonction sous-jacente de l'oprateur d'addition est indique IMMUTABLE.

Pour une meilleure optimisation des rsultats, vous devez mettre un label sur les fonctions avec la catgorie la plus volatile valide
pour elles.
657

tendre SQL

Toute fonction avec des effets de bord doit tre indique comme VOLATILE, de faon ce que les appels ne puissent pas tre optimiss. Mme une fonction sans effets de bord doit tre indique comme VOLATILE si sa valeur peut changer l'intrieur d'une
seule requte ; quelques exemples sont random(), currval(), timeofday().
Un autre exemple important est que la famille de fonctions current_timestamp est qualifie comme STABLE car leurs valeurs ne changent pas l'intrieur d'une transaction.
Il y a relativement peu de diffrences entre les catgories STABLE et IMMUTABLE en considrant les requtes interactives qui
sont planifies et immdiatement excutes : il importe peu que la fonction soit excute une fois lors de la planification ou une
fois au lancement de l'excution de la requte mais cela fait une grosse diffrence si le plan est sauvegard et utilis plus tard. Placer un label IMMUTABLE sur une fonction quand elle ne l'est pas vraiment pourrait avoir comme consquence de la considrer
prmaturment comme une constante lors de la planification et rsulterait en une valeur errone lors d'une utilisation ultrieure de
ce plan d'excution. C'est un danger qui arrive lors de l'utilisattion d'instructions prpares ou avec l'utilisation de langages de
fonctions mettant les plans d'excutions en cache (comme PL/pgSQL).
Pour les fonctions crites en SQL ou dans tout autre langage de procdure standard, la catgorie de volatibilit dtermine une
deuxime proprit importante, savoir la visibilit de toute modification de donnes effectues par la commande SQL qui a appel la fonction. Une fonction VOLATILE verra les changements, une fonction STABLE ou IMMUTABLE ne les verra pas. Ce
comportement est implante en utilisant le comportement par images de MVCC (voir Chapitre 13, Contrle d'accs simultan) :
les fonctions STABLE et IMMUTABLE utilisent une image tablie au lancement de la requte appelante alors que les fonctions
VOLATILE obtiennent une image fraiche au dbut de chaque requte qu'elles excutent.

Note
Les fonctions crites en C peuvent grer les images de la faon qu'elles le souhaitent, mais il est prfrable de coder
les fonctions C de la mme faon.
cause du comportement base d'images, une fonction contenant seulement des commandes SELECT peut tre indique
STABLE en toute scurit mme s'il slectionne des donnes partir de tables qui pourraient avoir subi des modifications entre
temps par des requtes concurrentes. PostgreSQL excutera toutes les commandes d'une fonction STABLE en utilisant l'image
tablie par la requte appelante et n'aura qu'une vision fige de la base de donnes au cours de la requte.
Ce mme comportement d'images est utilis pour les commandes SELECT l'intrieur de fonctions IMMUTABLE. Il est gnralement dconseill de slectionner des tables de la base de donnes l'intrieur de fonctions IMMUTABLE car l'immutabilit sera
rompue si le contenu de la table change. Nanmoins, PostgreSQL ne vous force pas ne pas le faire.
Une erreur commune est de placer un label sur une fonction IMMUTABLE quand son rsultat dpend d'un paramtre de configuration. Par exemple, une fonction qui manipule des types date/heure pourrait bien avoir des rsultats dpendant du paramtre timezone. Pour tre scurises, de telles fonctions devraient avoir le label STABLE la place.

Note
Avant PostgreSQL version 8.0, le prrequis que les fonctions STABLE et IMMUTABLE ne pouvaient pas modifier la base de donnes n'tait pas contraint par le systme. Les versions 8.0 et ultrieures le contraignent en rclamant que les fonctions SQL et les fonctions de langages de procdures de ces catgories ne contiennent pas de
commandes SQL autre que SELECT (ceci n'a pas t compltement test car de telles fonctions pourraient toujours appeler des fonctions VOLATILE qui modifient la base de donnes. Si vous le faites, vous trouverez que la
fonction STABLE ou IMMUTABLE n'est pas au courant des modifications effectues sur la base de donnes par la
fonction appele, car elles sont caches depuis son image).

35.7. Fonctions en langage de procdures


PostgreSQL autorise l'criture de fonctions dfinies par l'utilisateur dans d'autres langages que SQL et C. Ces autres langages
sont appels des langages de procdure (PL). Les langages de procdures ne sont pas compils dans le serveur PostgreSQL ; ils
sont fournis comme des modules chargeables. Voir le Chapitre 38, Langages de procdures et les chapitres suivants pour plus
d'informations.
Il y a actuellement quatre langages de procdures disponibles dans la distribution PostgreSQL standard : PL/pgSQL, PL/Tcl,
PL/Perl et PL/Python. Rfrez-vous au Chapitre 38, Langages de procdures pour plus d'informations. D'autres langages peuvent
tre dfinis par les utilisateurs. Les bases du dveloppement d'un nouveau langage de procdures sont traites dans le Chapitre 49,
crire un gestionnaire de langage procdural.

35.8. Fonctions internes


658

tendre SQL

Les fonctions internes sont des fonctions crites en C qui ont t lies de faon statique dans le serveur PostgreSQL. Le
corps de la dfinition de la fonction spcifie le nom en langage C de la fonction, qui n'est pas obligatoirement le mme que le
nom dclar pour l'utilisation en SQL (pour des raisons de rtro compatibilit, un corps vide est accept pour signifier que le nom
de la fonction en langage C est le mme que le nom SQL).
Normalement, toutes les fonctions internes prsentes dans le serveur sont dclares pendant l'initialisation du groupe de base de
donnes (voir Section 17.2, Crer un groupe de base de donnes ) mais un utilisateur peut utiliser la commande CREATE
FUNCTION pour crer des noms d'alias supplmentaires pour une fonction interne. Les fonctions internes sont dclares dans la
commande CREATE FUNCTION avec le nom de langage internal. Par exemple, pour crer un alias de la fonction sqrt :
CREATE FUNCTION racine_carree(double precision) RETURNS double precision
'dsqrt'
LANGUAGE internal
STRICT;

AS

(la plupart des fonctions internes doivent tre dclares STRICT )

Note
Toutes les fonctions prdfinies ne sont pas internes (au sens explicit ci-dessus). Quelques fonctions prdfinies sont crites en SQL.

35.9. Fonctions en langage C


Les fonctions dfinies par l'utilisateur peuvent tre crites en C (ou dans un langage pouvant tre rendu compatible avec C, comme
le C++). Ces fonctions sont compiles en objets dynamiques chargeables (encore appels bibliothques partages) et sont charges
par le serveur la demande. Cette caractristique de chargement dynamique est ce qui distingue les fonctions en langage C des
fonctions internes -- les vritables conventions de codage sont essentiellement les mmes pour les deux (c'est pourquoi la bibliothque standard de fonctions internes est une source abondante d'exemples de code pour les fonctions C dfinies par
l'utilisateur).
Deux diffrentes conventions d'appel sont actuellement en usage pour les fonctions C. La plus rcente, version 1 , est indique
en crivant une macro d'appel PG_FUNCTION_INFO_V1() comme illustr ci-aprs. L'absence d'une telle macro indique une
fonction crite selon l'ancien style ( version 0 ). Le nom de langage spcifi dans la commande CREATE FUNCTION est C
dans les deux cas. Les fonctions suivant l'ancien style sont maintenant dconseilles en raison de problmes de portabilit et d'un
manque de fonctionnalit mais elles sont encore supportes pour des raisons de compatibilit.

35.9.1. Chargement dynamique


La premire fois qu'une fonction dfinie par l'utilisateur dans un fichier objet particulier chargeable est appele dans une session,
le chargeur dynamique charge ce fichier objet en mmoire de telle sorte que la fonction peut tre appele. La commande
CREATE FUNCTION pour une fonction en C dfinie par l'utilisateur doit par consquent spcifier deux lments d'information
pour la fonction : le nom du fichier objet chargeable et le nom en C (lien symbolique) de la fonction spcifique appeler
l'intrieur de ce fichier objet. Si le nom en C n'est pas explicitement spcifi, il est suppos tre le mme que le nom de la fonction
SQL.
L'algorithme suivant, bas sur le nom donn dans la commande CREATE FUNCTION, est utilis pour localiser le fichier objet
partag :
1. Si le nom est un chemin absolu, le fichier est charg.
2. Si le nom commence par la chane $libdir, cette chane est remplace par le nom du rpertoire de la bibliothque du paquetage PostgreSQL, qui est dtermin au moment de la compilation.
3. Si le nom ne contient pas de partie rpertoire, le fichier est recherch par le chemin spcifi dans la variable de configuration
dynamic_library_path.
4. Dans les autres cas, (nom de fichier non trouv dans le chemin ou ne contenant pas de partie rpertoire non absolu), le chargeur
dynamique essaiera d'utiliser le nom donn, ce qui chouera trs vraisemblablement (dpendre du rpertoire de travail en cours
n'est pas fiable).
Si cette squence ne fonctionne pas, l'extension pour les noms de fichier des bibliothques partages spcifique la plateforme
(souvent .so) est ajoute au nom attribu et la squence est nouveau tente. En cas de nouvel chec, le chargement choue.
Il est recommand de localiser les bibliothques partages soit relativement $libdir ou via le chemin dynamique des bibliothques. Ceci simplifie les mises jour de versions si la nouvelle installation est un emplacement diffrent. Le rpertoire actuel
reprsent par $libdir est trouvable avec la commande pg_config --pkglibdir.
659

tendre SQL

L'identifiant utilisateur sous lequel fonctionne le serveur PostgreSQL doit pouvoir suivre le chemin jusqu'au fichier que vous essayez de charger. Une erreur frquente revient dfinir le fichier ou un rpertoire suprieur comme non lisible et/ou non excutable par l'utilisateur postgres.
Dans tous les cas, le nom de fichier donn dans la commande CREATE FUNCTION est enregistr littralement dans les catalogues systmes, de sorte que, si le fichier doit tre nouveau charg, la mme procdure sera applique.

Note
PostgreSQL ne compilera pas une fonction C automatiquement. Le fichier objet doit tre compil avant d'tre rfrenc dans une commande CREATE FUNCTION. Voir la Section 35.9.6, Compiler et lier des fonctions charges dynamiquement pour des informations complmentaires.
Pour s'assurer qu'un fichier objet chargeable dynamiquement n'est pas charg dans un serveur incompatible, PostgreSQL vrifie
que le fichier contient un bloc magique avec un contenu appropri. Ceci permet au serveur de dtecter les incompatibilits videntes comme du code compilet pour une version majeure diffrente de PostgreSQL. Un bloc magique est requis partir de
PostgreSQL 8.2. Pour inclure un bloc magique, crivez ceci dans un (et seulement un) des fichiers source du module, aprs
avoir inclus l'en-tte fmgr.h :
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
Le test #ifdef peut tre omis si le code n'a pas besoin d'tre compil avec des versions de PostgreSQL antrieures la 8.2.
Aprs avoir t utilis pour la premire fois, un fichier objet charg dynamiquement est conserv en mmoire. Les futurs appels de
fonction(s) dans ce fichier pendant la mme session provoqueront seulement une lgre surcharge due la consultation d'une table
de symboles. Si vous devez forcer le chargement d'un fichier objet, par exemple aprs une recompilation, commencez une nouvelle session.
De faon optionnelle, un fichier charg dynamiquement peut contenir des fonctions d'initialisation et de terminaison. Si le fichier
inclut une fonction nomme _PG_init, cette fonction sera appele immdiatement aprs le chargement du fichier. La fonction
ne reoit aucun paramtre et doit renvoyer void. Si le fichier inclut une fonction nomme _PG_fini, cette fonction sera appele
tout juste avant le dchargement du fichier. De la mme faon, la fonction ne reoit aucun paramtre et doit renvoyer void. Notez
que _PG_fini sera seulement appele lors du dchargement du fichier, pas au moment de la fin du processus. (Actuellement, les
dchargements sont dsactivs et ne surviendront jamais, bien que cela puisse changer un jour.)

35.9.2. Types de base dans les fonctions en langage C


Pour savoir comment crire des fonctions en langage C, vous devez savoir comment PostgreSQL reprsente en interne les types
de donnes de base et comment elles peuvent tre passs vers et depuis les fonctions. En interne, PostgreSQL considre un type
de base comme un blob de mmoire . Les fonctions que vous dfinissez sur un type dfinissent leur tour la faon que PostgreSQL opre sur lui. C'est--dire que PostgreSQL ne fera que conserver et retrouver les donnes sur le disque et utilisera
votre fonction pour entrer, traiter et restituer les donnes.
Les types de base peuvent avoir un des trois formats internes suivants :

passage par valeur, longueur fixe ;

passage par rfrence, longueur fixe ;

passage par rfrence, longueur variable.

Les types par valeur peuvent seulement avoir une longueur de 1, 2 ou 4 octets (galement 8 octets si sizeof(Datum) est de
huit octets sur votre machine). Vous devriez tre attentif lors de la dfinition de vos types de sorte qu'ils aient la mme taille sur
toutes les architectures. Par exemple, le type long est dangereux car il a une taille de quatre octets sur certaines machines et huit
octets sur d'autres, alors que le type int est de quatre octets sur la plupart des machines Unix. Une implmentation raisonnable du
type int4 sur une machine Unix pourrait tre
/* entier sur quatre octets, pass par valeur */
typedef int int4;
D'autre part, les types longueur fixe d'une taille quelconque peuvent tre passs par rfrence. Par exemple, voici
l'implmentation d'un type PostgreSQL :
/* structure de 16 octets, passe par rfrence */
typedef struct
660

tendre SQL

{
double
} Point;

x, y;

Seuls des pointeurs vers de tels types peuvent tre utiliss en les passant dans et hors des fonctions PostgreSQL. Pour renvoyer
une valeur d'un tel type, allouez la quantit approprie de mmoire avec palloc, remplissez la mmoire alloue et renvoyez un
pointeur vers elle (de plus, si vous souhaitez seulement renvoyer la mme valeur qu'un de vos arguments en entre qui se trouve
du mme type, vous pouvez passer le palloc supplmentaire et simplement renvoyer le pointeur vers la valeur en entre).
Enfin, tous les types longueur variable doivent aussi tre passs par rfrence. Tous les types longueur variable doivent commencer avec un champ d'une longueur d'exactement quatre octets et toutes les donnes devant tre stockes dans ce type doivent
tre localises dans la mmoire la suite immdiate de ce champ longueur. Le champ longueur contient la longueur totale de la
structure, c'est--dire incluant la longueur du champ longueur lui-mme.
Un autre point important est d'viter de laisser des bits non initialiss dans les structures de types de donnes ;; par exemple, prenez bien soin de remplir avec des zros tous les octets de remplissage qui sont prsents dans les structures de donnes des fins
d'alignement. A dfaut, des constantes logiquement quivalentes de vos types de donnes pourraient tre considres comme ingales par l'optimiseur, impliquant une planification inefficace (bien que les rsultats puissent malgr tout tre corrects).

Avertissement
Ne jamais modifier le contenu d'une valeur en entre passe par rfrence. Si vous le faites, il y a de forts risques
pour que vous russissiez corrompre les donnes sur disque car le pointeur que vous avez reu pourrait bien pointer directement vers un tampon disque. La seule exception cette rgle est explique dans la Section 35.10,
Agrgats utilisateur .
Comme exemple, nous pouvons dfinir le type text comme ceci :
typedef struct {
int4 length;
char data[1];
} text;
Il est vident que le champ dclar ici n'est pas assez long pour contenir toutes les chanes possibles. Comme il est impossible de
dclarer une structure de taille variable en C, nous nous appuyons sur le fait que le compilateur C ne vrifie pas la plage des indices de tableau. Nous allouons juste la quantit d'espace ncessaire et ensuite nous accdons au tableau comme s'il avait t dclar avec la bonne longueur (c'est une astuce courante que vous pouvez trouver dans beaucoup de manuels de C).
En manipulant les types longueur variable, nous devons tre attentifs allouer la quantit correcte de mmoire et fixer correctement le champ longueur. Par exemple, si nous voulons stocker 40 octets dans une structure text, nous devrions utiliser un fragment de code comme celui-ci :
#include "postgres.h"
...
char buffer[40]; /* notre donne source */
...
text *destination = (text *) palloc(VARHDRSZ + 40);
SET_VARSIZE(destination, VARHDRSZ + 40);
memcpy(destination->data, buffer, 40);
...
VARHDRSZ est quivalent sizeof(int4) mais est considr comme une meilleure tournure de rfrence la taille de
l'overhead pour un type longueur variable. Also, the length field must be set using the SET_VARSIZE macro, not by simple assignment.
Le Tableau 35.1, quivalence des types C et des types SQL intgrs spcifie la correspondance entre les types C et les types
SQL quand on crit une fonction en langage C utilisant les types internes de PostgreSQL. La colonne Dfini dans donne le
fichier d'en-tte devant tre inclus pour accder la dfinition du type (la dfinition effective peut se trouver dans un fichier diffrent inclus dans le fichier indiqu. Il est recommand que les utilisateurs s'en tiennent l'interface dfinie). Notez que vous devriez
toujours inclure postgres.h en premier dans tout fichier source car il dclare un grand nombre d'lments dont vous aurez besoin de toute faon.
Tableau 35.1. quivalence des types C et des types SQL intgrs

Type SQL

Type C

Dfini dans

abstime

AbsoluteTime

utils/nabstime.h

boolean

bool

postgres.h (intgration au compilateur)


661

tendre SQL

Type SQL

Type C

Dfini dans

box

BOX*

utils/geo_decls.h

bytea

bytea*

postgres.h

"char"

char

(intgr au compilateur)

character

BpChar*

postgres.h

cid

CommandId

postgres.h

date

DateADT

utils/date.h

smallint (int2)

int2 or int16

postgres.h

int2vector

int2vector*

postgres.h

integer (int4)

int4 or int32

postgres.h

real (float4)

float4*

postgres.h

double precision (float8)

float8*

postgres.h

interval

Interval*

utils/timestamp.h

lseg

LSEG*

utils/geo_decls.h

name

Name

postgres.h

oid

Oid

postgres.h

oidvector

oidvector*

postgres.h

path

PATH*

utils/geo_decls.h

point

POINT*

utils/geo_decls.h

regproc

regproc

postgres.h

reltime

RelativeTime

utils/nabstime.h

text

text*

postgres.h

tid

ItemPointer

storage/itemptr.h

time

TimeADT

utils/date.h

time with time zone

TimeTzADT

utils/date.h

timestamp

Timestamp*

utils/timestamp.h

tinterval

TimeInterval

utils/nabstime.h

varchar

VarChar*

postgres.h

xid

TransactionId

postgres.h

Maintenant que nous avons pass en revue toutes les structures possibles pour les types de base, nous pouvons donner quelques
exemples de vraies fonctions.

35.9.3. Conventions d'appel de la version 0


Nous prsentons l' ancien style de convention d'appel en premier -- bien que cette approche soit maintenant dconseille, elle
est plus facile matriser au dbut. Dans la mthode version-0, les arguments et rsultats de la fonction C sont simplement dclars dans le style C normal mais en faisant attention utiliser la reprsentation C de chaque type de donnes SQL comme montr
ci-dessus.
Voici quelques exemples :
#include "postgres.h"
#include <string.h>
#include "utils/geo_decls.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
/* par valeur */
int
662

tendre SQL

add_one(int arg)
{
return arg + 1;
}
/* par rfrence, taille fixe */
float8 *
add_one_float8(float8 *arg)
{
float8
*result = (float8 *) palloc(sizeof(float8));
*result = *arg + 1.0;
return result;
}
Point *
makepoint(Point *pointx, Point *pointy)
{
Point
*new_point = (Point *) palloc(sizeof(Point));
new_point->x = pointx->x;
new_point->y = pointy->y;
return new_point;
}
/* par rfrence, taille variable */
text *
copytext(text *t)
{
/*
* VARSIZE est la taille totale de la structure en octets.
*/
text *new_t = (text *) palloc(VARSIZE(t));
SET_VARSIZE(new_t, VARSIZE(t));
/*
* VARDATA est un pointeur sur la rgion de donnes de la structure.
*/
memcpy((void *) VARDATA(new_t), /* destination */
(void *) VARDATA(t),
/* source */
VARSIZE(t) - VARHDRSZ); /* nombre d'octets */
return new_t;
}
text *
concat_text(text *arg1, text *arg2)
{
int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
text *new_text = (text *) palloc(new_text_size);
SET_VARSIZE(new_text, new_text_size);
memcpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1) - VARHDRSZ);
memcpy(VARDATA(new_text) + (VARSIZE(arg1) - VARHDRSZ),
VARDATA(arg2), VARSIZE(arg2) - VARHDRSZ);
return new_text;
}
En supposant que le code ci-dessus ait t crit dans le fichier funcs.c et compil en objet partag, nous pourrions dfinir les
fonctions pour PostgreSQL avec des commandes comme ceci :
CREATE FUNCTION add_one(integer) RETURNS integer
AS 'DIRECTORY/funcs', 'add_one'
LANGUAGE C STRICT;
-- notez la surcharge du nom de la fonction SQL "add_one"
CREATE FUNCTION add_one(double precision) RETURNS double precision
663

tendre SQL

AS 'DIRECTORY/funcs', 'add_one_float8'
LANGUAGE C STRICT;
CREATE FUNCTION makepoint(point, point) RETURNS point
AS 'DIRECTORY/funcs', 'makepoint'
LANGUAGE C STRICT;
CREATE FUNCTION copytext(text) RETURNS text
AS 'DIRECTORY/funcs', 'copytext'
LANGUAGE C STRICT;
CREATE FUNCTION concat_text(text, text) RETURNS text
AS 'DIRECTORY/funcs', 'concat_text'
LANGUAGE C STRICT;
Ici, DIRECTORY reprsente le rpertoire contenant le fichier de la bibliothque partage (par exemple le rpertoire du tutoriel de
PostgreSQL, qui contient le code des exemples utiliss dans cette section). (Un meilleur style aurait t d'crire seulement
'funcs' dans la clause AS, aprs avoir ajout DIRECTORY au chemin de recherche. Dans tous les cas, nous pouvons omettre
l'extension spcifique au systme pour les bibliothques partages, communment .so ou .sl.)
Remarquez que nous avons spcifi la fonction comme STRICT , ce qui signifie que le systme devra automatiquement supposer un rsultat NULL si n'importe quelle valeur d'entre est NULL. Ainsi, nous vitons d'avoir vrifier l'existence d'entres
NULL dans le code de la fonction. Sinon, nous aurions d contrler explicitement les valeurs NULL en testant un pointeur NULL
pour chaque argument pass par rfrence (pour les arguments passs par valeur, nous n'aurions mme aucun moyen de
contrle !).
Bien que cette convention d'appel soit simple utiliser, elle n'est pas trs portable ; sur certaines architectures, il y a des problmes
pour passer de cette manire des types de donnes plus petits que int. De plus, il n'y a pas de moyen simple de renvoyer un rsultat
NULL, ni de traiter des arguments NULL autrement qu'en rendant la fonction strict. La convention version-1, prsente ci-aprs,
permet de surmonter ces objections.

35.9.4. Conventions d'appel de la version 1


La convention d'appel version-1 repose sur des macros pour supprimer la plus grande partie de la complexit du passage
d'arguments et de rsultats. La dclaration C d'une fonction en version-1 est toujours :
Datum nom_fonction(PG_FUNCTION_ARGS)
De plus, la macro d'appel :
PG_FUNCTION_INFO_V1(nom_fonction);
doit apparatre dans le mme fichier source (par convention, elle est crite juste avant la fonction elle-mme). Cette macro n'est
pas ncessaire pour les fonctions internal puisque PostgreSQL assume que toutes les fonctions internes utilisent la convention version-1. Elle est toutefois requise pour les fonctions charges dynamiquement.
Dans une fonction version-1, chaque argument existant est trait par une macro PG_GETARG_xxx() correspondant au type de
donne de l'argument et le rsultat est renvoy par une macro PG_RETURN_xxx() correspondant au type renvoy.
PG_GETARG_xxx() prend comme argument le nombre d'arguments de la fonction parcourir, le compteur commenant 0.
PG_RETURN_xxx() prend comme argument la valeur effective renvoyer.
Voici la mme fonction que prcdemment, code en style version-1
#include
#include
#include
#include

"postgres.h"
<string.h>
"fmgr.h"
"utils/geo_decls.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
/* par valeur */
PG_FUNCTION_INFO_V1(add_one);
Datum
add_one(PG_FUNCTION_ARGS)
{
int32
arg = PG_GETARG_INT32(0);
664

tendre SQL

PG_RETURN_INT32(arg + 1);
}
/* par rfrence, longueur fixe */
PG_FUNCTION_INFO_V1(add_one_float8);
Datum
add_one_float8(PG_FUNCTION_ARGS)
{
/* La macro pour FLOAT8 cache sa nature de passage par rfrence. */
float8
arg = PG_GETARG_FLOAT8(0);
PG_RETURN_FLOAT8(arg + 1.0);
}
PG_FUNCTION_INFO_V1(makepoint);
Datum
makepoint(PG_FUNCTION_ARGS)
{
/* Ici, la nature de passage par rfrence de Point n'est pas cache. */
Point
*pointx = PG_GETARG_POINT_P(0);
Point
*pointy = PG_GETARG_POINT_P(1);
Point
*new_point = (Point *) palloc(sizeof(Point));
new_point->x = pointx->x;
new_point->y = pointy->y;
PG_RETURN_POINT_P(new_point);
}
/* par rfrence, longueur variable */
PG_FUNCTION_INFO_V1(copytext);
Datum
copytext(PG_FUNCTION_ARGS)
{
text
*t = PG_GETARG_TEXT_P(0);
/*
* VARSIZE est la longueur totale de la structure en octets.
*/
text
*new_t = (text *) palloc(VARSIZE(t));
SET_VARSIZE(new_t, VARSIZE(t));
/*
* VARDATA est un pointeur vers la rgion de donnes de la structure.
*/
memcpy((void *) VARDATA(new_t), /* destination */
(void *) VARDATA(t),
/* source */
VARSIZE(t) - VARHDRSZ);
/* nombre d'octets */
PG_RETURN_TEXT_P(new_t);
}
PG_FUNCTION_INFO_V1(concat_text);
Datum
concat_text(PG_FUNCTION_ARGS)
{
text *arg1 = PG_GETARG_TEXT_P(0);
text *arg2 = PG_GETARG_TEXT_P(1);
int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
text *new_text = (text *) palloc(new_text_size);
SET_VARSIZE(new_text, new_text_size);
memcpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1) - VARHDRSZ);
memcpy(VARDATA(new_text) + (VARSIZE(arg1) - VARHDRSZ),
VARDATA(arg2), VARSIZE(arg2) - VARHDRSZ);
665

tendre SQL

PG_RETURN_TEXT_P(new_text);
}
Les commandes CREATE FUNCTION sont les mmes que pour leurs quivalents dans la version-0.
Au premier coup d'il, les conventions de codage de la version-1 peuvent sembler inutilement obscures. Pourtant, elles offrent
nombre d'amliorations car les macros peuvent cacher les dtails superflus. Un exemple est donn par la fonction
add_one_float8 o nous n'avons plus besoin de prter attention au fait que le type float8 est pass par rfrence. Un autre
exemple de simplification est donn par les macros pour les types longueur variable GETARG qui permettent un traitement plus
efficace des valeurs toasted (compresses ou hors-ligne).
Une des grandes amliorations dans les fonctions version-1 est le meilleur traitement des entres et des rsultats NULL. La macro
PG_ARGISNULL(n) permet une fonction de tester si chaque entre est NULL (videmment, ceci n'est ncessaire que pour les
fonctions dclares non STRICT ). Comme avec les macros PG_GETARG_xxx(), les arguments en entre sont compts
partir de zro. Notez qu'on doit se garder d'excuter PG_GETARG_xxx() jusqu' ce qu'on ait vrifi que l'argument n'est pas
NULL. Pour renvoyer un rsultat NULL, excutez la fonction PG_RETURN_NULL() ; ceci convient aussi bien dans les fonctions
STRICT que non STRICT.
Les autres options proposes dans l'interface de nouveau style sont deux variantes des macros PG_GETARG_xxx(). La premire
d'entre elles, PG_GETARG_xxx_COPY(), garantit le renvoi d'une copie de l'argument spcifi o nous pouvons crire en toute
scurit (les macros normales peuvent parfois renvoyer un pointeur vers une valeur physiquement mise en mmoire dans une table
qui ne doit pas tre modifie. En utilisant les macros PG_GETARG_xxx_COPY(), on garantit l'criture du rsultat). La seconde
variante se compose des macros PG_GETARG_xxx_SLICE() qui prennent trois arguments. Le premier est le nombre
d'arguments de la fonction (comme ci-dessus). Le second et le troisime sont le dcalage et la longueur du segment qui doit tre
renvoy. Les dcalages sont compts partir de zro et une longueur ngative demande le renvoi du reste de la valeur. Ces macros
procurent un accs plus efficace des parties de valeurs grande dimension dans le cas o elles ont un type de stockage en mmoire external (le type de stockage d'une colonne peut tre spcifi en utilisant ALTER TABLE nom_table ALTER COLUMN nom_colonne SET STORAGE typestockage. typestockage est un type parmi plain, external, extended ou main).
Enfin, les conventions d'appels de la version-1 rendent possible le renvoi de rsultats d'ensemble (Section 35.9.9, Renvoi
d'ensembles ), l'implmentation de fonctions dclencheurs (Chapitre 36, Dclencheurs (triggers)) et d'oprateurs d'appel de langage procdural (Chapitre 49, crire un gestionnaire de langage procdural). Le code version-1 est aussi plus portable que celui de
version-0 car il ne contrevient pas aux restrictions du protocole d'appel de fonction en C standard. Pour plus de dtails, voir src/
backend/utils/fmgr/README dans les fichiers sources de la distribution.

35.9.5. criture du code


Avant de nous intresser des sujets plus avancs, nous devons discuter de quelques rgles de codage des fonctions en langage C
de PostgreSQL. Bien qu'il soit possible de charger des fonctions crites dans des langages autre que le C dans PostgreSQL,
c'est habituellement difficile (quand c'est possible) parce que les autres langages comme C++, FORTRAN ou Pascal ne suivent
pas frquemment les mmes conventions de nommage que le C. C'est--dire que les autres langages ne passent pas les arguments
et ne renvoient pas les valeurs entre fonctions de la mme manire. Pour cette raison, nous supposerons que nos fonctions en langage C sont rellement crites en C.
Les rgles de base pour l'criture de fonctions C sont les suivantes :

Utilisez pg_config --includedir-server pour dcouvrir o sont installs les fichiers d'en-tte du serveur PostgreSQL sur votre systme (ou sur le systme de vos utilisateurs).

Compilez et liez votre code de faon ce qu'il soit charg dynamiquement dans PostgreSQL, ce qui requiert des informations spciales. Voir Section 35.9.6, Compiler et lier des fonctions charges dynamiquement pour une explication dtaille
sur la faon de le faire pour votre systme d'exploitation spcifique.

Rappelez-vous de dfinir un bloc magique pour votre bibliothque partage, comme dcrit dans Section 35.9.1,
Chargement dynamique .

Quand vous allouez de la mmoire, utilisez les fonctions PostgreSQL palloc et pfree au lieu des fonctions correspondantes malloc et free de la bibliothque C. La mmoire alloue par palloc sera libre automatiquement la fin de
chaque transaction, empchant des dbordements de mmoire.

Remettez toujours zro les octets de vos structures en utilisant memset (ou allouez les avec la fonction palloc0). Mme si
vous assignez chacun des champs de votre structure, il pourrait rester des espaces de remplissage (trous dans la structure) afin
de respecter l'alignement des donnes qui contiennent des valeurs parasites. Sans cela, il sera difficile de calculer des hachages
pour les index ou les jointures, dans la mesure o vous devrez uniquement tenir compte des octets significatifs de vos structures de donnes pour calculer ces hachages. Le planificateur se base galement sur des comparaisons de constantes via des
galits de bits, aussi vous pouvez obtenir des planifications incorrectes si des valeurs logiquement quivalentes ne sont pas
666

tendre SQL

identiques bit bit.

La plupart des types internes PostgreSQL sont dclars dans postgres.h alors que les interfaces de gestion des fonctions
(PG_FUNCTION_ARGS, etc.) sont dans fmgr.h. Du coup, vous aurez besoin d'inclure au moins ces deux fichiers. Pour des
raisons de portabilit, il vaut mieux inclure postgres.h en premier avant tout autre fichier d'en-tte systme ou utilisateur.
En incluant postgres.h, il incluera galement elog.h et palloc.h pour vous.

Les noms de symboles dfinis dans les objets ne doivent pas entrer en conflit entre eux ou avec les symboles dfinis dans les
excutables du serveur PostgreSQL. Vous aurez renommer vos fonctions ou variables si vous recevez un message d'erreur
cet effet.

35.9.6. Compiler et lier des fonctions charges dynamiquement


Avant de pouvoir tre utilises dans PostgreSQL, les fonctions d'extension crites en C doivent tre compiles et lies d'une certaine faon, ceci afin de produire un fichier dynamiquement chargeable par le serveur. Pour tre plus prcis, une bibliothque partage doit tre cre.
Pour obtenir plus d'informations que celles contenues dans cette section, il faut se rfrer la documentation du systme
d'exploitation, en particulier les pages traitant du compilateur C, de cc et de l'diteur de lien, ld. Par ailleurs, le code source de
PostgreSQL contient de nombreux exemples fonctionnels dans le rpertoire contrib. Nanmoins, ces exemples entranent la
cration de modules qui dpendent de la disponibilit du code source de PostgreSQL.
La cration de bibliothques partages est un processus analogue celui utilis pour lier des excutables : les fichiers sources sont
d'abord compils en fichiers objets puis sont lies ensemble. Les fichiers objets doivent tre compils sous la forme de code indpendant de sa position (PIC, acronyme de position-independent code) . Conceptuellement, cela signifie qu'ils peuvent tre placs
dans une position arbitraire de la mmoire lorsqu'ils sont chargs par l'excutable. (Les fichiers objets destins aux excutables ne
sont gnralement pas compils de cette manire.) La commande qui permet de lier des bibliothques partages ncessite des options spciales qui la distinguent de celle permettant de lier un excutable. En thorie, tout du moins. La ralit est, sur certains
systmes, beaucoup plus complexe.
Les exemples suivants considrent que le code source est un fichier foo.c et qu'une bibliothque partage foo.so doit tre
cre. Sans prcision, le fichier objet intermdiaire est appel foo.o. Une bibliothque partage peut contenir plusieurs fichiers
objet. Cela dit, un seul est utilis ici.
BSD/OS
L'option du compilateur pour crer des PIC est -fpic. L'option de l'diteur de liens pour crer des bibliothques partages
est -shared.
gcc -fpic -c foo.c
ld -shared -o foo.so foo.o
Ceci est applicable partir de la version 4.0 de BSD/OS.
FreeBSD
L'option du compilateur pour crer des PIC est -fpic. L'option de l'diteur de liens pour crer des bibliothques partages
est -shared.
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
Ceci est applicable partir de la version 3.0 de FreeBSD.
HP-UX
L'option du compilateur du systme pour crer des PIC est +z. Avec GCC, l'option est -fpic. Le commutateur de l'diteur
de liens pour les bibliothques partages est -b. Ainsi :
cc +z -c foo.c
ou :
gcc -fpic -c foo.c
puis :
ld -b -o foo.sl foo.o
HP-UX utilise l'extension .sl pour les bibliothques partages, la diffrence de la plupart des autres systmes.
IRIX
667

tendre SQL

PIC est l'option par dfaut. Aucune option de compilation particulire n'est ncessaire. Le commutateur de l'diteur de liens
pour produire des bibliothques partages est -shared :
cc -c foo.c
ld -shared -o foo.so foo.o
Linux
L'option du compilateur pour crer des PIC est -fpic. Sur certaines plateformes et dans certaines situations, -fPIC doit
tre utilis si -fpic ne fonctionne pas. Le manuel de GCC donne plus d'informations. L'option de compilation pour crer des
bibliothques partages est -shared. Un exemple complet ressemble :
cc -fpic -c foo.c
cc -shared -o foo.so foo.o
Mac OS X
L'exemple suivant suppose que les outils de dveloppement sont installs.
cc -c foo.c
cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o
NetBSD
L'option du compilateur pour crer des PIC est -fpic. Pour les systmes ELF, l'option de compilation pour lier les bibliothques partages est -shared. Sur les systmes plus anciens et non-ELF, on utilise ld -Bshareable.
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
OpenBSD
L'option du compilateur pour crer des PIC est -fpic. Les bibliothques partages peuvent tre cres avec ld Bshareable.
gcc -fpic -c foo.c
ld -Bshareable -o foo.so foo.o
Solaris
L'option du compilateur pour crer des PIC est -KPIC avec le compilateur de Sun et -fpic avec GCC. Pour lier les bibliothques partages, l'option de compilation est respectivement -G ou -shared.
cc -KPIC -c foo.c
cc -G -o foo.so foo.o
ou
gcc -fpic -c foo.c
gcc -G -o foo.so foo.o
Tru64 UNIX
Par dfaut, il s'agit de PIC. Ainsi, aucune directive particulire n'est fournir pour la compilation. Pour l'dition de lien, des
options spcifiques sont fournir ld :
cc -c foo.c
ld -shared -expect_unresolved '*' -o foo.so foo.o
Une procdure identique doit tre employe dans le cas o GCC est utilis la place du compilateur du systme ; aucune option particulire n'est ncessaire.
UnixWare
L'option de compilation pour crer des PIC est -KPIC avec le compilateur SCO et -fpic avec GCC. Pour lier des bibliothques partages, les options respectives sont -G et -shared.
cc -K PIC -c foo.c
cc -G -o foo.so foo.o
ou
gcc -fpic -c foo.c
668

tendre SQL

gcc -shared -o foo.so foo.o

Astuce
Si cela s'vre trop compliqu, GNU Libtool peut tre utilis. Cet outil permet de s'affranchir des diffrences
entre les nombreux systmes au travers d'une interface uniformise.
La bibliothque partage rsultante peut tre charge dans PostgreSQL. Lorsque l'on prcise le nom du fichier dans la commande CREATE FUNCTION, il faut indiquer le nom de la bibliothque partage et non celui du fichier objet intermdiaire.
L'extension standard pour les bibliothques partages (en gnral .so ou .sl) peut tre omise dans la commande CREATE
FUNCTION, et doit l'tre pour une meilleure portabilit.
La Section 35.9.1, Chargement dynamique indique l'endroit o le serveur s'attend trouver les fichiers de bibliothques partages.

35.9.7. Arguments de type composite


Les types composites n'ont pas une organisation fixe comme les structures en C. Des instances d'un type composite peuvent contenir des champs NULL. De plus, les types composites faisant partie d'une hirarchie d'hritage peuvent avoir des champs diffrents
des autres membres de la mme hirarchie. En consquence, PostgreSQL propose une interface de fonction pour accder depuis
le C aux champs des types composites.
Supposons que nous voulions crire une fonction pour rpondre la requte :
SELECT nom, c_surpaye(emp, 1500) AS surpaye
FROM emp
WHERE nom = 'Bill' OR nom = 'Sam';
En utilisant les conventions d'appel de la version 0, nous pouvons dfinir c_surpaye comme :
#include "postgres.h"
#include "executor/executor.h"

/* pour GetAttributeByName() */

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
bool
c_surpaye(HeapTupleHeader *t, /* la ligne courante d'emp */
int32 limite)
{
bool isNULL;
int32 salaire;
salaire = DatumGetInt32(GetAttributeByName(t, "salaire", &isNULL));
if (isNULL)
return false;
return salaire > limite;
}
Dans le codage version-1, le code ci-dessus devient :
#include "postgres.h"
#include "executor/executor.h"

/* pour GetAttributeByName() */

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(c_surpaye);
Datum
c_surpaye(PG_FUNCTION_ARGS)
{
HeapTupleHeader *t = (HeapTupleHeader *) PG_GETARG_HEAPTUPLEHEADER(0);
int32
limite = PG_GETARG_INT32(1);
bool isNULL;
Datum salaire;
669

tendre SQL

salaire = GetAttributeByName(t, "salaire", &isNULL);


if (isNULL)
PG_RETURN_BOOL(false);
/* Autrement, nous pourrions prfrer de lancer PG_RETURN_NULL() pour un
salaire NULL.
*/
PG_RETURN_BOOL(DatumGetInt32(salaire) > limite);
}
GetAttributeByName est la fonction systme PostgreSQL qui renvoie les attributs depuis une colonne spcifie. Elle a
trois arguments : l'argument de type HeapTupleHeader pass la fonction, le nom de l'attribut recherch et un paramtre de retour
qui indique si l'attribut est NULL. GetAttributeByName renvoie une valeur de type Datum que vous pouvez convertir dans
un type voulu en utilisant la macro approprie DatumGetXXX(). Notez que la valeur de retour est insignifiante si le commutateur NULL est positionn ; il faut toujours vrifier le commutateur NULL avant de commencer faire quelque chose avec le rsultat.
Il y a aussi GetAttributeByNum, qui slectionne l'attribut cible par le numro de colonne au lieu de son nom.
La commande suivante dclare la fonction c_surpaye en SQL :
CREATE FUNCTION c_surpaye(emp, integer) RETURNS boolean
AS 'DIRECTORY/funcs', 'c_surpaye'
LANGUAGE C STRICT;
Notez que nous avons utilis STRICT pour que nous n'ayons pas vrifier si les arguments en entre sont NULL.

35.9.8. Renvoi de lignes (types composites)


Pour renvoyer une ligne ou une valeur de type composite partir d'une fonction en langage C, vous pouvez utiliser une API spciale qui fournit les macros et les fonctions dissimulant en grande partie la complexit lie la construction de types de donnes
composites. Pour utiliser cette API, le fichier source doit inclure :
#include "funcapi.h"
Il existe deux faons de construire une valeur de donnes composites (autrement dit un tuple ) : vous pouvez le construire
partir d'un tableau de valeurs Datum ou partir d'un tableau de chanes C qui peuvent passer dans les fonctions de conversion des
types de donnes du tuple. Quelque soit le cas, vous avez d'abord besoin d'obtenir et de construire un descripteur TupleDesc pour
la structure du tuple. En travaillant avec des Datums, vous passez le TupleDesc BlessTupleDesc, puis vous appelez
heap_form_tuple pour chaque ligne. En travaillant avec des chanes C, vous passez TupleDesc TupleDescGetAttInMetadata, puis vous appelez BuildTupleFromCStrings pour chaque ligne. Dans le cas d'une fonction renvoyant un ensemble de tuple, les tapes de configuration peuvent toutes tre entreprises une fois lors du premier appel la fonction.
Plusieurs fonctions d'aide sont disponibles pour configurer le TupleDesc requis. La faon recommande de le faire dans la plupart
des fonctions renvoyant des valeurs composites est d'appeler :
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,
Oid *resultTypeId,
TupleDesc *resultTupleDesc)
en passant la mme structure fcinfo que celle passe la fonction appelante (ceci requiert bien sr que vous utilisez les conventions d'appel version-1). resultTypeId peut tre spcifi comme NULL ou comme l'adresse d'une variable locale pour recevoir
l'OID du type de rsultat de la fonction. resultTupleDesc devrait tre l'adresse d'une variable TupleDesc locale. Vrifiez que
le rsultat est TYPEFUNC_COMPOSITE ; dans ce cas, resultTupleDesc a t rempli avec le TupleDesc requis (si ce n'est
pas le cas, vous pouvez rapporter une erreur pour une fonction renvoyant un enregistrement appel dans un contexte qui ne peut
pas accepter ce type enregistrement ).

Astuce
get_call_result_type peut rsoudre le vrai type du rsultat d'une fonction polymorphique ; donc, il est utile
pour les fonctions qui renvoient des rsultats scalaires polymorphiques, pas seulement les fonctions qui renvoient
des types composites. Le rsultat resultTypeId est principalement utile pour les fonctions renvoyant des scalaires polymorphiques.

Note
670

tendre SQL

get_call_result_type a une fonction cousine get_expr_result_type, qui peut tre utilise pour rsoudre le tupe attendu en sortie en un appel de fonction reprsent par un arbre d'expressions. Ceci peut tre utilis
pour tenter de dterminer le type de rsultat sans entrer dans la fonction elle-mme. Il existe aussi
get_func_result_type, qui peut seulement tre utilise quand l'OID de la fonction est disponible. Nanmoins, ces fonctions ne sont pas capables de grer les fonctions dclares renvoyer des enregistrements (record).
get_func_result_type ne peut pas rsoudre les types polymorphiques, donc vous devriez utiliser de prfrence get_call_result_type.
Les fonctions anciennes, et maintenant obsoltes, qui permettent d'obtenir des TupleDesc sont :
TupleDesc RelationNameGetTupleDesc(const char *relname)
pour obtenir un TupleDesc pour le type de ligne d'une relation nomme ou :
TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)
pour obtenir une TupleDesc base sur l'OID d'un type. Ceci peut tre utilis pour obtenir un TupleDesc soit pour un type de base,
soit pour un type composite. Nanmoins, cela ne fonctionnera pas pour une fonction qui renvoie record et cela ne rsoudra pas les
types polymorphiques.
Une fois que vous avez un TupleDesc, appelez :
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
si vous pensez travailler avec des Datums ou :
AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc)
si vous pensez travailler avec des chanes C. Si vous crivez une fonction renvoyant un ensemble, vous pouvez sauvegarder les rsultats de ces fonctions dans la structure dans le FuncCallContext -- utilisez le champ tuple_desc ou attinmeta respectivement.
Lorsque vous fonctionnez avec des Datums, utilisez :
HeapTuple heap_form_tuple(TupleDesc tupdesc, Datum *values, bool *isnull)
pour construire une donne utilisateur HeapTuple indique dans le format Datum.
Lorsque vous travaillez avec des chanes C, utilisez :
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
pour construire une donne utilisateur HeapTuple indique dans le format des chanes C. values est un tableau de chane C, une
pour chaque attribut de la ligne renvoye. Chaque chane C doit tre de la forme attendue par la fonction d'entre du type de donne de l'attribut. Afin de renvoyer une valeur NULL pour un des attributs, le pointeur correspondant dans le tableau de valeurs
(values) doit tre fix NULL. Cette fonction demandera tre appele pour chaque ligne que vous renvoyez.
Une fois que vous avez construit un tuple devant tre renvoy par votre fonction, vous devez le convertir en type Datum. Utilisez :
HeapTupleGetDatum(HeapTuple tuple)
pour convertir un type HeapTuple en un Datum valide. Ce Datum peut tre renvoy directement si vous envisagez de renvoyer
juste une simple ligne ou bien il peut tre utilis pour renvoyer la valeur courante dans une fonction renvoyant un ensemble.
Un exemple figure dans la section suivante.

35.9.9. Renvoi d'ensembles


Il existe aussi une API spciale procurant le moyen de renvoyer des ensembles (lignes multiples) depuis une fonction en langage
C. Une fonction renvoyant un ensemble doit suivre les conventions d'appel de la version-1. Aussi, les fichiers source doivent inclure l'en-tte funcapi.h, comme ci-dessus.
Une fonction renvoyant un ensemble (SRF : set returning function ) est appele une fois pour chaque lment qu'elle renvoie.
La SRF doit donc sauvegarder suffisamment l'tat pour se rappeler ce qu'elle tait en train de faire et renvoyer le prochain lment
chaque appel. La structure FuncCallContext est offerte pour assister le contrle de ce processus. l'intrieur d'une fonction,
fcinfo->flinfo->fn_extra est utilise pour conserver un pointeur vers FuncCallContext au cours des appels successifs.
typedef struct
{
/*
* Number of times we've been called before
*
671

tendre SQL

* call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and


* incremented for you every time SRF_RETURN_NEXT() is called.
*/
uint32 call_cntr;
/*
* OPTIONAL maximum number of calls
*
* max_calls is here for convenience only and setting it is optional.
* If not set, you must provide alternative means to know when the
* function is done.
*/
uint32 max_calls;
/*
* OPTIONAL pointer to result slot
*
* This is obsolete and only present for backwards compatibility, viz,
* user-defined SRFs that use the deprecated TupleDescGetSlot().
*/
TupleTableSlot *slot;
/*
* OPTIONAL pointer to miscellaneous user-provided context information
*
* user_fctx is for use as a pointer to your own data to retain
* arbitrary context information between calls of your function.
*/
void *user_fctx;
/*
* OPTIONAL pointer to struct containing attribute type input metadata
*
* attinmeta is for use when returning tuples (i.e., composite data types)
* and is not used when returning base data types. It is only needed
* if you intend to use BuildTupleFromCStrings() to create the return
* tuple.
*/
AttInMetadata *attinmeta;
/*
* memory context used for structures that must live for multiple calls
*
* multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
* by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
* context for any memory that is to be reused across multiple calls
* of the SRF.
*/
MemoryContext multi_call_memory_ctx;
/*
* OPTIONAL pointer to struct containing tuple description
*
* tuple_desc is for use when returning tuples (i.e. composite data types)
* and is only needed if you are going to build the tuples with
* heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that
* the TupleDesc pointer stored here should usually have been run through
* BlessTupleDesc() first.
*/
TupleDesc tuple_desc;
} FuncCallContext;
Une SRF utilise plusieurs fonctions et macros qui manipulent automatiquement la structure FuncCallContext (et s'attendent la
trouver via fn_extra). Utilisez :
SRF_IS_FIRSTCALL()
pour dterminer si votre fonction est appele pour la premire fois. Au premier appel, utilisez :
672

tendre SQL

SRF_FIRSTCALL_INIT()
pour initialiser la structure FuncCallContext. chaque appel de fonction, y compris le premier, utilisez :
SRF_PERCALL_SETUP()
pour une mise jour correcte en vue de l'utilisation de FuncCallContext et pour nettoyer toutes les donnes renvoyes prcdemment et conserves depuis le dernier passage de la fonction.
Si votre fonction a des donnes renvoyer, utilisez :
SRF_RETURN_NEXT(funcctx, result)
pour les renvoyer l'appelant. (result doit tre de type Datum, soit une valeur simple, soit un tuple prpar comme dcrit cidessus.) Enfin, quand votre fonction a fini de renvoyer des donnes, utilisez :
SRF_RETURN_DONE(funcctx)
pour nettoyer et terminer la SRF.
Lors de l'appel de la SRF, le contexte mmoire courant est un contexte transitoire qui est effac entre les appels. Cela signifie que
vous n'avez pas besoin d'appeler pfree sur tout ce que vous avez allou en utilisant palloc ; ce sera supprim de toute faon.
Toutefois, si vous voulez allouer des structures de donnes devant persister tout au long des appels, vous avez besoin de les
conserver quelque part. Le contexte mmoire rfrenc par multi_call_memory_ctx est un endroit appropri pour toute
donne devant survivre jusqu' l'achvement de la fonction SRF. Dans la plupart des cas, cela signifie que vous devrez basculer
vers multi_call_memory_ctx au moment de la prparation du premier appel.
Voici un exemple complet de pseudo-code :
Datum
my_set_returning_function(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum
result;
further declarations as needed
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcontext;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/* One-time setup code appears here: */
user code
if returning composite
build TupleDesc, and perhaps AttInMetadata
endif returning composite
user code
MemoryContextSwitchTo(oldcontext);
}
/* Each-time setup code appears here: */
user code
funcctx = SRF_PERCALL_SETUP();
user code
/* this is just one way we might test whether we are done: */
if (funcctx->call_cntr < funcctx->max_calls)
{
/* Here we want to return another item: */
user code
obtain result Datum
SRF_RETURN_NEXT(funcctx, result);
}
else
{
/* Here we are done returning items and just need to clean up: */
user code
SRF_RETURN_DONE(funcctx);
}
}

673

tendre SQL

Et voici un exemple complet d'une simple SRF retournant un type composite :


PG_FUNCTION_INFO_V1(retcomposite);
Datum
retcomposite(PG_FUNCTION_ARGS)
{
FuncCallContext
*funcctx;
int
call_cntr;
int
max_calls;
TupleDesc
tupdesc;
AttInMetadata
*attinmeta;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcontext;
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
/* switch to memory context appropriate for multiple function calls */
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/* total number of tuples to be returned */
funcctx->max_calls = PG_GETARG_UINT32(0);
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context "
"that cannot accept type record")));
/*
* generate attribute metadata needed later to produce tuples from raw
* C strings
*/
attinmeta = TupleDescGetAttInMetadata(tupdesc);
funcctx->attinmeta = attinmeta;
MemoryContextSwitchTo(oldcontext);
}
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
call_cntr = funcctx->call_cntr;
max_calls = funcctx->max_calls;
attinmeta = funcctx->attinmeta;
if (call_cntr < max_calls)
{
char
**values;
HeapTuple
tuple;
Datum
result;

/* do when there is more left to send */

/*
* Prepare a values array for building the returned tuple.
* This should be an array of C strings which will
* be processed later by the type input functions.
*/
values = (char **) palloc(3 * sizeof(char *));
values[0] = (char *) palloc(16 * sizeof(char));
values[1] = (char *) palloc(16 * sizeof(char));
values[2] = (char *) palloc(16 * sizeof(char));
snprintf(values[0], 16, "%d", 1 * PG_GETARG_INT32(1));
snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1));
snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1));
674

tendre SQL

/* build a tuple */
tuple = BuildTupleFromCStrings(attinmeta, values);
/* make the tuple into a datum */
result = HeapTupleGetDatum(tuple);
/* clean up (this is not really necessary) */
pfree(values[0]);
pfree(values[1]);
pfree(values[2]);
pfree(values);
SRF_RETURN_NEXT(funcctx, result);
}
else
{

/* do when there is no more left */


SRF_RETURN_DONE(funcctx);

}
}
Voici une faon de dclarer cette fonction en SQL :
CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer);
CREATE OR REPLACE FUNCTION retcomposite(integer, integer)
RETURNS SETOF __retcomposite
AS 'filename', 'retcomposite'
LANGUAGE C IMMUTABLE STRICT;
Une faon diffrente de le faire est d'utiliser des paramtres OUT :
CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,
OUT f1 integer, OUT f2 integer, OUT f3 integer)
RETURNS SETOF record
AS 'filename', 'retcomposite'
LANGUAGE C IMMUTABLE STRICT;
Notez que dans cette mthode le type en sortie de la fonction est du type record anonyme.
Le module contrib/tablefunc situ dans les fichiers source de la distribution contient d'autres exemples de fonctions renvoyant des
ensembles.

35.9.10. Arguments polymorphes et types renvoys


Les fonctions en langage C peuvent tre dclares pour accepter et renvoyer les types polymorphes anyelement, anyarray, anynonarray et anyenum. Voir la Section 35.2.5, Types et fonctions polymorphes pour une explication plus dtaille des fonctions
polymorphes. Si les types des arguments ou du renvoi de la fonction sont dfinis comme polymorphes, l'auteur de la fonction ne
peut pas savoir l'avance quel type de donnes sera appel ou bien quel type doit tre renvoy. Il y a deux routines offertes par
fmgr.h qui permettent une fonction en version-1 de dcouvrir les types de donnes effectifs de ses arguments et le type qu'elle
doit
renvoyer.
Ces
routines
s'appellent
get_fn_expr_rettype(FmgrInfo
*flinfo)
et
get_fn_expr_argtype(FmgrInfo *flinfo, int argnum). Elles renvoient l'OID du type du rsultat ou de
l'argument ou InvalidOID si l'information n'est pas disponible. L'accs la structure flinfo se fait normalement avec fcinfo>flinfo. Le paramtre argnum est bas partir de zro. get_call_result_type peut aussi tre utilis comme alternative
get_fn_expr_rettype.
Par exemple, supposons que nous voulions crire une fonction qui accepte un argument de n'importe quel type et qui renvoie un
tableau uni-dimensionnel de ce type :
PG_FUNCTION_INFO_V1(make_array);
Datum
make_array(PG_FUNCTION_ARGS)
{
ArrayType *result;
Oid
element_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
Datum
element;
bool
isnull;
int16
typlen;
bool
typbyval;
char
typalign;
675

tendre SQL

int
int
int

ndims;
dims[MAXDIM];
lbs[MAXDIM];

if (!OidIsValid(element_type))
elog(ERROR, "could not determine data type of input");
/* get the provided element, being careful in case it's NULL */
isnull = PG_ARGISNULL(0);
if (isnull)
element = (Datum) 0;
else
element = PG_GETARG_DATUM(0);
/* we have one dimension */
ndims = 1;
/* and one element */
dims[0] = 1;
/* and lower bound is 1 */
lbs[0] = 1;
/* get required info about the element type */
get_typlenbyvalalign(element_type, &typlen, &typbyval,
&typalign);
/* now build the array */
result = construct_md_array(&element, &isnull, ndims, dims, lbs,
element_type, typlen, typbyval, typalign);
PG_RETURN_ARRAYTYPE_P(result);
}
La commande suivante dclare la fonction make_array en SQL :
CREATE FUNCTION make_array(anyelement)
RETURNS anyarray
AS 'DIRECTORY/funcs', 'make_array'
LANGUAGE 'C' IMMUTABLE;
Notez l'utilisation de STRICT ; ceci est primordial car le code ne se proccupe pas de tester une entre NULL.
Il existe une variante du polymorphisme qui est seulement disponible pour les fonctions en langage C : elles peuvent tre dclares
prendre des paramtres de type "any". (Notez que ce nom de type doit tre plac entre des guillemets doubles car il s'agit d'un
mot SQL rserv.) Ceci fonctionne comme anyelement sauf qu'il ne contraint pas les diffrents arguments "any" tre du mme
type, pas plus qu'ils n'aident dterminer le type de rsultat de la fonction. Une fonction en langage C peut aussi dclarer son paramtre final ainsi : VARIADIC "any". Cela correspondra un ou plusieurs arguments rels de tout type (pas ncessairement le
mme type). Ces arguments ne seront pas placs dans un tableau comme c'est le cas pour les fonctions variadic normales ; ils seront passs sparment la fonction. La macro PG_NARGS() et les mthodes dcrites ci-dessus doivent tre utilises pour dterminer le nombre d'arguments rels et leur type lors de l'utilisation de cette fonctionnalit.

35.9.11. Mmoire partage et LWLocks


Les modules peuvent rserver des LWLocks et allouer de la mmoire partage au lancement du serveur. La bibliothque partage
du module doit tre prcharge en l'ajoutant shared_preload_libraries. La mmoire partage est rserve en appelant :
void RequestAddinShmemSpace(int size)
partir de votre fonction _PG_init.
Les LWLocks sont rservs en appelant :
void RequestAddinLWLocks(int n)
partir de _PG_init.
Pour viter des cas rares possibles, chaque moteur devrait utiliser la fonction AddinShmemInitLock lors de la connexion et de
l'initialisation de la mmoire partage, comme indique ci-dessous :
static mystruct *ptr = NULL;
676

tendre SQL

if (!ptr)
{
bool

found;

LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
ptr = ShmemInitStruct("my struct name", size, &found);
if (!found)
{
initialize contents of shmem area;
acquire any requested LWLocks using:
ptr->mylockid = LWLockAssign();
}
LWLockRelease(AddinShmemInitLock);
}

35.9.12. Coder des extensions en C++


Bien que le moteur PostgreSQL soit crit en C, il est possible de coder des extensions en C++ si les lignes de conduite suivantes
sont respectes :

Toutes les fonctions accessibles par le serveur doivent prsenter une interface en C ; seules ces fonctions C pourront alors appeler du code C++. Ainsi, l'dition de liens extern C est ncessaire pour les fonctions appeles par le serveur. Ceci est galement obligatoire pour toutes les fonctions passes comme pointeur entre le serveur et du code C++.

Librez la mmoire en utilisant la mthode de dsallocation approprie. Par exemple, la majeure partie de la mmoire alloue
par le serveur l'est par appel de la fonction palloc(), aussi, il convient de librer ces zones mmoire en utilisant la fonction
pfree(). L'utilisation de la fonction C++ delete chouerait pour ces blocs de mmoire.

vitez la propagation d'exceptions dans le code C (utilisez un bloc catch-all au niveau le plus haut de toute fonction extern
C. Ceci est ncessaire, mme si le code C++ n'met explicitement aucune exception, dans la mesure o la survenue
d'vnements tels qu'un manque de mmoire peut toujours lancer une exception. Toutes les exceptions devront tre gres et
les erreurs correspondantes transmises via l'interface du code C. Si possible, compilez le code C++ avec l'option fno-exceptions afin d'liminer entirement la venue d'exceptions ; dans ce cas, vous devrez effectuer vous-mme les vrifications correspondantes dans votre code C++, par exemple, vrifier les ventuels paramtres NULL retourns par la fonction new().

Si vous appelez des fonctions du serveur depuis du code C++, assurez vous que la pile d'appels ne contienne que des structures
C (POD). Ceci est ncessaire dans la mesure o les erreurs au niveau du serveur gnrent un saut via l'instruction longjmp() qui ne peut dpiler proprement une pile d'appels C++ comportant des objets non-POD.

Pour rsumer, le code C++ doit donc tre plac derrire un rempart de fonctions extern C qui fourniront l'interface avec le serveur, et devra viter toute fuite de mcanismes propres au C++ (exceptions, allocation/libration de mmoire et objets non-POD
dans la pile).

35.10. Agrgats utilisateur


Dans PostgreSQL, les fonctions d'agrgat sont exprimes comme des valeurs d'tat et des fonctions de transition d'tat.
C'est--dire qu'un agrgat opre en utilisant une valeur d'tat qui est mis jour chaque ligne traite. Pour dfinir une nouvelle
fonction d'agrgat, on choisit un type de donne pour la valeur d'tat, une valeur initiale pour l'tat et une fonction de transition
d'tat. La fonction de transition d'tat est une fonction ordinaire qui peut tre utilise hors agrgat. Une fonction finale peut galement tre spcifie pour le cas o le rsultat dsir comme agrgat est diffrent des donnes conserves comme valeur d'tat courant.
Ainsi, en plus des types de donnes d'argument et de rsultat vus par l'utilisateur, il existe un type de donnes pour la valeur d'tat
interne qui peut tre diffrent des deux autres.
Un agrgat qui n'utilise pas de fonction finale est un agrgat qui utilise pour chaque ligne une fonction dpendante des valeurs de
colonnes. sum en est un exemple. sum dbute zro et ajoute la valeur de la ligne courante son total en cours. Par exemple,
pour obtenir un agrgat sum qui opre sur un type de donnes nombres complexes, il suffira dcrire la fonction d'addition pour ce
type de donne. La dfinition de l'agrgat sera :
CREATE AGGREGATE somme (complex)
(
sfunc = ajout_complexe,
stype = complexe,
677

tendre SQL

initcond = '(0,0)'
);
SELECT somme(a) FROM test_complexe;
somme
----------(34,53.9)
(Notez que nous nous reposons sur une surcharge de fonction : il existe plus d'un agrgat nomm sum mais PostgreSQL trouve
le type de somme s'appliquant une colonne de type complex.)
La dfinition prcdente de sum retournera zro (la condition d'tat initial) s'il n'y a que des valeurs d'entre NULL. Dans ce cas,
on peut souhaiter qu' elle retourne NULL -- le standard SQL prvoit que la fonction sum se comporte ainsi. Cela peut tre obtenu
par l'omission de l'instruction initcond, de sorte que la condition d'tat initial soit NULL. Dans ce cas, sfunc vrifie l'entre
d'une condition d'tat NULL mais, pour sum et quelques autres agrgats simples comme max et min, il suffit d'insrer la premire
valeur d'entre non NULL dans la variable d'tat et d'appliquer la fonction de transition d'tat partir de la seconde valeur non
NULL. PostgreSQL fait cela automatiquement si la condition initiale est NULL et si la fonction de transition est marque
strict (elle n'est pas appele pour les entres NULL).
Par dfaut galement, pour les fonctions de transition strict , la valeur d'tat prcdente reste inchange pour une entre NULL.
Les valeurs NULL sont ainsi ignores. Pour obtenir un autre comportement, il suffit de ne pas dclarer la fonction de transition
strict . la place, codez-la de faon ce qu'elle vrifie et traite les entres NULL.
avg (average = moyenne) est un exemple plus complexe d'agrgat. Il demande deux tats courants : la somme des entres et le
nombre d'entres. Le rsultat final est obtenu en divisant ces quantits. La moyenne est typiquement implante en utilisant comme
valeur d'tat un tableau. Par exemple, l'implmentation intgre de avg(float8) ressemble :
CREATE AGGREGATE avg (float8)
(
sfunc = float8_accum,
stype = float8[],
finalfunc = float8_avg,
initcond = '{0,0,0}'
);
(float8_accum ncessite un tableau trois lments, et non pas seulement deux, car il accumule la somme des carrs, ainsi que
la somme et le nombre des entres. Cela permet son utilisation pour d'autres agrgats que avg.)
Les fonctions d'agrgat peuvent utiliser des fonctions d'tat transitionnelles ou des fonctions finales polymorphes. De cette faon,
les mmes fonctions peuvent tre utilises pour de multiples agrgats. Voir la Section 35.2.5, Types et fonctions polymorphes
pour une explication des fonctions polymorphes. La fonction d'agrgat elle-mme peut tre spcifie avec un type de base et des
types d'tat polymorphes, ce qui permet ainsi une unique dfinition de fonction de servir pour de multiples types de donnes en
entre. Voici un exemple d'agrgat polymorphe :
CREATE AGGREGATE array_accum (anyelement)
(
sfunc = array_append,
stype = anyarray,
initcond = '{}'
);
Dans ce cas, le type d'tat effectif pour tout appel d'agrgat est le type tableau avec comme lments le type effectif d'entre. Le
comportement de l'agrgat est de concatner toutes les entres dans un tableau de ce type. (Note : l'agrgat array_agg fournit
une fonctionnalit similaire, avec de meilleures performances que ne pourrait avoir cette dfinition.)
Voici le rsultat pour deux types de donnes diffrents en arguments :
SELECT attrelid::regclass, array_accum(attname)
FROM pg_attribute WHERE attnum > 0
AND attrelid = 'pg_tablespace'::regclass GROUP BY attrelid;
attrelid
|
array_accum
---------------+--------------------------------------pg_tablespace | {spcname,spcowner,spclocation,spcacl}
(1 row)
SELECT attrelid::regclass, array_accum(atttypid::regtype)
FROM pg_attribute
WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass
GROUP BY attrelid;
678

tendre SQL

attrelid
|
array_accum
---------------+--------------------------pg_tablespace | {name,oid,text,aclitem[]}
(1 row)
Une fonction crite en C peut dtecter si elle est appele en tant que fonction de transition ou en tant que fonction finale d'un agrgat en appelant AggCheckCallContext, par exemple :
if (AggCheckCallContext(fcinfo, NULL))
Une raison de surveiller ceci est que, si le retour de cette fonction vaut true pour une fonction de transition, la premire valeur doit
tre une valeur de transition temporaire et peut du coup tre modifie en toute sret sans avoir allouer une nouvelle copie. Voir
int8inc() pour un exemple. (C'est le seul cas o une fonction peut modifier en toute scurit un argument pass en rfrence.
En particulier, les fonctions finales d'agrgat ne doivent pas modifier leur arguments dans tous les cas car, dans certains cas, elles
seront r-excutes sur la mme valeur de transition finale.)
Pour de plus amples dtails, on se rfrera la commande CREATE AGGREGATE(7).

35.11. Types utilisateur


Comme cela est dcrit dans la Section 35.2, Le systme des types de PostgreSQL , PostgreSQL peut tre tendu pour supporter de nouveaux types de donnes. Cette section dcrit la dfinition de nouveaux types basiques. Ces types de donnes sont dfinis en-dessous du SQL. Crer un nouveau type requiert d'implanter des fonctions dans un langage de bas niveau, gnralement le
C.
Les exemples de cette section sont disponibles dans complex.sql et complex.c du rpertoire src/tutorial de la distribution. Voir le fichier README de ce rpertoire pour les instructions d'excution des exemples.
Un type utilisateur doit toujours possder des fonctions d'entre et de sortie. Ces fonctions dterminent la prsentation du type en
chanes de caractres (pour la saisie par l'utilisateur et le renvoi l'utilisateur) et son organisation en mmoire. La fonction d'entre
prend comme argument une chane de caractres termine par NULL et retourne la reprsentation interne (en mmoire) du type.
La fonction de sortie prend en argument la reprsentation interne du type et retourne une chane de caractres termine par NULL.
Il est possible de faire plus que stocker un type, mais il faut pour cela implanter des fonctions supplmentaires grant les oprations souhaites.
Soit le cas d'un type complex reprsentant les nombres complexes. Une faon naturelle de reprsenter un nombre complexe en
mmoire passe par la structure C suivante :
typedef struct Complex {
double
x;
double
y;
} Complex;
Ce type ne pouvant tenir sur une simple valeur Datum, il sera pass par rfrence.
La reprsentation externe du type se fera sous la forme de la chane (x,y).
En gnral, les fonctions d'entre et de sortie ne sont pas compliques crire, particulirement la fonction de sortie. Mais lors de
la dfinition de la reprsentation externe du type par une chane de caractres, il faudra peut-tre crire un analyseur complet et robuste, comme fonction d'entre, pour cette reprsentation. Par exemple :
PG_FUNCTION_INFO_V1(complex_in);
Datum
complex_in(PG_FUNCTION_ARGS)
{
char
*str = PG_GETARG_CSTRING(0);
double
x,
y;
Complex
*result;
if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for complex: \"%s\"",
str)));
result = (Complex *) palloc(sizeof(Complex));
679

tendre SQL

result->x = x;
result->y = y;
PG_RETURN_POINTER(result);
}
La fonction de sortie peut s'crire simplement :
PG_FUNCTION_INFO_V1(complex_out);
Datum
complex_out(PG_FUNCTION_ARGS)
{
Complex
*complex = (Complex *) PG_GETARG_POINTER(0);
char
*result;
result = (char *) palloc(100);
snprintf(result, 100, "(%g,%g)", complex->x, complex->y);
PG_RETURN_CSTRING(result);
}
Il est particulirement important de veiller ce que les fonctions d'entre et de sortie soient bien inverses l'une par rapport
l'autre. Dans le cas contraire, de grosses difficults pourraient apparatre lors de la sauvegarde de la base dans un fichier en vue
d'une future relecture de ce fichier. Ceci est un problme particulirement frquent lorsque des nombres virgule flottante entrent
en jeu.
De manire optionnelle, un type utilisateur peut fournir des routines d'entre et de sortie binaires. Les entres/sorties binaires sont
normalement plus rapides mais moins portables que les entres/sorties textuelles. Comme avec les entres/sorties textuelles, c'est
l'utilisateur qui dfinit prcisment la reprsentation binaire externe. La plupart des types de donnes intgrs tentent de fournir
une reprsentation binaire indpendante de la machine. Dans le cas du type complex, des convertisseurs d'entres/sorties binaires
pour le type float8 sont utiliss :
PG_FUNCTION_INFO_V1(complex_recv);
Datum
complex_recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
Complex
*result;
result = (Complex *) palloc(sizeof(Complex));
result->x = pq_getmsgfloat8(buf);
result->y = pq_getmsgfloat8(buf);
PG_RETURN_POINTER(result);
}
PG_FUNCTION_INFO_V1(complex_send);
Datum
complex_send(PG_FUNCTION_ARGS)
{
Complex
*complex = (Complex *) PG_GETARG_POINTER(0);
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendfloat8(&buf, complex->x);
pq_sendfloat8(&buf, complex->y);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
Lorsque les fonctions d'entre/sortie sont crites et compiles en une bibliothque partage, le type complex peut tre dfini en
SQL. Tout d'abord, il est dclar comme un type shell :
CREATE TYPE complex;
Ceci sert de paramtre qui permet de mettre en rfrence le type pendant la dfinition de ses fonctions E/S. Les fonctions E/S
peuvent alors tre dfinies :
CREATE FUNCTION complex_in(cstring)
RETURNS complex
AS 'filename'
680

tendre SQL

LANGUAGE C IMMUTABLE STRICT;


CREATE FUNCTION complex_out(complex)
RETURNS cstring
AS 'filename'
LANGUAGE C IMMUTABLE STRICT;
CREATE FUNCTION complex_recv(internal)
RETURNS complex
AS 'filename'
LANGUAGE C IMMUTABLE STRICT;
CREATE FUNCTION complex_send(complex)
RETURNS bytea
AS 'filename'
LANGUAGE C IMMUTABLE STRICT;
La dfinition du type de donnes peut ensuite tre fournie compltement :
CREATE TYPE complex (
internallength = 16,
input = complex_in,
output = complex_out,
receive = complex_recv,
send = complex_send,
alignment = double
);
Quand un nouveau type de base est dfini, PostgreSQL fournit automatiquement le support pour des tableaux de ce type. Le
type tableau a habituellement le nom du type de base prfix par un caractre soulign (_).
Lorsque le type de donnes existe, il est possible de dclarer les fonctions supplmentaires de dfinition des oprations utiles pour
ce type. Les oprateurs peuvent alors tre dfinis par dessus ces fonctions et, si ncessaire, des classes d'oprateurs peuvent tre
cres pour le support de l'indexage du type de donnes. Ces couches supplmentaires sont discutes dans les sections suivantes.
Si les valeurs du type de donnes varient en taille (sous la forme interne), le type de donnes doit tre marqu comme TOASTable (voir Section 55.2, TOAST ). Vous devez le faire mme si les donnes sont trop petites pour tre compresses ou stockes
en externe car TOAST peut aussi gagner de la place sur des petites donnes en rduisant la surcharge de l'en-tte.
Pour cela, la reprsentation interne doit suivre la disposition standard pour les donnes de longueur variable : les quatre premiers
octets doivent tre un champ char[4] dont l'accs n'est jamais direct (appel vl_len_). Vous devez utiliser SET_VARSIZE()
pour stocker la taille du datum dans ce champ et VARSIZE() pour le rcuprer. Les fonctions C oprant sur ce type de donnes
doivent toujours faire attention dballer toutes valeurs TOAST qu'elles rcuprent en utilisant PG_DETOAST_DATUM (ce dtail
est habituellement cach en dfinissant des macros GETARG_DATATYPE_P spcifiques au type). Ensuite, lors de l'excution de
la commande CREATE TYPE, prcisez la longueur interne comme variable et slectionnez l'option de stockage appropri.
Si l'alignement n'est pas important (soit seulement pour une fonction spcifique soit parce que le type de donnes spcifie un alignement par octet), alors il est possible d'viter PG_DETOAST_DATUM. Vous pouvez utiliser PG_DETOAST_DATUM_PACKED
la place (habituellement cach par une macro GETARG_DATATYPE_PP) et utiliser les macros VARSIZE_ANY_EXHDR et VARDATA_ANY pour accder un datum potentiellement packag. Encore une fois, les donnes renvoyes par ces macros ne sont pas
alignes mme si la dfinition du type de donnes indique un alignement. Si l'alignement est important pour vous, vous devez passer par l'interface habituelle, PG_DETOAST_DATUM.

Note
Un ancien code dclare frquemment vl_len_ comme un champ de type int32 au lieu de char[4]. C'est correct
tant que la dfinition de la structure a d'autres champs qui ont au moins un alignement int32. Mais il est dangereux
d'utiliser une telle dfinition de structure en travaillant avec un datum potentiellement mal align ; le compilateur
peut le prendre comme une indication pour supposer que le datum est en fait align, ceci amenant des core dump
sur des architectures qui sont strictes sur l'alignement.
Pour plus de dtails, voir la description de la commande CREATE TYPE(7).

35.12. Oprateurs dfinis par l'utilisateur


chaque oprateur est un sucre syntaxique pour l'appel d'une fonction sous-jacente qui effectue le vritable travail ; aussi devezvous en premier lieu crer cette fonction avant de pouvoir crer l'oprateur. Toutefois, un oprateur n'est pas simplement un
681

tendre SQL

sucre syntaxique car il apporte des informations supplmentaires qui aident le planificateur de requte optimiser les requtes
utilises par l'oprateur. La prochaine section est consacre l'explication de ces informations additionnelles.
postgresql accepte les oprateurs unaire gauche, unaire droit et binaire. Les oprateurs peuvent tre surchargs ; c'est--dire que
le mme nom d'oprateur peut tre utilis pour diffrents oprateurs condition qu'ils aient des nombres et des types diffrents
d'oprandes. Quand une requte est excute, le systme dtermine l'oprateur appeler en fonction du nombre et des types
d'oprandes fournis.
Voici un exemple de cration d'oprateur pour l'addition de deux nombres complexes. Nous supposons avoir dj cr la dfinition du type complex (voir la Section 35.11, Types utilisateur ). premirement, nous avons besoin d'une fonction qui fasse le
travail, ensuite nous pouvons dfinir l'oprateur :
CREATE FUNCTION complex_add(complex, complex)
RETURNS complex
AS 'filename', 'complex_add'
LANGUAGE C;
CREATE OPERATOR + ( leftarg = complex, rightarg = complex, procedure =
complex_add, commutator = + );
Maintenant nous pouvons excuter la requte comme ceci :
SELECT (a + b) AS c FROM test_complex;
c
----------------(5.2,6.05)
(133.42,144.95)
Nous avons montr comment crer un oprateur binaire. Pour crer des oprateurs unaires, il suffit d'omettre un des leftarg
(pour un oprateur unaire gauche) ou rightarg (pour un oprateur unaire droit). La clause procedure et les clauses argument
sont les seuls lments requis dans la commande create operator. la clause commutator montre dans l'exemple est une indication optionnelle pour l'optimiseur de requte. Des dtails supplmentaires sur la clause commutator et d'autres complments
d'optimisation sont donns dans la prochaine section.

35.13. Informations sur l'optimisation d'un oprateur


Une dfinition d'oprateur PostgreSQL peut inclure plusieurs clauses optionnelles qui donnent au systme des informations
utiles sur le comportement de l'oprateur. Ces clauses devraient tre fournies chaque fois que c'est utile car elles peuvent considrablement acclrer l'excution des requtes utilisant cet oprateur. Mais si vous le faites, vous devez tre sr de leur justesse !
L'usage incorrect d'une clause d'optimisation peut tre la cause de requtes lentes, des sorties subtilement fausses ou d'autres effets
pervers. Vous pouvez toujours abandonner une clause d'optimisation si vous n'tes pas sr d'elle ; la seule consquence est un possible ralentissement des requtes.
Des clauses additionnelles d'optimisation pourront tre ajoutes dans les futures versions de postgresql. celles dcrites ici sont
toutes celles que cette version comprend.

35.13.1. COMMUTATOR
Si elle est fournie, la clause commutator dsigne un oprateur qui est le commutateur de l'oprateur en cours de dfinition.
Nous disons qu'un oprateur A est le commutateur de l'oprateur B si (x A y) est gal (y B x) pour toute valeur possible de x, y.
Notez que B est aussi le commutateur de A. Par exemple, les oprateurs < et > pour un type particulier de donnes sont habituellement des commutateurs l'un pour l'autre, et l'oprateur + est habituellement commutatif avec lui-mme. Mais l'oprateur - n'est
habituellement commutatif avec rien.
Le type de l'oprande gauche d'un oprateur commut est le mme que l'oprande droit de son commutateur, et vice versa. Aussi
postgresql n'a besoin que du nom de l'oprateur commutateur pour consulter le commutateur, et c'est tout ce qui doit tre fourni
la clause commutator .
Vous avez juste dfinir un oprateur auto-commutateur. Mais les choses sont un peu plus compliques quand vous dfinissez
une paire de commutateurs : comment peut-on dfinir la rfrence du premier au second alors que ce dernier n'est pas encore dfini ? Il y a deux solutions ce problme :

Une faon d'oprer est d'omettre la clause commutator dans le premier oprateur que vous dfinissez et ensuite d'en insrer
une dans la dfinition du second oprateur. Puisque postgresql sait que les oprateurs commutatifs vont par paire, quand il
voit la seconde dfinition, il retourne instantanment remplir la clause commutator manquante dans la premire dfinition.

L'autre faon, plus directe, est de simplement inclure les clauses commutator dans les deux dfinitions. quand postgresql
682

tendre SQL

traite la premire dfinition et ralise que la clause commutator se rfre un oprateur inexistant, le systme va crer une
entre provisoire pour cet oprateur dans le catalogue systme. Cette entre sera pourvue seulement de donnes valides pour le
nom de l'oprateur, les types d'oprande droit et gauche et le type du rsultat, puisque c'est tout ce que postgresql peut dduire ce point. la premire entre du catalogue pour l'oprateur sera lie cette entre provisoire. Plus tard, quand vous dfinirez le second oprateur, le systme mettra jour l'entre provisoire avec les informations additionnelles fournies par la seconde dfinition. Si vous essayez d'utiliser l'oprateur provisoire avant qu'il ne soit complt, vous aurez juste un message
d'erreur.

35.13.2. NEGATOR
La clause negator dnomme un oprateur qui est l'oprateur de ngation de l'oprateur en cours de dfinition. Nous disons
qu'un oprateur A est l'oprateur de ngation de l'oprateur B si tous les deux renvoient des rsultats boolens et si (x A y) est gal
NOT (x B y) pour toutes les entres possible x, y. Notez que B est aussi l'oprateur de ngation de A. Par exemple, < et >=
forment une paire d'oprateurs de ngation pour la plupart des types de donnes. Un oprateur ne peut jamais tre valid comme
son propre oprateur de ngation .
Au contraire des commutateurs, une paire d'oprateurs unaires peut tre valide comme une paire d'oprateurs de ngation rciproques ; ce qui signifie que (A x) est gal NOT (B x) pour tout x ou l'quivalent pour les oprateurs unaires droite.
L'oprateur de ngation d'un oprateur doit avoir les mmes types d'oprandes gauche et/ou droit que l'oprateur dfinir comme
avec commutator. seul le nom de l'oprateur doit tre donn dans la clause negator.
Dfinir un oprateur de ngation est trs utile pour l'optimiseur de requtes car il permet de simplifier des expressions telles que
not (x = y) en x <> y. ceci arrive souvent parce que les oprations not peuvent tre insres la suite d'autres rarrangements.
Des paires d'oprateurs de ngation peuvent tre dfinies en utilisant la mme mthode que pour les commutateurs.

35.13.3. RESTRICT
La clause restrict, si elle est invoque, nomme une fonction d'estimation de slectivit de restriction pour cet oprateur (notez
que c'est un nom de fonction, et non pas un nom d'oprateur). Les clauses restrict n'ont de sens que pour les oprateurs binaires qui renvoient un type boolean. un estimateur de slectivit de restriction repose sur l'ide de prvoir quelle fraction des
lignes dans une table satisfera une condition de clause where de la forme :
colonne OP constante
pour l'oprateur courant et une valeur constante particulire. Ceci aide l'optimiseur en lui donnant une ide du nombre de lignes
qui sera limin par les clauses where qui ont cette forme (vous pouvez vous demander, qu'arrivera-t-il si la constante est
gauche ? h bien, c'est une des choses laquelle sert le commutator...).
L'criture de nouvelles fonctions d'estimation de restriction de slectivit est loigne des objectifs de ce chapitre mais, heureusement, vous pouvez habituellement utiliser un des estimateurs standards du systme pour beaucoup de vos propres oprateurs. Voici les estimateurs standards de restriction :
eqsel pour =
neqsel pour <>
scalarltsel pour < ou <=
scalargtsel pour > ou >=
Ces catgories peuvent sembler un peu curieuses mais cela prend un sens si vous y rflchissez. = acceptera typiquement une petite fraction des lignes d'une table ; <> rejettera typiquement seulement une petite fraction des lignes de la table. < acceptera une
fraction des lignes en fonction de la situation de la constante donne dans la gamme de valeurs de la colonne pour cette table (ce
qui est justement l'information collecte par la commande analyze et rendue disponible pour l'estimateur de slectivit). <= acceptera une fraction lgrement plus grande que < pour la mme constante de comparaison mais elles sont assez proches pour ne pas
valoir la peine d'tre distingues puisque nous ne risquons pas de toute faon de faire mieux qu'une grossire estimation. La mme
remarque s'applique > et >=.
Vous pouvez frquemment vous en sortir bon compte en utilisant soit eqsel ou neqsel pour des oprateurs qui ont une trs
grande ou une trs faible slectivit, mme s'ils ne sont pas rellement galit ou ingalit. Par exemple, les oprateurs gomtriques d'galit approche utilisent eqsel en supposant habituellement qu'ils ne correspondent qu' une petite fraction des entres dans une table.
Vous pouvez utiliser scalarltsel et scalargtsel pour des comparaisons de types de donnes qui possdent un moyen de
conversion en scalaires numriques pour les comparaisons de rang. Si possible, ajoutez le type de donnes ceux accepts par la
fonction convert_to_scalar() dans src/backend/utils/adt/selfuncs.c (finalement, cette fonction devrait tre
remplace par des fonctions pour chaque type de donnes identifi grce une colonne du catalogue systme pg_type ; mais cela n'a pas encore t fait). si vous ne faites pas ceci, les choses fonctionneront mais les estimations de l'optimiseur ne seront pas
683

tendre SQL

aussi bonnes qu'elles pourraient l'tre.


D'autres fonctions d'estimation de slectivit conues pour les oprateurs gomtriques sont places dans src/backend/utils/adt/geo_selfuncs.c : areasel, positionsel et contsel. lors de cette rdaction, ce sont seulement des fragments mais vous pouvez vouloir les utiliser (ou mieux les amliorer).

35.13.4. JOIN
La clause join, si elle est invoque, nomme une fonction d'estimation de slectivit de jointure pour l'oprateur (notez que c'est
un nom de fonction, et non pas un nom d'oprateur). Les clauses join n'ont de sens que pour les oprateurs binaires qui renvoient
un type boolean. un estimateur de slectivit de jointure repose sur l'ide de prvoir quelle fraction des lignes dans une paire de
tables satisfera une condition de clause where de la forme :
table1.colonne1 OP table2.colonne2
pour l'oprateur courant. Comme pour la clause restrict, ceci aide considrablement l'optimiseur en lui indiquant parmi plusieurs squences de jointure possibles laquelle prendra vraisemblablement le moins de travail.
Comme prcdemment, ce chapitre n'essaiera pas d'expliquer comment crire une fonction d'estimation de slectivit de jointure
mais suggrera simplement d'utiliser un des estimateurs standard s'il est applicable :
eqjoinsel pour =
neqjoinsel pour <>
scalarltjoinsel pour < ou <=
scalargtjoinsel pour > ou >=
areajoinsel pour des comparaisons bases sur une aire 2d
positionjoinsel pour des comparaisons bases sur une position 2d
contjoinsel pour des comparaisons bases sur un appartenance 2d

35.13.5. HASHES
La clause hashes indique au systme qu'il est permis d'utiliser la mthode de jointure-dcoupage pour une jointure base sur cet
oprateur. hashes n'a de sens que pour un oprateur binaire qui renvoie un boolean et en pratique l'oprateur galit doit reprsenter l'galit pour certains types de donnes ou paire de type de donnes.
La jointure-dcoupage repose sur l'hypothse que l'oprateur de jointure peut seulement renvoyer la valeur vrai pour des paires de
valeurs droite et gauche qui correspondent au mme code de dcoupage. Si deux valeurs sont places dans deux diffrents paquets
( buckets ), la jointure ne pourra jamais les comparer avec la supposition implicite que le rsultat de l'oprateur de jointure doit
tre faux. Ainsi, il n'y a aucun sens spcifier hashes pour des oprateurs qui ne reprsentent pas une certaine forme d'galit.
Dans la plupart des cas, il est seulement pratique de supporter le hachage pour les oprateurs qui prennent le mme type de donnes sur chaque ct. Nanmoins, quelque fois, il est possible de concevoir des fonctions de hachage compatibles pour deux type
de donnes, voire plus ; c'est--dire pour les fonctions qui gnreront les mmes codes de hachage pour des valeurs gales mme
si elles ont des reprsentations diffrentes. Par exemple, il est assez simple d'arranger cette proprit lors du hachage d'entiers de
largeurs diffrentes.
Pour tre marqu hashes, l'oprateur de jointure doit apparatre dans une famille d'oprateurs d'index de dcoupage. Ceci n'est
pas rendu obligatoire quand vous crez l'oprateur, puisque videmment la classe rfrenant l'oprateur peut ne pas encore exister. Mais les tentatives d'utilisation de l'oprateur dans les jointure-dcoupage choueront l'excution si une telle famille
d'oprateur n'existe pas. Le systme a besoin de la famille d'oprateur pour dfinir la fonction de dcoupage spcifique au type de
donnes d'entre de l'oprateur. Bien sr, vous devez galement crer des fonctions de dcoupage appropries avant de pouvoir
crer la famille d'oprateur.
On doit apporter une grande attention la prparation des fonctions de dcoupage parce qu'il y a des processus dpendants de la
machine qui peuvent ne pas faire les choses correctement. Par exemple, si votre type de donnes est une structure dans laquelle
peuvent se trouver des bits de remplissage sans intrt, vous ne pouvez pas simplement passer la structure complte la fonction
hash_any ( moins d'crire vos autres oprateurs et fonctions de faon s'assurer que les bits inutiliss sont toujours zro, ce qui
est la stratgie recommande). Un autre exemple est fourni sur les machines qui respectent le standard de virgule-flottante ieee, le
zro ngatif et le zro positif sont des valeurs diffrentes (les motifs de bit sont diffrents) mais ils sont dfinis pour tre gaux. Si
une valeur flottante peut contenir un zro ngatif, alors une tape supplmentaire est ncessaire pour s'assurer qu'elle gnre la
mme valeur de dcoupage qu'un zro positif.
Un oprateur joignable par hachage doit avoir un commutateur (lui-mme si les types de donnes des deux oprandes sont identiques, ou un oprateur d'galit relatif dans le cas contraire) qui apparat dans la mme famille d'oprateur. Si ce n'est pas le cas,
des erreurs du planificateur pourraient apparatre quand l'oprateur est utilis. De plus, une bonne ide (mais pas obligatoire) est
qu'une famille d'oprateur de hachage supporte les tupes de donnes multiples pour fournir des oprateurs d'galit pour chaque
combinaison des types de donnes ; cela permet une meilleure optimisation.

684

tendre SQL

Note
La fonction sous-jacente un oprateur de jointure-dcoupage doit tre marque immuable ou stable. Si elle est volatile, le systme n'essaiera jamais d'utiliser l'oprateur pour une jointure hachage.

Note
Si un oprateur de jointure-hachage a une fonction sous-jacente marque stricte, la fonction doit galement tre
complte : cela signifie qu'elle doit renvoyer TRUE ou FALSE, jamais NULL, pour n'importe quelle double entre
non NULL. Si cette rgle n'est pas respecte, l'optimisation de dcoupage des oprations in peut gnrer des rsultats faux (spcifiquement, in devrait renvoyer false quand la rponse correcte devrait tre NULL ; ou bien il devrait renvoyer une erreur indiquant qu'il ne s'attendait pas un rsultat NULL).

35.13.6. MERGES
La clause merges, si elle est prsente, indique au systme qu'il est permis d'utiliser la mthode de jointure-union pour une jointure base sur cet oprateur. merges n'a de sens que pour un oprateur binaire qui renvoie un boolean et, en pratique, cet oprateur doit reprsenter l'galit pour des types de donnes ou des paires de types de donnes.
La jointure-union est fonde sur le principe d'ordonner les tables gauche et droite et ensuite de les comparer en parallle. Ainsi, les
deux types de donnes doivent tre capable d'tre pleinement ordonnes, et l'oprateur de jointure doit pouvoir russir seulement
pour des paires de valeurs tombant la mme place dans l'ordre de tri. En pratique, cela signifie que l'oprateur de jointure
doit se comporter comme l'oprateur galit. Mais il est possible de faire une jointure-union sur deux types de donnes distincts
tant qu'ils sont logiquement compatibles. Par exemple, l'oprateur d'galit smallint-contre-integer est susceptible d'oprer une
jointure-union. Nous avons seulement besoin d'oprateurs de tri qui organisent les deux types de donnes en squences logiquement comparables.
Pour tre marqu MERGES, l'oprateur de jointure doit apparatre en tant que membre d'galit d'une famille oprateur d'index
btree. Ceci n'est pas forc quand vous crez l'oprateur puisque, bien sr, la famille d'oprateur rfrente n'existe pas encore.
Mais l'oprateur ne sera pas utilis pour les jointures de fusion sauf si une famille d'oprateur correspondante est trouve. L'option
MERGES agit en fait comme une aide pour le planificateur lui indiquant qu'il est intressant de chercher une famille d'oprateur
correspondant.
Un oprateur joignable par fusion doit avoir un commutateur (lui-mme si les types de donnes des deux oprateurs sont identiques, ou un oprateur d'galit en relation dans le cas contraire) qui apparatdans la mme famille d'oprateur. Si ce n'est pas le
cas, des erreurs du planificateur pourraient apparatre quand l'oprateur est utilis. De plus, une bonne ide (mais pas obligatoire)
est qu'une famille d'oprateur de hachage supporte les tupes de donnes multiples pour fournir des oprateurs d'galit pour
chaque combinaison des types de donnes ; cela permet une meilleure optimisation.

Note
La fonction sous-jacente un oprateur de jointure-union doit tre marque immuable ou stable. Si elle est volatile,
le systme n'essaiera jamais d'utiliser l'oprateur pour une jointure union.

35.14. Interfacer des extensions d'index


Les procdures dcrites jusqu' maintenant permettent de dfinir de nouveaux types, de nouvelles fonctions et de nouveaux oprateurs. Nanmoins, nous ne pouvons pas encore dfinir un index sur une colonne d'un nouveau type de donnes. Pour cela, nous devons dfinir une classe d'oprateur pour le nouveau type de donnes. Plus loin dans cette section, nous illustrerons ce concept
avec un exemple : une nouvelle classe d'oprateur pour la mthode d'indexation B-tree qui enregistre et trie des nombres complexes dans l'ordre ascendant des valeurs absolues.
Les classes d'oprateur peuvent tre groupes en familles d'oprateur pour afficher les relations entre classes compatibles smantiquement. Quand un seul type de donnes est impliqu, une classe d'oprateur est suffisant, donc nous allons nous fixer sur ce cas
en premier puis retourner aux familles d'oprateur.

35.14.1. Mthodes d'indexation et classes d'oprateurs


La table pg_am contient une ligne pour chaque mthode d'indexation (connue en interne comme mthode d'accs). Le support
pour l'accs normal aux tables est implment dans PostgreSQL mais toutes les mthodes d'index sont dcrites dans pg_am. Il
est possible d'ajouter une nouvelle mthode d'indexation en dfinissant les routines d'interface ncessaires et en crant ensuite une
ligne dans la table pg_am -- mais ceci est au-del du sujet de ce chapitre (voir le Chapitre 52, Dfinition de l'interface des m685

tendre SQL

thodes d'accs aux index).


Les routines pour une mthode d'indexation n'ont pas connatre directement les types de donnes sur lesquels opre la mthode
d'indexation. Au lieu de cela, une classe d'oprateur identifie l'ensemble d'oprations que la mthode d'indexation doit utiliser
pour fonctionner avec un type particulier de donnes. Les classes d'oprateurs sont ainsi dnommes parce qu'une de leur tche est
de spcifier l'ensemble des oprateurs de la clause WHERE utilisables avec un index (c'est--dire, qui peuvent tre requalifis en
balayage d'index). Une classe d'oprateur peut galement spcifier des procdures d'appui, ncessaires pour les oprations internes de la mthode d'indexation mais sans correspondance directe avec un quelconque oprateur de clause WHERE pouvant tre
utilis avec l'index.
Il est possible de dfinir plusieurs classes d'oprateurs pour le mme type de donnes et la mme mthode d'indexation. Ainsi, de
multiples ensembles de smantiques d'indexation peuvent tre dfinis pour un seul type de donnes. Par exemple, un index B-tree
exige qu'un tri ordonn soit dfini pour chaque type de donnes auquel il peut s'appliquer. Il peut tre utile pour un type de donne
de nombre complexe de disposer d'une classe d'oprateur B-tree qui trie les donnes selon la valeur absolue complexe, une autre
selon la partie relle, etc. Typiquement, une des classes d'oprateur sera considre comme plus utile et sera marque comme
l'oprateur par dfaut pour ce type de donnes et cette mthode d'indexation.
Le mme nom de classe d'oprateur peut tre utilis pour plusieurs mthodes d'indexation diffrentes (par exemple, les mthodes
d'index B-tree et hash ont toutes les deux des classes d'oprateur nommes int4_ops) mais chacune de ces classes est une entit
indpendante et doit tre dfinie sparment.

35.14.2. Stratgies des mthode d'indexation


Les oprateurs associs une classe d'oprateur sont identifis par des numros de stratgie , servant identifier la smantique
de chaque oprateur dans le contexte de sa classe d'oprateur. Par exemple, les B-trees imposent un classement strict selon les
cls, du plus petit au plus grand. Ainsi, des oprateurs comme plus petit que et plus grand que sont intressants pour un Btree. Comme PostgreSQL permet l'utilisateur de dfinir des oprateurs, PostgreSQL ne peut pas rechercher le nom d'un oprateur (par exemple, < ou >=) et rapporter de quelle comparaison il s'agit. Au lieu de cela, la mthode d'indexation dfinit un ensemble de stratgies , qui peuvent tre comprises comme des oprateurs gnraliss. Chaque classe d'oprateur spcifie
l'oprateur effectif correspondant chaque stratgie pour un type de donne particulier et pour une interprtation de la smantique
d'index.
La mthode d'indexation B-tree dfinit cinq stratgies, qui sont exposes dans le Tableau 35.2, Stratgies B-tree .
Tableau 35.2. Stratgies B-tree

Opration

Numro de stratgie

plus petit que

plus petit ou gal

gal

plus grand ou gal

plus grand que

Les index de dcoupage permettent seulement des comparaisons d'galit et utilisent ainsi une seule stratgie expose dans le Tableau 35.3, Stratgies de dcoupage .
Tableau 35.3. Stratgies de dcoupage

Opration

Numro de stratgie

gal

Les index GiST sont plus flexibles : ils n'ont pas du tout un ensemble fixe de stratgies. la place, la routine de support de
cohrence de chaque classe d'oprateur GiST interprte les numros de stratgie comme elle l'entend. Comme exemple, plusieurs des classes d'oprateurs GiST indexe les objets gomtriques deux dimensions fournissant les stratgies R-tree affiches dans Tableau 35.4, Stratgies R-tree pour GiST deux dimensions . Quatre d'entre elles sont des vrais tests deux dimensions (surcharge, identique, contient, contenu par) ; quatre autres considrent seulement la direction X ; et les quatre dernires
fournissent les mmes tests dans la direction Y.
Tableau 35.4. Stratgies R-tree pour GiST deux dimensions

686

tendre SQL

Opration

Numro de stratgie

strictement gauche de

ne s'tend pas droite de

surcharge

ne s'tend pas gauche de

strictement droite de

identique

contient

contenu par

ne s'tend pas au dessus

strictement en dessous

10

strictement au dessus

11

ne s'tend pas en dessous

12

Les index GIN sont similaires aux index GiST en flexibilit : ils n'ont pas un ensemble fixe de stratgie. la place, les routines de
support de chaque classe d'oprateur interprtent les numros de stratgie suivant la dfinition du classe d'oprateur. Comme
exemple, les numros des stratgies utiliss par les classes d'oprateur sur des tableaux sont affichs dans Tableau 35.5,
Stratgies des tableaux GIN .
Tableau 35.5. Stratgies des tableaux GIN

Opration

Numro de stratgie

surcharge

contient

est contenu par

identique

Notez que tous les oprateurs ci-dessus renvoient des valeurs de type boolen. Dans la pratique, tous les oprateurs dfinis comme
index method search operators doivent renvoyer un type boolean puisqu'ils doivent apparatre au plus haut niveau d'une clause
WHERE pour tre utiliss avec un index. (Some index access methods also support ordering operators, which typically don't return
Boolean values; that feature is discussed in Section 35.14.7, Ordering Operators .)

35.14.3. Routines d'appui des mthodes d'indexation


Gnralement, les stratgies n'apportent pas assez d'informations au systme pour indiquer comment utiliser un index. Dans la pratique, les mthodes d'indexation demandent des routines d'appui additionnelles pour fonctionner. Par exemple, les mthodes
d'index B-tree doivent tre capables de comparer deux cls et de dterminer laquelle est suprieure, gale ou infrieure l'autre.
De la mme faon, la mthode d'indexation hash doit tre capable de calculer les codes de hachage pour les valeurs de cls. Ces
oprations ne correspondent pas des oprateurs utiliss dans les commandes SQL ; ce sont des routines administratives utilises
en interne par des mthodes d'index.
Comme pour les stratgies, la classe d'oprateur numre les fonctions spcifiques et le rle qu'elles doivent jouer pour un type de
donne donn et une interprtation smantique donne. La mthode d'indexation dfinit l'ensemble des fonctions dont elle a besoin et la classe d'oprateur identifie les fonctions exactes utiliser en les assignant aux numros de fonction d'appui spcifis
par la mthode d'indexage.
Les B-trees demandent une seule fonction d'appui, expose dans le Tableau 35.6, Fonctions d'appui de B-tree .
Tableau 35.6. Fonctions d'appui de B-tree

Fonction

Numro d'appui

Comparer deux cls et renvoyer un entier infrieur zro, zro 1


ou suprieure zro indiquant si la premire cl est infrieure,
gale ou suprieure la deuxime.

687

tendre SQL

De faon identique, les index de dcoupage requirent une fonction d'appui expose dans le Tableau 35.7, Fonctions d'appui
pour dcoupage .
Tableau 35.7. Fonctions d'appui pour dcoupage

Fonction

Numro d'appui

Calculer la valeur de dcoupage pour une cl

Les index GiST requirent sept fonctions d'appui, with an optional eighth, exposes dans le Tableau 35.8, Fonctions d'appui
pour GiST .
Tableau 35.8. Fonctions d'appui pour GiST

Fonction

Description

Numro d'appui

consistent

dtermine si la cl satisfait le qualifiant de 1


la requte

union

calcule l'union d'un ensemble de cls

compress

calcule une reprsentation compresse 3


d'une cl ou d'une valeur indexer

decompress

calcule une reprsentation dcompresse 4


d'une cl compresse

penalty

calcule la pnalit pour l'insertion d'une 5


nouvelle cl dans un sous-arbre avec la
cl du sous-arbre indiqu

picksplit

dtermine les entres d'une page qui sont 6


dplacer vers la nouvelle page et calcule
les cls d'union pour les pages rsultantes

equal

compare deux cls et renvoie true si elles 7


sont identiques

distance

(optional method) determine distance 8


from key to query value

Les index GIN requirent quatre fonctions d'appui, with an optional fifth, exposes dans le Tableau 35.9, Fonctions d'appui
GIN .
Tableau 35.9. Fonctions d'appui GIN

Fonction

Description

compare

Compare deux cls et renvoie un entier plus petit que zro, zro
ou plus grand que zro, indiquant si la premire cl est plus petit, gal ou plus grand que la seconde.

extractValue

Extrait les cls partir d'une condition de requte

extractQuery

Extrait les cls partir d'une condition de requte

consistent

Dtermine la valeur correspondant la condition de requte

comparePartial

(mthode optionnelle) compare la cl partielle de la requte et la


cl de l'index, et renvoie un entier ngatif, nul ou positif, indiquant si GIN doit ignorer cette entre d'index, traiter l'entre
comme une correspondance ou arrer le parcours d'index

Contrairement aux oprateurs de recherche, les fonctions d'appui renvoient le type de donne, quelqu'il soit, que la mthode
d'indexation particulire attend, par exemple, dans le cas de la fonction de comparaison des B-trees, un entier sign. Le nombre et
le type des arguments pour chaque fonction de support peuvent dpendre de la mthode d'indexage. Pour les B-tree et les hash, les
fonctions de support prennent les mme types de donnes en entre comme le font les oprateurs incluant dans la classe
d'oprateur, bien que ce ne soit pas le cas pour la plupart des fonctions de support GIN et GiST.
688

tendre SQL

35.14.4. Exemple
Maintenant que nous avons vu les ides, voici l'exemple promis de cration d'une nouvelle classe d'oprateur. Cette classe
d'oprateur encapsule les oprateurs qui trient les nombres complexes selon l'ordre de la valeur absolue, aussi avons-nous choisi le
nom de complex_abs_ops. En premier lieu, nous avons besoin d'un ensemble d'oprateurs. La procdure pour dfinir des oprateurs a t discute dans la Section 35.12, Oprateurs dfinis par l'utilisateur . Pour une classe d'oprateur sur les B-trees,
nous avons besoin des oprateurs :

valeur absolue less-than (stratgie 1) ;


valeur absolue less-than-or-equal (stratgie 2) ;
valeur absolue equal (stratgie 3) ;
valeur absolue greater-than-or-equal (stratgie 4) ;
valeur absolue greater-than (stratgie 5) ;

Le plus simple moyen de dfinie un ensemble d'oprateurs de comparaison est d'crire en premier la fonction de comparaison Btree, puis d'crire les autres fonctions en tant que wrapper de la fonction de support. Ceci rduit les risques de rsultats incohrents
pour les cas spcifiques. En suivant cette approche, nous devons tout d'abord crire :
#define Mag(c)

((c)->x*(c)->x + (c)->y*(c)->y)

static int
complex_abs_cmp_internal(Complex *a, Complex *b)
{
double
amag = Mag(a),
bmag = Mag(b);
if (amag <
return
if (amag >
return
return 0;

bmag)
-1;
bmag)
1;

}
Maintenant, la fonction plus-petit-que ressemble ceci :
PG_FUNCTION_INFO_V1(complex_abs_lt);
Datum
complex_abs_lt(PG_FUNCTION_ARGS)
{
Complex
*a = (Complex *) PG_GETARG_POINTER(0);
Complex
*b = (Complex *) PG_GETARG_POINTER(1);
PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0);
}
Les quatre autres fonctions diffrent seulement sur la faon dont ils comparent le rsultat de la fonction interne au zro.
Maintenant, dclarons en SQL les fonctions et les oprateurs bass sur ces fonctions :
CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool
AS 'nom_fichier', 'complex_abs_lt'
LANGUAGE C IMMUTABLE STRICT;
CREATE OPERATOR < (
leftarg = complex, rightarg = complex, procedure = complex_abs_lt,
commutator = > , negator = >= ,
restrict = scalarltsel, join = scalarltjoinsel
);
Il est important de spcifier les fonctions de slectivit de restriction et de jointure, sinon l'optimiseur sera incapable de faire un
usage effectif de l'index. Notez que les cas 'less-than', 'equal' et 'greater-than' doivent utiliser des fonctions diffrentes de slectivit.
Voici d'autres choses importantes noter :

Il ne peut y avoir qu'un seul oprateur nomm, disons, = et acceptant un type complex pour ses deux oprandes. Dans le cas
prsent, nous n'avons aucun autre oprateur = pour complex mais, si nous construisons un type de donne fonctionnel, nous
689

tendre SQL

aurions certainement dsir que = soit l'opration ordinaire d'galit pour les nombres complexes (et non pour l'galit de leurs
valeurs absolues). Dans ce cas, nous aurions eu besoin d'utiliser un autre nom d'oprateur pour notre fonction complex_abs_eq.

Bien que PostgreSQL puisse se dbrouiller avec des fonctions ayant le mme nom SQL, tant qu'elles ont en argument des
types de donnes diffrents, en C il ne peut exister qu'une fonction globale pour un nom donn. Aussi ne devons-nous pas donner un nom simple comme abs_eq. Habituellement, inclure le nom du type de donnes dans le nom de la fonction C est une
bonne habitude pour ne pas provoquer de conflit avec des fonctions pour d'autres types de donne.

Nous aurions pu faire de abs_eq le nom SQL de la fonction, en laissant PostgreSQL le soin de la distinguer de toute
autre fonction SQL de mme nom par les types de donnes en argument. Pour la simplicit de l'exemple, nous donnerons la
fonction le mme nom au niveau de C et au niveau de SQL.

La prochaine tape est l'enregistrement de la routine d'appui ncessaire pour les B-trees. Le code exemple C qui implmente ceci
est dans le mme fichier qui contient les fonctions d'oprateur. Voici comment dclarer la fonction :
CREATE FUNCTION complex_abs_cmp(complex, complex)
RETURNS integer
AS 'filename'
LANGUAGE C;
Maintenant que nous avons les oprateurs requis et la routine d'appui, nous pouvons enfin crer la classe d'oprateur.
CREATE OPERATOR CLASS complex_abs_ops
DEFAULT FOR TYPE complex USING btree AS
OPERATOR
1
< ,
OPERATOR
2
<= ,
OPERATOR
3
= ,
OPERATOR
4
>= ,
OPERATOR
5
> ,
FUNCTION
1
complex_abs_cmp(complex, complex);
Et c'est fait ! Il devrait tre possible maintenant de crer et d'utiliser les index B-tree sur les colonnes complex.
Nous aurions pu crire les entres de l'oprateur de faon plus explicite comme dans :
OPERATOR

< (complex, complex) ,

mais il n'y a pas besoin de faire ainsi quand les oprateurs prennent le mme type de donne que celui pour lequel la classe
d'oprateur a t dfinie.
Les exemples ci-dessus supposent que vous voulez que cette nouvelle classe d'oprateur soit la classe d'oprateur B-tree par dfaut
pour le type de donne complex. Si vous ne voulez pas, supprimez simplement le mot DEFAULT.

35.14.5. Classes et familles d'oprateur


Jusqu' maintenant, nous avons suppos implicitement qu'une classe d'oprateur s'occupe d'un seul type de donnes. Bien qu'il ne
peut y avoir qu'un seul type de donnes dans une colonne d'index particulire, il est souvent utile d'indexer les oprations qui comparent une colonne indexe une valeur d'un type de donnes diffrent. De plus, s'il est intressant d'utiliser un oprateur intertype en connexion avec une classe d'oprateur, souvent cet autre type de donne a sa propre classe d'oprateur. Rendre explicite
les connexions entre classes en relation est d'une grande aide pour que le planificateur optimise les requtes SQL (tout particulirement pour les classes d'oprateur B-tree car le planificateur sait bien comme les utiliser).
Pour grer ces besoins, PostgreSQL utilise le concept d'une famille d'oprateur . Une famille d'oprateur contient une ou plusieurs classes d'oprateur et peut aussi contenir des oprateurs indexables et les fonctions de support correspondantes appartenant
la famille entire mais pas une classe particulire de la famille. Nous disons que ces oprateurs et fonctions sont lches
l'intrieur de la famille, en opposition tre li une classe spcifique. Typiquement, chaque classe d'oprateur contient des oprateurs de types de donnes simples alors que les oprateurs inter-type sont lches dans la famille.
Tous les oprateurs et fonctions d'une famille d'oprateurs doivent avoir une smantique compatible o les pr-requis de la compatibilit sont dicts par la mthode indexage. Du coup, vous pouvez vous demander la raison pour s'embarrasser de distinguer les
sous-ensembles de la famille en tant que classes d'oprateur. En fait, dans beaucoup de cas, les divisions en classe sont inutiles et
la famille est le seul groupe intressant. La raison de la dfinition de classes d'oprateurs est qu'ils spcifient quel point la famille
est ncessaire pour supporter un index particulier. S'il existe un index utilisant une classe d'oprateur, alors cette classe d'oprateur
ne peut pas tre supprime sans supprimer l'index -- mais les autres parties de la famille d'oprateurs, donc les autres classes et les
oprateurs lches, peuvent tre supprimes. Du coup, une classe d'oprateur doit tre indique pour contenir l'ensemble minimum
d'oprateurs et de fonctions qui sont raisonnablement ncessaire pour travailler avec un index sur un type de donnes spcifique,
690

tendre SQL

et ensuite les oprateurs en relation mais peuvent tre ajouts en tant que membres lches de la famille d'oprateur.
Comme exemple, PostgreSQL a une famille d'oprateur B-tree interne integer_ops, qui inclut les classes d'oprateurs
int8_ops, int4_ops et int2_ops pour les index sur les colonnes bigint (int8), integer (int4) et smallint (int2) respectivement. La famille contient aussi des oprateurs de comparaison inter-type permettant la comparaison de deux de ces types, pour
qu'un index parmi ces types puisse tre parcouru en utilisant une valeur de comparaison d'un autre type. La famille peut tre dupliqu par ces dfinitions :
CREATE OPERATOR FAMILY integer_ops USING btree;
CREATE OPERATOR CLASS int8_ops
DEFAULT FOR TYPE int8 USING btree FAMILY integer_ops AS
-- comparaisons int8 standard
OPERATOR 1 < ,
OPERATOR 2 <= ,
OPERATOR 3 = ,
OPERATOR 4 >= ,
OPERATOR 5 > ,
FUNCTION 1 btint8cmp(int8, int8) ;
CREATE OPERATOR CLASS int4_ops
DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS
-- comparaisons int4 standard
OPERATOR 1 < ,
OPERATOR 2 <= ,
OPERATOR 3 = ,
OPERATOR 4 >= ,
OPERATOR 5 > ,
FUNCTION 1 btint4cmp(int4, int4) ;
CREATE OPERATOR CLASS int2_ops
DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS
-- comparaisons int2 standard
OPERATOR 1 < ,
OPERATOR 2 <= ,
OPERATOR 3 = ,
OPERATOR 4 >= ,
OPERATOR 5 > ,
FUNCTION 1 btint2cmp(int2, int2) ;
ALTER OPERATOR FAMILY integer_ops USING btree ADD
-- comparaisons inter-types int8 vs int2
OPERATOR 1 < (int8, int2) ,
OPERATOR 2 <= (int8, int2) ,
OPERATOR 3 = (int8, int2) ,
OPERATOR 4 >= (int8, int2) ,
OPERATOR 5 > (int8, int2) ,
FUNCTION 1 btint82cmp(int8, int2) ,
-- comparaisons inter-types int8 vs int4
OPERATOR 1 < (int8, int4) ,
OPERATOR 2 <= (int8, int4) ,
OPERATOR 3 = (int8, int4) ,
OPERATOR 4 >= (int8, int4) ,
OPERATOR 5 > (int8, int4) ,
FUNCTION 1 btint84cmp(int8, int4) ,
-- comparaisons inter-types int4 vs int2
OPERATOR 1 < (int4, int2) ,
OPERATOR 2 <= (int4, int2) ,
OPERATOR 3 = (int4, int2) ,
OPERATOR 4 >= (int4, int2) ,
OPERATOR 5 > (int4, int2) ,
FUNCTION 1 btint42cmp(int4, int2) ,
-- comparaisons inter-types int4 vs int8
OPERATOR 1 < (int4, int8) ,
OPERATOR 2 <= (int4, int8) ,
OPERATOR 3 = (int4, int8) ,
691

tendre SQL

OPERATOR 4 >= (int4, int8) ,


OPERATOR 5 > (int4, int8) ,
FUNCTION 1 btint48cmp(int4, int8) ,
-- comparaisons inter-types int2 vs int8
OPERATOR 1 < (int2, int8) ,
OPERATOR 2 <= (int2, int8) ,
OPERATOR 3 = (int2, int8) ,
OPERATOR 4 >= (int2, int8) ,
OPERATOR 5 > (int2, int8) ,
FUNCTION 1 btint28cmp(int2, int8) ,
-- comparaisons inter-types int2 vs int4
OPERATOR 1 < (int2, int4) ,
OPERATOR 2 <= (int2, int4) ,
OPERATOR 3 = (int2, int4) ,
OPERATOR 4 >= (int2, int4) ,
OPERATOR 5 > (int2, int4) ,
FUNCTION 1 btint24cmp(int2, int4) ;
Notez que cette dfinition surcharge la stratgie de l'oprateur et les numros de fonction support : chaque numro survient
plusieurs fois dans la famille. Ceci est autoris aussi longtemps que chaque instance d'un numro particulier a des types de donnes distincts en entre. Les instances qui ont les deux types en entre galent au type en entre de la classe d'oprateur sont les
oprateurs primaires et les fonctions de support pour cette classe d'oprateur et, dans la plupart des cas, doivent tre dclares
comme membre de la classe d'oprateur plutt qu'en tant que membres lches de la famille.
Dans une famille d'oprateur B-tree, tous les oprateurs de la famille doivent trier de faon compatible, ceci signifiant ques les lois
transitives tiennent parmi tous les types de donnes supports par la famille : if A = B and B = C, then A = C et if A < B and
B < C, then A < C . Pour chaque oprateur de la famille, il doit y avoir une fonction de support pour les deux mmes types de
donnes en entre que celui de l'oprateur. Il est recommand qu'une famille soit complte, c'est--dire que pour chaque combinaison de types de donnes, tous les oprateurs sont inclus. Chaque classe d'oprateur doit juste inclure les oprateurs non inter-types
et les fonctions de support pour ce type de donnes.
Pour construire une famille d'oprateurs de hachage pour plusieurs types de donnes, des fonctions de support de hachage compatibles doivent tre cres pour chaque type de donnes support par la famille. Ici, compatibilit signifie que les fonctions sont garanties de renvoyer le mme code de hachage pour toutes les paires de valeurs qui sont considres gales par les oprateurs
d'galit de la famille, mme quand les valeurs sont de type diffrent. Ceci est habituellement difficile accomplir quand les types
ont diffrentes reprsentations physiques, mais cela peut se faire dans la plupart des cas. Notez qu'il y a seulement une fonction de
support par type de donnes, pas une par oprateur d'galit. Il est recommand qu'une famille soit termine, c'est--dire fournit un
oprateur d'galit pour chaque combinaison de types de donnes. Chaque classe d'oprateur doit inclure l'oprateur d'galit non
inter-type et la fonction de support pour ce type de donnes.
Les index GIN et GiST n'ont pas de notion explicite d'oprations inter-types. L'ensemble des oprateurs supports est simplement
ce que les fonctions de support primaire peuvent supporter pour un oprateur donn.

Note
Avant PostgreSQL 8.3, le concept des familles d'oprateurs n'existait pas. Donc, tous les oprateurs inter-type
dont le but tait d'tre utiliss avec un index taient lis directement la classe d'oprateur de l'index. Bien que
cette approche fonctionne toujours, elle est obsolte car elle rend trop importantes les dpendances de l'index et
parce que le planificateur peut grer des comparaisons inter-type avec plus d'efficacit que quand les typdes de
donnes ont des oprateurs dans la mme famille d'oprateur.

35.14.6. Dpendances du systme pour les classes d'oprateur


PostgreSQL utilise les classe d'oprateur pour infrer les proprits des oprateurs de plusieurs autres faons que le seul usage
avec les index. Donc, vous pouvez crer des classes d'oprateur mme si vous n'avez pas l'intention d'indexer une quelconque colonne de votre type de donne.
En particulier, il existe des caractristiques de SQL telles que ORDER BY et DISTINCT qui requirent la comparaison et le tri
des valeurs. Pour implmenter ces caractristiques sur un type de donne dfini par l'utilisateur, PostgreSQL recherche la classe
d'oprateur B-tree par dfaut pour le type de donne. Le membre equals de cette classe d'oprateur dfinit pour le systme la
notion d'galit des valeurs pour GROUP BY et DISTINCT, et le tri ordonn impos par la classe d'oprateur dfinit le ORDER
BY par dfaut.
La comparaison des tableaux de types dfinis par l'utilisateur repose sur les smantiques dfinies par la classe d'oprateur B-tree
692

tendre SQL

par dfaut.
S'il n'y a pas de classe d'oprateur B-tree par dfaut pour le type de donne, le systme cherchera une classe d'oprateur de dcoupage. Mais puisque cette classe d'oprateur ne fournit que l'galit, c'est en pratique seulement suffisant pour tablir l'galit de tableau.
Quand il n'y a pas de classe d'oprateur par dfaut pour un type de donne, vous obtenez des erreurs telles que could not identify
an ordering operator si vous essayez d'utiliser ces caractristiques SQL avec le type de donne.

Note
Dans les versions de PostgreSQL antrieures la 7.4, les oprations de tri et de groupement utilisaient implicitement les oprateurs nomms =, < et >. Le nouveau comportement qui repose sur les classes d'oprateurs par dfaut
vite d'avoir faire une quelconque supposition sur le comportement des oprateurs avec des noms particuliers.
Un autre point important est qu'un oprateur apparaissant dans une famille d'oprateur de hachage est un candidat pour les jointures de hachage, les agrgations de hachage et les optimisations relatives. La famille d'oprateur de hachage est essentiel ici car
elle identifie le(s) fonction(s) de hachage utiliser.

35.14.7. Ordering Operators


Some index access methods (currently, only GiST) support the concept of ordering operators. What we have been discussing so
far are search operators. A search operator is one for which the index can be searched to find all rows satisfying WHERE indexed_column operator constant. Note that nothing is promised about the order in which the matching rows will be returned. In contrast, an ordering operator does not restrict the set of rows that can be returned, but instead determines their order.
An ordering operator is one for which the index can be scanned to return rows in the order represented by ORDER BY indexed_column operator constant. The reason for defining ordering operators that way is that it supports nearest-neighbor searches, if the operator is one that measures distance. For example, a query like
SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
finds the ten places closest to a given target point. A GiST index on the location column can do this efficiently because <-> is an
ordering operator.
While search operators have to return Boolean results, ordering operators usually return some other type, such as float or numeric
for distances. This type is normally not the same as the data type being indexed. To avoid hard-wiring assumptions about the behavior of different data types, the definition of an ordering operator is required to name a B-tree operator family that specifies the
sort ordering of the result data type. As was stated in the previous section, B-tree operator families define PostgreSQL's notion
of ordering, so this is a natural representation. Since the point <-> operator returns float8, it could be specified in an operator
class creation command like this:
OPERATOR 15

<-> (point, point) FOR ORDER BY float_ops

where float_ops is the built-in operator family that includes operations on float8. This declaration states that the index is able
to return rows in order of increasing values of the <-> operator.

35.14.8. Caractristiques spciales des classes d'oprateur


Il y a deux caractristiques spciales des classes d'oprateur dont nous n'avons pas encore parles, essentiellement parce qu'elles
ne sont pas utiles avec les mthodes d'index les plus communment utilises.
Normalement, dclarer un oprateur comme membre d'une classe ou d'une famille d'oprateur signifie que la mthode
d'indexation peut retrouver exactement l'ensemble de lignes qui satisfait la condition WHERE utilisant cet oprateur. Par exemple :
SELECT * FROM table WHERE colonne_entier < 4;
peut tre accompli exactement par un index B-tree sur la colonne entire. Mais il y a des cas o un index est utile comme un guide
inexact vers la colonne correspondante. Par exemple, si un index GiST enregistre seulement les rectangles limite des objets gomtriques, alors il ne peut pas exactement satisfaire une condition WHERE qui teste le chevauchement entre des objets non rectangulaires comme des polygones. Cependant, nous pourrions utiliser l'index pour trouver des objets dont les rectangles limites chevauchent les limites de l'objet cible. Dans ce cas, l'index est dit tre perte pour l'oprateur. Les recherches par index perte sont
implmentes en ayant une mthode d'indexage qui renvoie un drapeau recheck quand une ligne pourrait ou non satisfaire la
condition de la requte. Le systme principal testera ensuite la condition originale de la requte sur la ligne rcupre pour
s'assurer que la correspondance est relle. Cette approche fonctionne si l'index garantit de renvoyer toutes les lignes requises, ainsi
693

tendre SQL

que quelques lignes supplmentaires qui pourront tre limines par la vrification. Les mthodes d'indexage qui supportent les recherches perte (actuellement GiST et GIN) permettent aux fonctions de support des classes individuelles d'oprateurs de lever le
drapeau recheck, et donc c'est essentiellement une fonctionnalit pour les classes d'oprateur.
Considrons nouveau la situation o nous gardons seulement dans l'index le rectangle dlimitant un objet complexe comme un
polygone. Dans ce cas, il n'est pas trs intressant de conserver le polygone entier dans l'index - nous pouvons aussi bien conserver
seulement un objet simple du type box. Cette situation est exprime par l'option STORAGE dans la commande CREATE OPERATOR CLASS : nous aurons crire quelque chose comme :
CREATE OPERATOR CLASS polygon_ops
DEFAULT FOR TYPE polygon USING gist AS
...
STORAGE box;
Actuellement, seule les mthodes d'indexation GIN et GiST supportent un type STORAGE qui soit diffrent du type de donne de
la colonne. Les routines d'appui de GiST pour la compression (compress) et la dcompression (decompress) doivent
s'occuper de la conversion du type de donne quand STORAGE est utilis. Avec GIN, le type STORAGE identifie le type des valeurs key , qui est normalement diffrent du type de la colonne indexe -- par exemple, une classe d'oprateur pour des colonnes de tableaux d'entiers pourrait avoir des cls qui sont seulement des entiers. Les routines de support GIN extractValue
et extractQuery sont responsables de l'extraction des cls partir des valeurs indexes.

35.15. Empaqueter des objets dans une extension


Les extensions utiles PostgreSQL contiennent gnralement plusieurs objets SQL. Par exemple, un nouveau type de donnes
va ncessiter de nouvelles fonctions, de nouveaux oprateurs et probablement de nouvelles mthodes d'indexation. Il peut tre
utile de les grouper en un unique paquetage pour simplifier la gestion des bases de donnes. Avec PostgreSQL, ces paquetages
sont appels extension. Pour crer une extension, vous avez besoin au minimum d'un fichier de script qui contient les commandes
SQL permettant de crer ses objets, et un fichier de contrle qui rapporte quelques proprits de base de cette extension. Si cette
extension inclut du code C, elle sera aussi gnralement accompagne d'une bibliothque dans lequel le code C aura t compil.
Une fois ces fichiers en votre possession, un simple appel la commande CREATE EXTENSION(7) vous permettra de charger
ses objets dans la base de donnes.
Le principal avantage des extensions n'est toutefois pas de pouvoir de charger une grande quantit d'objets dans votre base de donne. Les extensions permettent en effet surtout PostgreSQL de comprendre que ces objets sont lis par cette extension. Vous
pouvez par exemple supprimer tous ces objets avec une simple commande DROP EXTENSION(7). Il n'est ainsi pas ncessaire de
maintenir un script de dsintallation . Plus utile encore, l'outil pg_dump saura reconnatre les objets appartenant une extension
et, plutt que de les extraire individuellement, ajoutera simplement une commande CREATE EXTENSION la sauvegarde. Ce
mcanisme simplifie aussi la migration une nouvelle version de l'extension qui peut contenir de nouveaux objets ou des objets
diffrents de la version d'origine. Notez bien toutefois qu'il est ncessaire de disposer des fichiers de contrles, de script, et autres
pour permettre la restauration d'une telle sauvegarde dans une nouvelle base de donne.
PostgreSQL ne permet pas de supprimer de manire individuelle les objets d'une extension sans supprimer l'extension tout entire. Aussi, bien que vous ayez la possibilit de modifier la dfinition d'un objet inclus dans une extension (par exemple via la
commande CREATE OR REPLACE FUNCTION dans le cas d'une fonction), il faut garder en tte que cette modification ne
sera pas sauvegarde par l'outil pg_dump. Une telle modification n'est en pratique raisonnable que si vous modifiez paralllement
le fichier de script de l'extension. Il existe toutefois des cas particuliers comme celui des tables qui contiennent des donnes de
configuration (voir ci-dessous).
Il existe aussi un mcanisme permettant de crer des scripts de mise jour de la dfinition des objets SQL contenus dans une extension. Par exemple, si la version 1.1 d'une extension ajoute une fonction et change le corps d'une autre vis--vis de la version 1.0
d'origine, l'auteur de l'extension peut fournir un script de mise jour qui effectue uniquement ces deux modifications. La commande ALTER EXTENSION UPDATE peut alors tre utilise pour appliquer ces changements et vrifier quelle version de
l'extension est actuellement installe sur une base de donne spcifie.
Les catgories d'objets SQL qui peuvent tre inclus dans une extension sont spcifies dans la description de la commande ALTER EXTENSION(7). D'une manire gnrale, les objets qui sont communs l'ensemble de la base ou du cluster, comme les
bases de donnes, les rles, les tablespaces ne peuvent tre inclus dans une extension car une extension n'est rfrence qu'
l'intrieur d'une base de donne. noter que rien n'empche la cration de fichier de script qui cre de tels objets, mais qu'ils ne
seront alors pas considrs aprs leur cration comme faisant partie de l'extension. savoir en outre que bien que les tables
puissent tre incluses dans une extension, les objets annexes tels que les index ne sont pas automatiquement inclus dans
l'extension et devront tre explicitement mentionns dans les fichiers de script. Un autre point important est que les schmas
peuvent appartenir des extensions et vice-versa : une extension n'a pas de nom qualifi et ne peut pas exister within dans un
schma. Par contre, les objets membres de l'extension appartiendront des schmas si c'est appropri suivant leur type. Il pourrait
tre appropri qu'un schma soit propritaire du ou des schmas o sont placs les objets membres de l'extension.

35.15.1. Fichiers des extensions


694

tendre SQL

La commande CREATE EXTENSION(7) repose sur un fichier de contrle associ chaque extension. Ce fichier doit avoir le
mme nom que l'extension suivi du suffixe .control, et doit tre plac dans le sous-rpertoire SHAREDIR/extension du rpertoire d'installation. Il doit tre accompagn d'au moins un fichier de script SQL dont le nom doit rpondre la syntaxe extension--version.sql (par exemple, foo--1.0.sql pour la version 1.0 de l'extension foo). Par dfaut, les fichiers de
script sont eux-aussi situs dans le rpertoire SHAREDIR/extension. Le fichier de contrle peut toutefois spcifier un rpertoire diffrent pour chaque fichier de script.
Le format du fichier de contrle d'une extension est le mme que pour le fichier postgresql.conf, savoir une liste
d'affectation nom_paramtre = valeur avec un maximum d'une affectation par ligne. Les lignes vides et les commentaires
introduits par # sont eux-aussi autoriss. Prenez garde placer entre guillemets les valeurs qui ne sont ni des nombres ni des mots
isols.
Un fichier de contrle peut dfinir les paramtres suivants :
directory (string)
Le rpertoire qui inclut les scripts SQL de l'extension. Si un chemin relatif est spcifi, le sous-rpertoire SHAREDIR du rpertoire d'installation sera choisi comme base. Le comportement par dfaut de ce paramtre revient le dfinir tel que directory = 'extension'.
default_version (string)
La version par dfaut de l'extension, qui sera installe si aucune version n'est spcifie avec la commande CREATE EXTENSION. Ainsi, bien que ce paramtre puisse ne pas tre prcis, il reste recommand de le dfinir pour viter que la commande CREATE EXTENSION ne provoque une erreur en l'absence de l'option VERSION.
comment (string)
Un commentaire de type chane de caractre au sujet de l'extension. Une alternative consiste utiliser la commande COMMENT(7) dans le script de l'extension.
encoding (string)
L'encodage des caractres utilis par les fichiers de script. Ce paramtre doit tre spcifi si les fichiers de script contiennent
des caractres non ASCII. Le comportement par dfaut en l'absence de ce paramtre consiste utiliser l'encodage de la base
de donne.
module_pathname (string)
La valeur de ce paramtre sera utilise pour toute rfrence MODULE_PATHNAME dans les fichiers de script. Si ce paramtre n'est pas dfini, la substitution ne sera pas effectue. La valeur $libdir/nom_de_bibliothque lui est usuellement attribue et dans ce cas, MODULE_PATHNAME est utilis dans la commande CREATE FUNCTION concernant les
fonctions en langage C, de manire ne pas mentionner en dur le nom de la bibliothque partage.
requires (string)
Une liste de noms d'extension dont dpend cette extension, comme par exemple requires = 'foo, bar'. Ces extensions doivent tre installes avant que l'extension puisse tre installe.
superuser (boolean)
Si ce paramtre est true (il s'agit de la valeur par dfaut), seuls les superutilisateurs pourront crer cet extension ou la
mettre jour. Si ce paramtre est false, seuls les droits ncessaires seront requis pour installer ou mettre jour
l'extension.
relocatable (boolean)
Une extension est dite dplaable (relocatable) s'il est possible de dplacer les objets qu'elle contient dans un schma diffrent de celui attribu initialement par l'extension. La valeur par dfaut est false, ce qui signifie que l'extension n'est pas
dplaable. Voir ci-dessous pour des informations complmentaires.
schema (string)
Ce paramtre ne peut tre spcifi que pour les extensions non dplaables. Il permet de forcer l'extension charger ses objets
dans le schma spcifi et aucun autre. Voir ci-dessous pour des informations complmentaires.
En complment au fichier de contrle extension.control, une extension peut disposer de fichiers de contrle secondaires
pour chaque version dont le nommage correspond extension--version.control. Ces fichiers doivent se trouver dans le
rpertoire des fichiers de script de l'extension. Les fichiers de contrle secondaires suivent le mme format que le fichier de
contrle principal. Tout paramtre spcifi dans un fichier de contrle secondaire surcharge la valeur spcifie dans le fichier de
contrle principal concernant les installations ou mises jour la version considre. Cependant, il n'est pas possible de spcifier
les paramtres directory et default_version dans un fichier de contrle secondaire.
Un fichier de script SQL d'une extension peut contenir toute commande SQL, l'exception des commandes de contrle de transaction (BEGIN, COMMIT, etc), et des commandes qui ne peuvent tre excutes au sein d'un bloc transactionnel (comme la commande VACUUM). Cette contrainte est lie au fait que les fichiers de script sont implicitement excuts dans une transaction.
695

tendre SQL

An extension's SQL script files can also contain lines beginning with \echo, which will be ignored (treated as comments) by the
extension mechanism. This provision is commonly used to throw an error if the script file is fed to psql rather than being loaded
via CREATE EXTENSION (see example script below). Without that, users might accidentally load the extension's contents as
loose objects rather than as an extension, a state of affairs that's a bit tedious to recover from.
Bien que les fichiers de script puissent contenir n'importe quel caractre autoris par l'encodage spcifi, les fichiers de contrle ne
peuvent contenir que des caractres ASCII non formats. En effet, PostgreSQL ne peut pas dterminer l'encodage utilis par les
fichiers de contrle. Dans la pratique, cela ne pose problme que dans le cas o vous voudriez utiliser des caractres non ASCII
dans le commentaire de l'extension. Dans ce cas de figure, il est recommand de ne pas utiliser le paramtre comment du fichier
de contrle pour dfinir ce commentaire, mais plutt la commande COMMENT ON EXTENSION dans un fichier de script.

35.15.2. Possibilits concernant le dplacement des extensions


Les utilisateurs souhaitent souvent charger les objets d'une extension dans un schma diffrent de celui impos par l'auteur. Trois
niveaux de dplacement sont supports :

Une extension supportant compltement le dplacement peut tre dplac dans un autre schma tout moment, y compris
aprs son chargement dans une base de donne. Initialement, tous les objets de l'extension installe appartiennent un premier
schma (except les objets qui n'appartiennent aucun schma comme les langages procduraux). L'opration de dplacement
peut alors tre ralise avec la commande ALTER EXTENSION SET SCHEMA, qui renomme automatiquement tous les
objets de l'extension pour tre intgrs dans le nouveau schma. Le dplacement ne sera toutefois fonctionnel que si
l'extension ne contient aucune rfrence de l'appartenance d'un de ses objets un schma. Dans ce cadre, il est alors possible
de spcifier qu'une extension supporte compltement le dplacement en initialisant relocatable = true dans son fichier
de contrle.

Une extension peut tre dplaable durant l'installation et ne plus l'tre par la suite. Un exemple courant est celui du fichier de
script de l'extension qui doit rfrencer un schma cible de manire explicite pour des fonctions SQL, par exemple en dfinissant la proprit search_path. Pour de telles extensions, il faut dfinir relocatable = false dans son fichier de
contrle, et utiliser @extschema@ pour rfrencer le schma cible dans le fichier de script. Toutes les occurences de cette
chane dans le fichier de script seront remplaces par le nom du schma choisi avant son excution. Le nom du schma choisi
peut tre fix par l'option SCHEMA de la commande CREATE EXTENSION>.

Si l'extension ne permet pas du tout le dplacement, il faut dfinir relocatable = false dans le fichier de contrle,
mais aussi dfinir schema comme tant le nom du schma cible. Cette prcaution permettra d'empcher l'usage de l'option
SCHEMA de la commande CREATE EXTENSION, moins que cette option ne rfrence la mme valeur que celle spcifie
dans le fichier de contrle. Ce choix est priori ncessaire si l'extension contient des rfrences des noms de schma qui ne
peuvent tre remplacs par @extschema@. noter que mme si son usage reste relativement limit dans ce cas de figure
puisque le nom du schma est alors fix dans le fichier de contrle, le mcanisme de substitution de @extschema@ reste toujours oprationnel.

Dans tous les cas, le fichier de script sera excut avec comme valeur de search_path le schma cible. Cela signifie que la commande CREATE EXTENSION ralisera l'quivalent de la commande suivante :
SET LOCAL search_path TO @extschema@;
Cela permettra aux objets du fichier de script d'tre crs dans le schma cible. Le fichier de script peut toutefois modifier la valeur de search_path si ncessaire, mais cela n'est gnralement pas le comportement souhait. La variable search_path retrouvera sa valeur initiale la fin de l'excution de la commande CREATE EXTENSION.
Le schma cible est dtermin par le paramtre schema dans le fichier de contrle s'il est prcis, sinon par l'option SCHEMA de
la commande CREATE EXTENSION si elle est spcifie, sinon par le schma de cration par dfaut actuel (le premier rencontr
en suivant le chemin de recherche search_path de l'appelant). Quand le paramtre schema du fichier de contrle est utilis,
le schma cible sera cr s'il n'existe pas encore. Dans les autres cas, il devra exister au pralable.
Si des extensions requises sont dfinies par requires dans le fichier de contrle, leur schma cible est ajout la valeur initiale
de search_path. Cela permet leurs objets d'tre visibles dans le fichier de script de l'extension installe.
Une extension peut contenir des objets rpartis dans plusieurs schmas. Il est alors conseill de regrouper dans un unique schma
l'ensemble des objets destins un usage externe l'extension, qui sera alors le schma cible de l'extension. Une telle organisation
est compatible avec la dfinition par dfaut de search_path pour la cration d'extensions qui en seront dpendantes.

35.15.3. Tables de configuration des extensions


Certaines extensions incluent des tables de configuration, contenant des donnes qui peuvent tre ajoutes ou changes par
l'utilisateur aprs l'installation de l'extension. Normalement, si la table fait partie de l'extension, ni la dfinition de la table, ni son
696

tendre SQL

contenu ne sera sauvegard par pg_dump. Mais ce comportement n'est pas celui attendu pour une table de configuration. Les donnes modifies par un utilisateur ncessitent d'tre sauvegardes, ou l'extension aura un comportement diffrent aprs rechargement.
Pour rsoudre ce problme, un fichier de script d'extension peut marquer une table comme tant une table de configuration, ce qui
indiquera pg_dump d'inclure le contenu de la table (et non sa dfinition) dans la sauvegarde. Pour cela, il s'agit d'appeler la fonction pg_extension_config_dump(regclass, text) aprs avoir cr la table, par exemple
CREATE TABLE my_config (key text, value text);
SELECT pg_catalog.pg_extension_config_dump('my_config', '');
Cette fonction permet de marquer autant de tables que ncessaire.
Si le second argument de pg_extension_config_dump est une chane vide, le contenu entier de la table sera sauvegard par
l'application pg_dump. Cela n'est correct que si la table tait initialement vide aprs l'installation du script. Si un mlange de donnes initiales et de donnes ajoutes par l'utilisateur est prsent dans la table, le second argument de
pg_extension_config_dump permet de spcifier une condition WHERE qui selectionne les donnes sauvegarder. Par
exemple, vous pourriez faire
CREATE TABLE my_config (key text, value text, standard_entry boolean);
SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry');
et vous assurer que la valeur de standard_entry soit true uniquement lorsque les lignes ont t cres par le script de
l'extension.
Des situations plus compliques, comme des donnes initiales qui peuvent tre modifies par l'utilisateur, peuvent tre prises en
charge en crant des triggers sur la table de configuration pour s'assurer que les lignes ont t marques correctement.
Vous pouvez modifier la condition du filtre associ avec une table de configuration en appelant de nouveau
pg_extension_config_dump. (Ceci serait typiquement utile dans un script de mise jour d'extension.) La seule faon de
marquer une table est de la dissocier de l'extension avec la commande ALTER EXTENSION ... DROP TABLE.

35.15.4. Mise jour d'extension


Un des avantages du mcanisme d'extension est de proposer un moyen simple de grer la mise jour des commandes SQL qui dfinissent les objets de l'extension. Cela est rendu possible par l'association d'un nom ou d'un numro de version chaque nouvelle
version du script d'installation de l'extension. En complment, si vous voulez qu'un utilisateur soit capable de mettre jour sa base
de donnes dynamiquement d'une version une autre, vous pouvez fournir des scripts de mise jour qui feront les modifications
ncessaires.
Les
scripts
de
mise

jour
ont
un
nom
qui
correspond
au
format
extension--oldversion--newversion.sql (par exemple, foo--1.0--1.1.sql contient les commandes pour modifier la version 1.0 de l'extension foo en la version 1.1).
En admettant qu'un tel script de mise jour soit disponible, la commande ALTER EXTENSION UPDATE mettra jour une extension installe vers la nouvelle version spcifie. Le script de mise jour est excut dans le mme environnement que celui que
la commande CREATE EXTENSION fournit pour l'installation de scripts : en particulier, la variable search_path est dfinie
de la mme faon et tout nouvel objet cr par le script est automatiquement ajout l'extension.
Si une extension a un fichier de contrle secondaire, les paramtres de contrle qui sont utiliss par un script de mise jour sont
ceux dfinis par le script de la version cible.
Le mcanisme de mise jour peut tre utilis pour rsoudre un cas particulier important : convertir une collection parse d'objets
en une extension. Avant que le mcanisme d'extension ne soit introduit PostgreSQL (dans la version 9.1), de nombreuses personnes crivaient des modules d'extension qui craient simplement un assortiment d'objets non empaquets. Etant donn une base
de donne existante contenant de tels objets, comment convertir ces objets en des extensions proprement empaquetes ? Les supprimer puis excuter la commande CREATE EXTENSION est une premire mthode, mais elle n'est pas envisageable lorsque
les objets ont des dpendances (par exemple, s'il y a des colonnes de table dont le type de donnes appartient une extension). Le
moyen propos pour rsoudre ce problme est de crer une extension vide, d'utiliser la commande ALTER EXTENSION ADD
pour lier chaque objet pr-existant l'extension, et finalement crer les nouveaux objets prsents dans la nouvelle extension mais
absents de celle non empaquete. La commande CREATE EXTENSION prend en charge cette fonction avec son option FROM
old_version, qui permet de ne pas charger le script d'installation par dfaut pour la version cible, mais celui nomm extension--old_version--target_version.sql. Le choix de la valeur de old_version relve de la responsabilit de
l'auteur de l'extension, mme si unpackaged est souvent rencontr. Il est aussi possible de multiplier les valeurs de
old_version pour prendre en compte une mise jour depuis diffrentes anciennes versions.
La commande ALTER EXTENSION peut excuter des mises jour en squence pour russir une mise jour. Par exemple, si
697

tendre SQL

seuls les fichiers foo--1.0--1.1.sql et foo--1.1--2.0.sql sont disponibles, la commande ALTER EXTENSION les
excutera squentiellement si une mise jour vers la version 2.0 est demande alors que la version 1.0 est installe.
PostgreSQL ne suppose rien au sujet des noms de version. Par exemple, il ne sait pas si 1.1 suit 1.0. Il effectue juste une correspondance entre les noms de version et suit un chemin qui ncessite d'appliquer le moins de fichier de script possible. Un nom
de version peut en ralit tre toute chane qui ne contiendrait pas -- ou qui ne commencerait ou ne finirait pas par -.
Il peut parfois tre utile de fournir des scripts de retour en arrire, comme par exemple foo--1.1--1.0.sql pour autoriser
d'inverser les modifications effectues par la mise jour en version 1.1. Si vous procdez ainsi, ayez conscience de la possibilit
laisse PostgreSQL d'excuter un tel script de retour en arrire s'il permet d'atteindre la version cible d'une mise jour en un
nombre rduit d'tapes. La cause du risque se trouve dans les scripts de mise jour optimiss permettant de passer plusieurs versions en un seul script. La longueur du chemin commenant par un retour en arrire suivi d'un script optimis pourrait tre infrieure la longueur du chemin qui monterait de version une par une. Si le script de retour en arrire supprime un objet irremplaable, les consquences pourraient en tre facheuses.
Pour vrifier que vous ne serez pas confront des chemins de mise jour inattendus, utilisez cette commande :
SELECT * FROM pg_extension_update_paths('extension_name');
Cette commande permet d'afficher chaque paire de noms de version connues pour l'extension spcifie, ainsi que le chemin de
mise jour qui serait suivi depuis la version de dpart jusque la version cible, ou la valeur NULL si aucun chemin valable n'est disponible. Le chemin est affich sous une forme textuelle avec des sparateurs --. Vous pouvez utiliser regexp_split_to_array(path,'--') si vous prfrez le format tableau.

35.15.5. Exemples d'extensions


Ci-aprs, un exemple complet d'une extension crite uniquement en SQL, un type composite de deux lments qui peut stocker
n'importe quelle valeur dans chaque emplacement, qui sont nomms k et v . Les valeurs non textuelles sont automatiquement changes en texte avant stockage.
Le fichier de script pair--1.0.sql ressemble ceci:
-- se plaint si le script est excut directement dans psql, plutt que via CREATE
EXTENSION
\echo Use "CREATE EXTENSION pair" to load this file. \quit
CREATE TYPE pair AS ( k text, v text );
CREATE OR REPLACE FUNCTION pair(anyelement, text)
RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair';
CREATE OR REPLACE FUNCTION pair(text, anyelement)
RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair';
CREATE OR REPLACE FUNCTION pair(anyelement, anyelement)
RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair';
CREATE OR REPLACE FUNCTION pair(text, text)
RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair;';
CREATE
CREATE
CREATE
CREATE

OPERATOR
OPERATOR
OPERATOR
OPERATOR

~>
~>
~>
~>

(LEFTARG
(LEFTARG
(LEFTARG
(LEFTARG

=
=
=
=

text, RIGHTARG = anyelement, PROCEDURE = pair);


anyelement, RIGHTARG = text, PROCEDURE = pair);
anyelement, RIGHTARG = anyelement, PROCEDURE = pair);
text, RIGHTARG = text, PROCEDURE = pair);

Le fichier de contrle pair.control ressemble ceci:


# extension pair
comment = 'Un type de donnees representant un couple clef/valeur'
default_version = '1.0'
relocatable = true
Si vous avez besoin d'un fichier d'installation pour installer ces deux fichiers dans le bon rpertoire, vous pouvez utiliser le fichier
Makefile qui suit :

698

tendre SQL

EXTENSION = pair
DATA = pair--1.0.sql
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
Ce fichier d'installation s'appuye sur PGXS, qui est dcrit dans Section 35.16, Outils de construction d'extension . La commande make install va installer les fichiers de contrle et de script dans le rpertoire adquat tel qu'indiqu par pg_config.
Une fois les fichiers installs, utilisez la commande CREATE EXTENSION(7) pour charger les objets dans une base de donne.

35.16. Outils de construction d'extension


Si vous comptez distribuer vos propres modules d'extension PostgreSQL, la mise en uvre d'un systme de construction multiplateforme sera rellement difficile. Cependant, PostgreSQL met disposition des outils pour construire des extensions, appels
PGXS, permettant de simples extensions d'tre construites sur un serveur dj install. PGXS est principalement destin aux extensions qui incluent du code C, bien qu'il puisse tre utilis aussi pour des extensions composes exclusivement de code SQL.
PGXS n'a pas toutefois t conu pour tre un framework de construction universel qui pourrait construire tout logiciel
s'interfaant avec PostgreSQL. Il automatise simplement des rgles de construction communes pour des extensions simples.
Pour des paquetages plus complexes, vous aurez toujours besoin d'crire vos propres systmes de construction.
Pour utiliser le systme PGXS pour votre extension, vous devez crire un simple makefile. Dans ce makefile, vous devez dfinir
plusieurs variables et inclure le makefile de PGXS. Voici un exemple qui construit une extension nomme isbn_issn, qui
consiste en une bibliothque qui contient du code C, un fichier de contrle d'extension, un script SQL et une documentation texte :
MODULES = isbn_issn
EXTENSION = isbn_issn
DATA = isbn_issn--1.0.sql
DOCS = README.isbn_issn
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
Les trois dernires lignes devraient toujours tre les mmes. En dbut de fichier, vous pouvez assigner des variables ou ajouter des
rgles make personnalises.
Dfinissez une de ces trois variables pour spcifier ce qui est construit :
MODULES
liste des bibliothques constuire depuis les fichiers sources communs (ne pas inclure les suffixes de bibliothques dans la
liste)
MODULE_big
Une bibliothque construire depuis plusieurs fichiers source (listez les fichiers objets dans la variable OBJS).
PROGRAM
Un programme excutable construire (listez les fichiers objet dans la variable OBJS).
Les variables suivantes peuvent aussi tre dfinies :
EXTENSION
Nom(s) de l'extension ; pour chaque nom, vous devez fournir un fichier extension.control, qui sera install dans le rpertoire prefix/share/extension
MODULEDIR
Sous-rpertoire de prefix/share dans lequel les fichiers DATA et DOCS seront installs (s'il n'est pas dfini, la valeur
par dfaut est extension si EXTENSION est dfini et contrib dans le cas contraire)
DATA
Fichiers divers installer dans prefix/share/$MODULEDIR
DATA_built
Fichiers divers installer dans prefix/share/$MODULEDIR, qui ncessitent d'tre construit au pralable
DATA_TSEARCH
Fichiers divers installer dans prefix/share/tsearch_data
699

tendre SQL

DOCS
Fichiers divers installer dans prefix/doc/$MODULEDIR
SCRIPTS
Fichiers de scripts (non binaires) installer dans prefix/bin
SCRIPTS_built
Fichiers de script (non binaires) installer dans prefix/bin, qui ncessitent d'tre construit au pralable.
REGRESS
Liste de tests de regression (sans suffixe), voir plus bas
REGRESS_OPTS
Options supplmentaires passer pg_regress
EXTRA_CLEAN
Fichiers supplmentaire supprimer par la commande make clean
PG_CPPFLAGS
Sera ajout CPPFLAGS
PG_LIBS
Sera ajout la ligne d'dition de lien de PROGRAM
SHLIB_LINK
Sera ajout la ligne d'dition de lien de MODULE_big
PG_CONFIG
Chemin vers le programme pg_config de l'installation de PostgreSQL pour laquelle construire la bibliothque ou le binaire
(l'utilisation de pg_config seul permet d'utiliser le premier accessible par votre PATH)
Placez ce fichier de construction comme Makefile dans le rpertoire qui contient votre extension. Puis vous pouvez excuter la
commande make pour compiler, et ensuite make install pour dployer le module. Par dfaut, l'extension est compile et installe pour l'installation de PostgreSQL qui correspond au premier programme pg_config trouv dans votre PATH. Vous pouvez
utiliser une installation diffrente en dfinissant PG_CONFIG pour pointer sur le programme pg_config de votre choix, soit dans
le fichier makefile, soit partir de la ligne de commande de la commande make.

Attention
Modifier la variable PG_CONFIG ne fonctionne que lorsque l'on compile pour PostgreSQL 8.3 et au del. Avec
des versions plus anciennes, il n'est possible de spcifier que pg_config. Vous devez modifier votre PATH pour
choisir l'installation souhaite.
Les scripts lists dans la variable REGRESS sont utiliss pour des tests de regression de votre module, qui peut tre invoqu par
make installcheck aprs avoir effectu make install. Pour que cela fonctionne, vous devez lancer le serveur PosgreSQL pralablement. Les fichiers de script lists dans la variable REGRESS doivent apparatre dans le sous-rpertoire appel
sql/ du rpertoire de votre extension. Ces fichiers doivent avoir l'extension .sql, qui ne doit pas tre inclus dans la liste REGRESS du makefile. Pour chaque test, il doit aussi y avoir un fichier qui contient les rsultats attendus dans un sous-rpertoire
nomm expected, avec le mme nom mais l'extension .out. La commande make installcheck excute chaque script de
test avec psql, et compare la sortie resultante au fichier de rsultat correspondant. Toute diffrence sera crite dans le fichier regression.diffs au format diff -c. Notez que l'excution d'un test qui ne dispose pas des fichiers ncessaires sera rapporte
comme une erreur dans le test, donc assurez-vous que tous les fichiers ncessaires soient prsents.

Astuce
Le moyen le plus simple de crer les fichiers ncessaires est de crer des fichiers vides, puis d'effectuer un jeu
d'essai (qui bien sr retournera des anomalies). tudiez les rsultats trouvs dans le rpertoire results et copiezles dans le rpertoire expected/ s'ils correspondent ce que vous attendiez du test correspondant.

700

Chapitre 36. Dclencheurs (triggers)


Ce chapitre fournit des informations gnrales sur l'criture des fonctions pour dclencheur. Les fonctions pour dclencheurs
peuvent tre crites dans la plupart des langages de procdure disponibles incluant PL/pgSQL (Chapitre 39, PL/pgSQL - Langage de procdures SQL), PL/Tcl (Chapitre 40, PL/Tcl - Langage de procdures Tcl), PL/Perl (Chapitre 41, PL/Perl - Langage
de procdures Perl) et PL/Python (Chapitre 42, PL/Python - Langage de procdures Python). Aprs avoir lu ce chapitre, vous
devriez consulter le chapitre sur votre langage de procdure favori pour dcouvrir les spcificits de l'criture de dclencheurs
dans ce langage.
Il est aussi possible d'crire une fonction dclencheur en C, bien que la plupart des gens trouvent plus facile d'utiliser un des langages de procdure. Il est actuellement impossible d'crire une fonction dclencheur dans le langage de fonction simple SQL.

36.1. Aperu du comportement des dclencheurs


Un dclencheur spcifie que la base de donnes doit excuter automatiquement une fonction donne chaque fois qu'un certain
type d'opration est excut. Les fonctions dclencheur peuvent tre attaches une table ou une vue.
Sur des tables, les triggers peuvent tre dfinies pour s'excuter avant ou aprs une commande INSERT, UPDATE ou DELETE, soit une fois par ligne modifie, soit une fois par expression SQL. Les triggers UPDATE peuvent en plus tre configures pour n'tre dclenchs que si certaines colonnes sont mentionnes dans la clause SET de l'instruction UPDATE. Les triggers peuvent aussi se dclencher pour des instructions TRUNCATE. Si un vnement d'un trigger intervient, la fonction du
trigger est appele au moment appropri pour grer l'vnement.
Des triggers peuvent tre dfinies sur des vues pour excuter des oprations la place des commandes INSERT, UPDATE ou
DELETE. Les triggers INSTEAD OF sont dclenchs une fois par ligne devant tre modifie dans la vue. C'est de la responsabilit de la fonction trigger de raliser les modifications ncessaires pour que les tables de base sous-jacentes et, si appropri, de
renvoyer la ligne modifie comme elle apparatra dans la vue. Les triggers sur les vues peuvent aussi tre dfinis pour s'excuter
une fois par requte SQL statement, avant ou aprs des oprations INSERT, UPDATE ou DELETE operations.
La fonction dclencheur doit tre dfinie avant que le dclencheur lui-mme puisse tre cr. La fonction dclencheur doit tre
dclare comme une fonction ne prenant aucun argument et retournant un type trigger (la fonction dclencheur reoit ses entres via une structure TriggerData passe spcifiquement, et non pas sous la forme d'arguments ordinaires de fonctions).
Une fois qu'une fonction dclencheur est cre, le dclencheur (trigger) est cr avec CREATE TRIGGER(7). La mme fonction dclencheur est utilisable par plusieurs dclencheurs.
PostgreSQL offre des dclencheurs par ligne et par instruction. Avec un dclencheur mode ligne, la fonction du dclencheur
est appele une fois pour chaque ligne affecte par l'instruction qui a lanc le dclencheur. Au contraire, un dclencheur mode
instruction n'est appel qu'une seule fois lorsqu'une instruction approprie est excute, quelque soit le nombre de lignes affectes par cette instruction. En particulier, une instruction n'affectant aucune ligne rsultera toujours en l'excution de tout dclencheur mode instruction applicable. Ces deux types sont quelque fois appels respectivement des dclencheurs niveau ligne et
des dclencheurs niveau instruction. Les triggers sur TRUNCATE peuvent seulement tre dfinis au niveau instruction. Sur des
vues, les triggers qui se dclenchent avant ou aprs peuvent tre seulement dfinis au niveau instruction alors que les triggers
qui ont un dclenchement la place d'un INSERT, UPDATE ou DELETE peuvent seulement tre dfinis au niveau ligne.
Les triggers sont aussi classifies suivant qu'ils se dclenchent avant (before), aprs (after) ou la place (instead of) de
l'opration. Ils sont rfrencs respectivement comme des triggers BEFORE, AFTER et INSTEAD OF. Les triggers BEFORE au
niveau requte se dclenchent avant que la requte ne commence quoi que ce soit alors que les triggers AFTER au niveau requte se dclenchent tout la fin de la requte. Ces types de triggers peuvent tre dfinis sur les tables et vues. Les triggers BEFORE au niveau ligne se dclenchent immdiatement avant l'opration sur une ligne particulire alors que les triggers AFTER au
niveau ligne se dclenchent la fin de la requte (mais avant les triggers AFTER au niveau requte). Ces types de triggers
peuvent seulement tre dfinis sur les tables. Les triggers INSTEAD OF au niveau ligne peuvent seulement tre dfinis sur des
vues et se dclenchent immdiatement sur chaque ligne de la vue qui est identifie comme ncessitant cette opration.
Les fonctions dclencheurs appeles par des dclencheurs niveau instruction devraient toujours renvoyer NULL. Les fonctions
dclencheurs appeles par des dclencheurs niveau ligne peuvent renvoyer une ligne de la table (une valeur de type HeapTuple)
vers l'excuteur appelant, s'ils le veulent. Un dclencheur niveau ligne excut avant une opration a les choix suivants :

Il peut retourner un pointeur NULL pour sauter l'opration pour la ligne courante. Ceci donne comme instruction
l'excuteur de ne pas excuter l'opration niveau ligne qui a lanc le dclencheur (l'insertion, la modification ou la suppression d'une ligne particulire de la table).

Pour les dclencheurs INSERT et UPDATE de niveau ligne uniquement, la valeur de retour devient la ligne qui sera insre
ou remplacera la ligne en cours de mise jour. Ceci permet la fonction dclencheur de modifier la ligne en cours
d'insertion ou de mise jour.
701

Dclencheurs (triggers)

Un dclencheur BEFORE niveau ligne qui ne serait pas conu pour avoir l'un de ces comportements doit prendre garde retourner
la mme ligne que celle qui lui a t passe comme nouvelle ligne (c'est--dire : pour des dclencheurs INSERT et UPDATE : la
nouvelle (NEW) ligne ,et pour les dclencheurs DELETE) : l'ancienne (OLD) ligne .
Un trigger INSTEAD OF niveau ligne devrait renvoyer soit NULL pour indiquer qu'il n'a pas modifi de donnes des tables de
base sous-jacentes de la vue, soit la ligne de la vue qui lui a t pass (la ligne NEW pour les oprations INSERT et UPDATE, ou
la ligne OLD pour l'opration DELETE). Une valeur de retour diffrent de NULL est utilise comme signal indiquant que le trigger a ralis les modifications de donnes ncessaires dans la vue. Ceci causera l'incrmentation du nombre de lignes affectes par
la commande. Pour les oprations INSERT et UPDATE, le trigger peut modifier la ligne NEW avant de la renvoyer. Ceci modifiera les donnes renvoyes par INSERT RETURNING ou UPDATE RETURNING, et est utile quand la vue n'affichera pas exactement les donnes fournies.
La valeur de retour est ignore pour les dclencheurs niveau ligne lancs aprs une opration. Ils peuvent donc renvoyer la valeur
NULL.
Si plus d'un dclencheur est dfini pour le mme vnement sur la mme relation, les dclencheurs seront lancs dans l'ordre alphabtique de leur nom. Dans le cas de dclencheurs BEFORE et INSTEAD OF, la ligne renvoye par chaque dclencheur, qui a
ventuellement t modifie, devient l'argument du prochain dclencheur. Si un des dclencheurs BEFORE ou INSTEAD OF renvoie un pointeur NULL, l'opration est abandonne pour cette ligne et les dclencheurs suivants ne sont pas lancs (pour cette
ligne).
Une dfinition de trigger peut aussi spcifier une condition boolenne WHEN qui sera teste pour savoir si le trigger doit bien tre
dclench. Dans les triggers de niveau ligne, la condition WHEN peut examiner l'ancienne et la nouvelle valeur des colonnes de la
ligne. (les triggers de niveau instruction peuvent aussi avoir des conditions WHEN mais cette fonctionnalit est moins intressante
pour elles). Dans un trigger avant, la condition WHEN est value juste avant l'excution de la fonction, donc l'utilisation de WHEN
n'est pas rellement diffrente du test de la mme condition au dbut de la fonction trigger. Nanmoins, dans un tigger AFTER, la
condition WHEN est value juste avant la mise jour de la ligne et dtermine si un vnement va dclencher le trigger la fin de
l'instruction. Donc, quand la condition WHEN d'un trigger AFTER ne renvoie pas true, il n'est pas ncessaire de mettre en queue un
vnement ou de rcuprer de nouveau la ligne la fin de l'instriction. Ceci permet une amlioration consquente des performances pour les instructions qui modifient un grand nombre de lignes si le trigger a seulement besoin d'tre excut que sur
quelques lignes. Les triggers INSTEAD OF n'acceptent pas les conditions WHEN.
Les dclencheurs BEFORE en mode ligne sont typiquement utiliss pour vrifier ou modifier les donnes qui seront insres ou
mises jour. Par exemple, un dclencheur BEFORE pourrait tre utilis pour insrer l'heure actuelle dans une colonne de type timestamp ou pour vrifier que deux lments d'une ligne sont cohrents. Les dclencheurs AFTER en mode ligne sont pour la plupart utiliss pour propager des mises jour vers d'autres tables ou pour raliser des tests de cohrence avec d'autres tables. La raison de cette division du travail est qu'un dclencheur AFTER peut tre certain qu'il voit la valeur finale de la ligne alors qu'un dclencheur BEFORE ne l'est pas ; il pourrait exister d'autres dclencheurs BEFORE qui seront excuts aprs lui. Si vous n'avez aucune raison spciale pour le moment du dclenchement, le cas BEFORE est plus efficace car l'information sur l'opration n'a pas
besoin d'tre sauvegarde jusqu' la fin du traitement.
Si une fonction dclencheur excute des commandes SQL, alors ces commandes peuvent lancer leur tour des dclencheurs. On
appelle ceci un dclencheur en cascade. Il n'y a pas de limitation directe du nombre de niveaux de cascade. Il est possible que les
cascades causent un appel rcursif du mme dclencheur ; par exemple, un dclencheur INSERT pourrait excuter une commande
qui insre une ligne supplmentaire dans la mme table, entranant un nouveau lancement du dclencheur INSERT. Il est de la
responsabilit du programmeur d'viter les rcursions infinies dans de tels scnarios.
Quand un dclencheur est dfini, des arguments peuvent tre spcifis pour lui. L'objectif de l'inclusion d'arguments dans la dfinition du dclencheur est de permettre diffrents dclencheurs ayant des exigences similaires d'appeler la mme fonction. Par
exemple, il pourrait y avoir une fonction dclencheur gnralise qui prend comme arguments deux noms de colonnes et place
l'utilisateur courant dans l'une et un horodatage dans l'autre. Correctement crit, cette fonction dclencheur serait indpendante de
la table particulire sur laquelle il se dclenche. Ainsi, la mme fonction pourrait tre utilise pour des vnements INSERT sur
n'importe quelle table ayant des colonnes adquates, pour automatiquement suivre les crations d'enregistrements dans une table
de transactions par exemple. Elle pourrait aussi tre utilise pour suivre les dernires mises jours si elle est dfinie comme un dclencheur UPDATE.
Chaque langage de programmation supportant les dclencheurs a sa propre mthode pour rendre les donnes en entre disponible
la fonction du dclencheur. Cette donne en entre inclut le type d'vnement du dclencheur (c'est--dire INSERT ou UPDATE) ainsi que tous les arguments lists dans CREATE TRIGGER. Pour un dclencheur niveau ligne, la donne en entre inclut aussi la ligne NEW pour les dclencheurs INSERT et UPDATE et/ou la ligne OLD pour les dclencheurs UPDATE et DELETE. Les dclencheurs niveau instruction n'ont actuellement aucun moyen pour examiner le(s) ligne(s) individuelle(s) modifies
par l'instruction.

36.2. Visibilit des modifications des donnes


Si vous excutez des commandes SQL dans votre fonction SQL et que ces commandes accdent la table pour laquelle vous
702

Dclencheurs (triggers)

crez ce dclencheur, alors vous avez besoin de connatre les rgles de visibilit des donnes car elles dterminent si les commandes SQL voient les modifications de donnes pour lesquelles est excut le dclencheur. En bref :

Les dclencheurs niveau instruction suivent des rgles de visibilit simples : aucune des modifications ralises par une instruction n'est visible aux dclencheurs niveau instruction appels avant l'instruction alors que toutes les modifications sont visibles aux dclencheurs AFTER niveau instruction.

Les modifications de donnes (insertion, mise jour ou suppression) lanant le dclencheur ne sont naturellement pas visibles
aux commandes SQL excutes dans un dclencheur BEFORE en mode ligne parce qu'elles ne sont pas encore survenues.

Nanmoins, les commandes SQL excutes par un dclencheur BEFORE en mode ligne verront les effets des modifications de
donnes pour les lignes prcdemment traites dans la mme commande externe. Ceci requiert une grande attention car l'ordre
des vnements de modification n'est en gnral pas prvisible ; une commande SQL affectant plusieurs lignes pourrait visiter
les lignes dans n'importe quel ordre.

De faon similaire, un trigger niveau ligne de type INSTEAD OF verra les effets des modifications de donnes ralises par
l'excution des autres triggers INSTEAD OF dans la mme commande.

Quand un dclencheur AFTER en mode ligne est excut, toutes les modifications de donnes ralises par la commande externe sont dj termines et sont visibles par la fonction appele par le dclencheur.

Si votre fonction trigger est crite dans un des langages de procdures standard, alors les instructions ci-desus s'appliquent seulement si la fonction est dclare VOLATILE. Les fonctions dclares STABLE ou IMMUTABLE ne verront pas les modifications
ralises par la commande appelante dans tous les cas.
Il existe plus d'informations sur les rgles de visibilit des donnes dans la Section 43.4, Visibilit des modifications de donnes . L'exemple dans la Section 36.4, Un exemple complet de trigger contient une dmonstration de ces rgles.

36.3. crire des fonctions dclencheurs en C


Cette section dcrit les dtails de bas niveau de l'interface d'une fonction dclencheur. Ces informations ne sont ncessaires que
lors de l'criture d'une fonction dclencheur en C. Si vous utilisez un langage de plus haut niveau, ces dtails sont grs pour vous.
Dans la plupart des cas, vous devez considrer l'utilisation d'un langage de procdure avant d'crire vos dclencheurs en C. La documentation de chaque langage de procdures explique comment crire un dclencheur dans ce langage.
Les fonctions dclencheurs doivent utiliser la version 1 de l'interface du gestionnaire de fonctions.
Quand une fonction est appele par le gestionnaire de dclencheur, elle ne reoit aucun argument classique, mais un pointeur de
contexte pointant sur une structure TriggerData. Les fonctions C peuvent vrifier si elles sont appeles par le gestionnaire de
dclencheurs ou pas en excutant la macro :
CALLED_AS_TRIGGER(fcinfo)
qui se dcompose en :
((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
Si elle retourne la valeur vraie, alors il est bon de convertir fcinfo->context en type TriggerData * et de faire usage de
la structure pointe TriggerData. La fonction ne doit pas modifier la structure TriggerData ou une donne quelconque vers laquelle elle pointe.
struct TriggerData est dfinie dans commands/trigger.h :
typedef struct TriggerData
{
NodeTag
type;
TriggerEvent tg_event;
Relation
tg_relation;
HeapTuple
tg_trigtuple;
HeapTuple
tg_newtuple;
Trigger
*tg_trigger;
Buffer
tg_trigtuplebuf;
Buffer
tg_newtuplebuf;
} TriggerData;
o les membres sont dfinis comme suit :
type
Toujours T_TriggerData.
703

Dclencheurs (triggers)

tg_event
Dcrit l'vnement pour lequel la fonction est appele. Vous pouvez utiliser les macros suivantes pour examiner tg_event :
TRIGGER_FIRED_BEFORE(tg_event)
Renvoie vrai si le dclencheur est lanc avant l'opration.
TRIGGER_FIRED_AFTER(tg_event)
Renvoie vrai si le dclencheur est lanc aprs l'opration.
TRIGGER_FIRED_INSTEAD(tg_event)
Renvoie vrai si le trigger a t lanc la place de l'opration.
TRIGGER_FIRED_FOR_ROW(tg_event)
Renvoie vrai si le dclencheur est lanc pour un vnement en mode ligne.
TRIGGER_FIRED_FOR_STATEMENT(tg_event)
Renvoie vrai si le dclencheur est lanc pour un vnement en mode instruction.
TRIGGER_FIRED_BY_INSERT(tg_event)
Retourne vrai si le dclencheur est lanc par une commande INSERT.
TRIGGER_FIRED_BY_UPDATE(tg_event)
Retourne vrai si le dclencheur est lanc par une commande UPDATE.
TRIGGER_FIRED_BY_DELETE(tg_event)
Retourne vrai si le dclencheur est lanc par une commande DELETE.
TRIGGER_FIRED_BY_TRUNCATE(tg_event)
Renvoie true si le trigger a t dclench par une commande TRUNCATE.
tg_relation
Un pointeur vers une structure dcrivant la relation pour laquelle le dclencheur est lanc. Voir utils/rel.h pour les dtails de cette structure. Les choses les plus intressantes sont tg_relation->rd_att (descripteur de nuplets de la relation) et tg_relation->rd_rel->relname (nom de la relation ; le type n'est pas char* mais NameData ; utilisez
SPI_getrelname(tg_relation) pour obtenir un char* si vous avez besoin d'une copie du nom).
tg_trigtuple
Un pointeur vers la ligne pour laquelle le dclencheur a t lanc. Il s'agit de la ligne tant insre, mise jour ou efface. Si
ce dclencheur a t lanc pour une commande INSERT ou DELETE, c'est cette valeur que la fonction doit retourner si vous
ne voulez pas remplacer la ligne par une ligne diffrente (dans le cas d'un INSERT) ou sauter l'opration.
tg_newtuple
Un pointeur vers la nouvelle version de la ligne, si le dclencheur a t lanc pour un UPDATE et NULL si c'est pour un INSERT ou un DELETE. C'est ce que la fonction doit retourner si l'vnement est un UPDATE et que vous ne voulez pas remplacer cette ligne par une ligne diffrente ou bien sauter l'opration.
tg_trigger
Un pointeur vers une structure de type Trigger, dfinie dans utils/rel.h :
typedef struct Trigger
{
Oid
tgoid;
char
*tgname;
Oid
tgfoid;
int16
tgtype;
char
tgenabled;
bool
tgisinternal;
Oid
tgconstrrelid;
Oid
tgconstrindid;
Oid
tgconstraint;
bool
tgdeferrable;
bool
tginitdeferred;
int16
tgnargs;
int16
tgnattr;
int16
*tgattr;
char
**tgargs;
char
*tgqual;
} Trigger;
o tgname est le nom du dclencheur, tgnargs est le nombre d'arguments dans tgargs et tgargs est un tableau de
pointeurs vers les arguments spcifis dans l'expression contenant la commande CREATE TRIGGER. Les autres membres
704

Dclencheurs (triggers)

ne sont destins qu' un usage interne.


tg_trigtuplebuf
Le tampon contenant tg_trigtuple ou InvalidBuffer s'il n'existe pas une telle ligne ou si elle n'est pas stocke dans un
tampon du disque.
tg_newtuplebuf
Le tampon contenant tg_newtuple ou InvalidBuffer s'il n'existe pas une telle ligne ou si elle n'est pas stocke dans un tampon du disque.
Une fonction dclencheur doit retourner soit un pointeur HeapTuple soit un pointeur NULL (pas une valeur SQL NULL, donc ne
positionnez pas isNull true). Faites attention de renvoyer soit un tg_trigtuple soit un tg_newtuple, comme appropri, si vous ne voulez pas changer la ligne en cours de modification.

36.4. Un exemple complet de trigger


Voici un exemple trs simple de fonction dclencheur crite en C (les exemples de dclencheurs crits avec diffrents langages de
procdures se trouvent dans la documentation de ceux-ci).
La fonction trigf indique le nombre de lignes de la table ttest et saute l'opration si la commande tente d'insrer une valeur
NULL dans la colonne x (ainsi le dclencheur agit comme une contrainte non NULL mais n'annule pas la transaction).
Tout d'abord, la dfinition des tables :
CREATE TABLE ttest (
x integer
);
Voici le code source de la fonction trigger :
#include "postgres.h"
#include "executor/spi.h"
#include "commands/trigger.h"

/* ncessaire pour fonctionner avec SPI */


/* ... et les dclencheurs */

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
extern Datum trigf(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(trigf);
Datum
trigf(PG_FUNCTION_ARGS)
{
TriggerData *trigdata = (TriggerData *) fcinfo->context;
TupleDesc
tupdesc;
HeapTuple
rettuple;
char
*when;
bool
checkNULL = false;
bool
isNULL;
int
ret, i;
/* on s'assure que la fonction est appele en tant que dclencheur */
if (!CALLED_AS_TRIGGER(fcinfo))
elog(ERROR, "trigf: not called by trigger manager");
/* nuplet retourner l'excuteur */
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
rettuple = trigdata->tg_newtuple;
else
rettuple = trigdata->tg_trigtuple;
/* vrification des valeurs NULL */
if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)
&& TRIGGER_FIRED_BEFORE(trigdata->tg_event))
checkNULL = true;
if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
when = "before";
705

Dclencheurs (triggers)

else
when = "after ";
tupdesc = trigdata->tg_relation->rd_att;
/* connexion au gestionnaire SPI */
if ((ret = SPI_connect()) < 0)
elog(ERROR, "trigf (fired %s): SPI_connect returned %d", when, ret);
/* obtient le nombre de lignes dans la table */
ret = SPI_exec("SELECT count(*) FROM ttest", 0);
if (ret < 0)
elog(ERROR, "trigf (fired %s): SPI_exec returned %d", when, ret);
/* count(*) renvoie int8, prenez garde bien convertir */
i = DatumGetInt64(SPI_getbinval(SPI_tuptable->vals[0],
SPI_tuptable->tupdesc,
1,
&isNULL));
elog (INFO, "trigf (fired %s): there are %d rows in ttest", when, i);
SPI_finish();
if (checkNULL)
{
SPI_getbinval(rettuple, tupdesc, 1, &isNULL);
if (isNULL)
rettuple = NULL;
}
return PointerGetDatum(rettuple);
}
Aprs avoir compil le code source (voir Section 35.9.6, Compiler et lier des fonctions charges dynamiquement ), dclarez la
fonction et les dclencheurs :
CREATE FUNCTION trigf() RETURNS trigger
AS 'nomfichier'
LANGUAGE C;
CREATE TRIGGER tbefore BEFORE INSERT OR UPDATE OR DELETE ON ttest
FOR EACH ROW EXECUTE PROCEDURE trigf();
CREATE TRIGGER tafter AFTER INSERT OR UPDATE OR DELETE ON ttest
FOR EACH ROW EXECUTE PROCEDURE trigf();
prsent, testez le fonctionnement du dclencheur :
=> INSERT INTO ttest VALUES (NULL);
INFO: trigf (fired before): there are 0 rows in ttest
INSERT 0 0
-- Insertion supprime et dclencheur APRES non excut
=> SELECT * FROM ttest;
x
--(0 rows)
=> INSERT INTO ttest VALUES (1);
INFO: trigf (fired before): there are 0 rows in ttest
INFO: trigf (fired after ): there are 1 rows in ttest
^^^^^^^^
souvenez-vous de ce que nous avons dit sur la visibilit.
INSERT 167793 1
vac=> SELECT * FROM ttest;
x
706

Dclencheurs (triggers)

--1
(1 row)
=> INSERT INTO ttest SELECT x * 2 FROM ttest;
INFO: trigf (fired before): there are 1 rows in ttest
INFO: trigf (fired after ): there are 2 rows in ttest
^^^^^^
souvenez-vous de ce que nous avons dit sur la visibilit.
INSERT 167794 1
=> SELECT * FROM ttest;
x
--1
2
(2 rows)
=> UPDATE ttest SET
INFO: trigf (fired
UPDATE 0
=> UPDATE ttest SET
INFO: trigf (fired
INFO: trigf (fired
UPDATE 1
vac=> SELECT * FROM
x
--1
4
(2 rows)

x = NULL WHERE x = 2;
before): there are 2 rows in ttest
x = 4 WHERE x = 2;
before): there are 2 rows in ttest
after ): there are 2 rows in ttest
ttest;

=> DELETE FROM ttest;


INFO: trigf (fired before):
INFO: trigf (fired before):
INFO: trigf (fired after ):
INFO: trigf (fired after ):

there
there
there
there

are
are
are
are

2 rows in ttest
1 rows in ttest
0 rows in ttest
0 rows in ttest
^^^^^^
souvenez-vous de ce que nous avons dit sur la visibilit.

DELETE 2
=> SELECT * FROM ttest;
x
--(0 rows)
Vous trouverez des exemples plus complexes dans src/test/regress/regress.c et dans spi.

707

Chapitre 37. Systme de rgles


Ce chapitre discute du systme de rgles dans PostgreSQL. les systmes de rgles de production sont simples conceptuellement mais il existe de nombreux points subtils impliqus dans leur utilisation.
Certains autres systmes de bases de donnes dfinissent des rgles actives pour la base de donnes, conserves habituellement
en tant que procdures stockes et dclencheurs. Avec PostgreSQL, elles peuvent aussi tre implmentes en utilisant des
fonctions et des dclencheurs.
Le systme de rgles (plus prcisment, le systme de rgles de rcriture de requtes) est totalement diffrent des procdures
stockes et des dclencheurs. Il modifie les requtes pour prendre en considration les rgles puis passe la requte modifie au
planificateur de requtes pour planification et excution. Il est trs puissant et peut tre utilis pour beaucoup de choses comme
des procdures en langage de requtes, des vues et des versions. Les fondations thoriques et la puissance de ce systme de
rgles sont aussi discutes dans Stonebraker et al, ACM, 1990 et Ong and Goh, 1990.

37.1. Arbre de requtes


Pour comprendre comment fonctionne le systme de rgles, il est ncessaire de comprendre quand il est appel et quelles sont
ses entres et sorties.
Le systme de rgles est situ entre l'analyseur et le planificateur. Il prend la sortie de l'analyseur, un arbre de requte et les
rgles de rcriture dfinies par l'utilisateur qui sont aussi des arbres de requtes avec quelques informations supplmentaires, et
cre zro ou plusieurs arbres de requtes comme rsultat. Donc, son entre et sortie sont toujours des lments que l'analyseur
lui-mme pourrait avoir produit et, du coup, tout ce qu'il voit est reprsentable basiquement comme une instruction SQL.
Maintenant, qu'est-ce qu'un arbre de requtes ? C'est une reprsentation interne d'une instruction SQL o les parties qui le
forment sont stockes sparment. Ces arbres de requtes sont affichables dans le journal de traces du serveur si vous avez
configur les paramtres debug_print_parse, debug_print_rewritten, ou debug_print_plan. les actions de
rgles sont aussi enregistres comme arbres de requtes dans le catalogue systme pg_rewrite. elles ne sont pas formates
comme la sortie de traces mais elles contiennent exactement la mme information.
Lire un arbre de requte brut requiert un peu d'exprience. Mais comme les reprsentations SQL des arbres de requtes sont suffisantes pour comprendre le systme de rgles, ce chapitre ne vous apprendra pas les lire.
Lors de la lecture des reprsentations SQL des arbres de requtes dans ce chapitre, il est ncessaire d'tre capable d'identifier les
morceaux casss de l'instruction lorsqu'ils sont dans la structure de l'arbre de requte. Les parties d'un arbre de requtes sont
le type de commande
C'est une simple valeur indiquant quelle commande (select, insert, update, delete) l'arbre de requtes produira.
la table d'chelle
La table d'chelle est une liste des relations utilises dans la requte. Dans une instruction select, ce sont les relations donnes aprs le mot cl from.
Chaque entre de la table d'chelle identifie une table ou une vue et indique par quel nom elle est dsigne dans les autres
parties de la requte. Dans l'arbre de requtes, les entres de la table d'chelle sont rfrences par des numros plutt que
par des noms. Il importe donc peu, ici, de savoir s'il y a des noms dupliqus comme cela peut tre le cas avec une instruction SQL. Cela peut arriver aprs l'assemblage des tables d'chelle des rgles. Les exemples de ce chapitre ne sont pas
confronts cette situation.
la relation rsultat
C'est un index dans la table d'chelle qui identifie la relation o iront les rsultats de la requte.
Les requtes select n'ont pas de relation rsultat. Le cas spcial d'un select into est pratiquement identique un create table
suivi par un insert ... select et n'est pas discut sparment ici.
Pour les commandes insert, update et delete, la relation de rsultat est la table (ou vue !) o les changements prennent effet.
la liste cible
La liste cible est une liste d'expressions dfinissant le rsultat d'une requte. Dans le cas d'un select, ces expressions sont
celles qui construisent la sortie finale de la requte. Ils correspondent aux expressions entre les mots cls select et from (*
est seulement une abrviation pour tous les noms de colonnes d'une relation. Il est tendu par l'analyseur en colonnes individuelles, pour que le systme de rgles ne le voit jamais).
Les commandes delete n'ont pas besoin d'une liste normale de colonnes car elles ne produisent aucun rsultat. En fait, le
708

Systme de rgles

systme de rgles ajoutera une entre spciale ctid pour aller jusqu' la liste de cibles vide pour permettre l'excuteur de
trouver la ligne supprimer. (CTID est ajout quand la relation rsultante est une table ordinaire. S'il s'agit d'une vue, une variable de type ligne est ajoute la place, comme dcrit dans Section 37.2.4, Mise jour d'une vue .)
Pour les commandes insert, la liste cible dcrit les nouvelles lignes devant aller dans la relation rsultat. Elle consiste en des
expressions de la clause values ou en celles de la clause select dans insert ... SELECT. la premire tape du processus de rcriture ajoute les entres de la liste cible pour les colonnes n'ont affectes par la commande originale mais ayant des
valeurs par dfaut. Toute colonne restante (avec soit une valeur donne soit une valeur par dfaut) sera remplie par le planificateur avec une expression NULL constante.
Pour les commandes update, la liste cible dcrit les nouvelles lignes remplaant les anciennes. Dans le systme des rgles,
elle contient seulement les expressions de la partie set colonne = expression de la commande. le planificateur grera les colonnes manquantes en insrant des expressions qui copient les valeurs provenant de l'ancienne ligne dans la nouvelle.
Comme pour DELETE, le systme de rgles ajoute un CTID ou une variable de type ligne pour que l'excuteur puisse identifier l'ancienne ligne mettre jour.
Chaque entre de la liste cible contient une expression qui peut tre une valeur constante, une variable pointant vers une colonne d'une des relations de la table d'chelle, un paramtre ou un arbre d'expressions ralis partir d'appels de fonctions, de
constantes, de variables, d'oprateurs, etc.
la qualification
La qualification de la requte est une expression ressemblant une de celles contenues dans les entres de la liste cible. La valeur rsultant de cette expression est un boolen indiquant si l'opration (insert, update, delete ou select) pour la ligne de rsultat final devrait tre excute ou non. Elle correspond la clause where d'une instruction SQL.
l'arbre de jointure
L'arbre de jointure de la requte affiche la structure de la clause from. pour une simple requte comme select ...
from a, b, c, l'arbre de jointure est une simple liste d'lments de from parce que nous sommes autoriss les joindre
dans tout ordre. Mais quand des expressions join, et plus particulirement les jointures externes, sont utilises, nous devons
les joindre dans l'ordre affich par les jointures. Dans ce cas, l'arbre de jointure affiche la structure des expressions join. les
restrictions associes avec ces clauses join particulires ( partir d'expressions on ou using) sont enregistres comme des
expressions de qualification attaches aux nuds de l'arbre de jointure. Il s'avre agrable d'enregistrer l'expression de haut
niveau where comme une qualification attache l'lment de l'arbre de jointure de haut niveau. Donc, rellement, l'arbre de
jointure reprsente la fois les clauses from et where d'un select.
le reste
Les autres parties de l'arbre de requte comme la clause order BY n'ont pas d'intrt ici. le systme de rgles substitue
quelques entres lors de l'application des rgles mais ceci n'a pas grand chose voir avec les fondamentaux du systme de
rgles.

37.2. Vues et systme de rgles


Avec PostgreSQL, les vues sont implmentes en utilisant le systme de rgles. En fait, il n'y a essentiellement pas de diffrences entre
CREATE VIEW ma_vue AS SELECT * FROM ma_table;
et ces deux commandes :
CREATE TABLE ma_vue (liste de colonnes identique celle de ma_table);
CREATE RULE "_RETURN" AS ON SELECT TO ma_vue DO INSTEAD
SELECT * FROM ma_table;
parce que c'est exactement ce que fait la commande create VIEW en interne. Cela prsente quelques effets de bord. L'un d'entre
eux est que l'information sur une vue dans les catalogues systme PostgreSQL est exactement la mme que celle d'une table.
Donc, pour l'analyseur, il n'y a aucune diffrence entre une table et une vue. Elles reprsentent la mme chose : des relations.

37.2.1. Fonctionnement des rgles select


Les rgles on select sont appliques toutes les requtes comme la dernire tape, mme si la commande donne est un insert, update ou delete. et ils ont des smantiques diffrentes partir des rgles sur les autres types de commandes dans le fait
qu'elles modifient l'arbre de requtes en place au lieu d'en crer un nouveau. Donc, les rgles select sont dcrites avant.
Actuellement, il n'existe qu'une action dans une rgle on SELECT et elle doit tre une action select inconditionnelle qui est
instead. cette restriction tait requise pour rendre les rgles assez sres pour les ouvrir aux utilisateurs ordinaires et cela restreint les rgles on select agir comme des vues.
Pour ce chapitre, les exemples sont deux vues jointes ralisant quelques calculs et quelques vues supplmentaires les utilisant
709

Systme de rgles

leur tour. Une des deux premires vues est personnalise plus tard en ajoutant des rgles pour des oprations insert, update et delete de faon ce que le rsultat final sera une vue qui se comporte comme une vraie table avec quelques fonctionnalits magiques. Il n'existe pas un tel exemple pour commencer et ceci rend les choses plus difficiles obtenir. Mais il est mieux d'avoir un
exemple couvrant tous les points discuts tape par tape plutt que plusieurs exemples, rendant la comprhension plus difficile.
Pour cet exemple, nous avons besoin d'une petite fonction min renvoyant la valeur la plus basse entre deux entiers. Nous la crons
ainsi :
CREATE FUNCTION min(integer, integer) RETURNS integer AS $$
SELECT CASE WHEN $1 < $2 THEN $1 ELSE $2 END
$$' LANGUAGE SQL STRICT;
Les tables relles dont nous avons besoin dans les deux premires descriptions du systme de rgles sont les suivantes :
CREATE TABLE donnees_chaussure (
nom_chaussure
text,
dispo_chaussure
integer,
couleur_chaussure
text,
long_min_chaussure
real,
long_max_chaussure
real,
unite_long_chaussure text
);

-------

cl primaire
nombre de pairs disponibles
couleur de lacet prfre
longueur minimum du lacet
longueur maximum du lacet
unit de longueur

CREATE TABLE donnees_lacet (


nom_lacet
text,
dispo_lacet
integer,
couleur_lacet
text,
longueur_lacet
real,
unite_lacet
text
);

------

cl primaire
nombre de pairs disponibles
couleur du lacet
longueur du lacet
unit de longueur

CREATE TABLE unite (


nom_unite
facteur_unite
);

-- cl primaire
-- facteur pour le transformer en cm

text,
real

Comme vous pouvez le constater, elles reprsentent les donnes d'un magasin de chaussures.
Les vues sont cres avec :
CREATE VIEW chaussure AS
SELECT sh.nom_chaussure,
sh.dispo_chaussure,
sh.couleur_chaussure,
sh.long_min_chaussure,
sh.long_min_chaussure * un.facteur_unite AS long_min_chaussure_cm,
sh.long_max_chaussure,
sh.long_max_chaussure * un.facteur_unite AS long_max_chaussure_cm,
sh.unite_long_chaussure
FROM donnees_chaussure sh, unite un
WHERE sh.unite_long_chaussure = un.nom_unite;
CREATE VIEW lacet AS
SELECT s.nom_lacet,
s.dispo_lacet,
s.couleur_lacet,
s.longueur_lacet,
s.unite_lacet,
s.longueur_lacet * u.facteur_unite AS longueur_lacet_cm
FROM donnees_lacet s, unite u
WHERE s.unite_lacet = u.nom_unite;
CREATE VIEW chaussure_prete AS
SELECT rsh.nom_chaussure,
rsh.dispo_chaussure,
rsl.nom_lacet,
rsl.dispo_lacet,
min(rsh.dispo, rsl.dispo_lacet) AS total_avail
FROM chaussure rsh, lacet rsl
WHERE rsl.couleur_lacet = rsh.couleur
AND rsl.longueur_lacet_cm >= rsh.long_min_chaussure_cm
710

Systme de rgles

AND rsl.longueur_lacet_cm <= rsh.long_max_chaussure_cm;


La commande create view pour la vue lacet (qui est la plus simple que nous avons) crira une relation lacet et une entre
dans pg_rewrite indiquant la prsence d'une rgle de rcriture devant tre applique chaque fois que la relation lacet est rfrence dans une table de la requte. La rgle n'a aucune qualification de rgle (discut plus tard, avec les rgles autres que select
car les rgles select ne le sont pas encore) et qu'il s'agit de instead. notez que les qualifications de rgles ne sont pas identiques
aux qualifications de requtes. L'action de notre rgle a une qualification de requte. L'action de la rgle a un arbre de requte qui
est une copie de l'instruction select dans la commande de cration de la vue.

Note
Les deux entres supplmentaires de la table d'chelle pour new et old que vous pouvez voir dans l'entre de
pg_rewrite ne sont d'aucun intrt pour les rgles select.
Maintenant, nous remplissons unit, donnees_chaussure et donnees_lacet, puis nous lanons une requte simple sur
une vue :
INSERT INTO unite VALUES ('cm', 1.0);
INSERT INTO unite VALUES ('m', 100.0);
INSERT INTO unite VALUES ('inch', 2.54);
INSERT
INSERT
INSERT
INSERT

INTO
INTO
INTO
INTO

donnees_chaussure
donnees_chaussure
donnees_chaussure
donnees_chaussure

INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT

INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO

donnees_lacet
donnees_lacet
donnees_lacet
donnees_lacet
donnees_lacet
donnees_lacet
donnees_lacet
donnees_lacet

VALUES
VALUES
VALUES
VALUES

VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES

('sh1',
('sh2',
('sh3',
('sh4',

('sl1',
('sl2',
('sl3',
('sl4',
('sl5',
('sl6',
('sl7',
('sl8',

5,
6,
0,
8,
4,
0,
7,
1,

2,
0,
4,
3,

'black',
'black',
'brown',
'brown',

'black',
'black',
'black',
'black',
'brown',
'brown',
'brown',
'brown',

70.0,
30.0,
50.0,
40.0,

90.0,
40.0,
65.0,
50.0,

'cm');
'inch');
'cm');
'inch');

80.0, 'cm');
100.0, 'cm');
35.0 , 'inch');
40.0 , 'inch');
1.0 , 'm');
0.9 , 'm');
60 , 'cm');
40 , 'inch');

SELECT * FROM lacet;

nom_lacet
| dispo_lacet | couleur_lacet | longueur_lacet | unite_lacet |
longueur_lacet_cm
-------------+-------------+---------------+----------------+-------------+----------------sl1
|
5 | black
|
80 | cm
|
80
sl2
|
6 | black
|
100 | cm
|
100
sl7
|
7 | brown
|
60 | cm
|
60
sl3
|
0 | black
|
35 | inch
|
88.9
sl4
|
8 | black
|
40 | inch
|
101.6
sl8
|
1 | brown
|
40 | inch
|
101.6
sl5
|
4 | brown
|
1 | m
|
100
sl6
|
0 | brown
|
0.9 | m
|
90
(8 rows)
C'est la requte select la plus simple que vous pouvez lancer sur nos vues, donc nous prenons cette opportunit d'expliquer les
bases des rgles de vues. select * from lacet a t interprt par l'analyseur et a produit l'arbre de requte :
SELECT lacet.nom_lacet, lacet.dispo_lacet,
lacet.couleur_lacet, lacet.longueur_lacet,
lacet.unite_lacet, lacet.longueur_lacet_cm
FROM lacet lacet;
et ceci est transmis au systme de rgles. Ce systme traverse la table d'chelle et vrifie s'il existe des rgles pour chaque relation.
Lors du traitement d'une entre de la table d'chelle pour lacet (la seule jusqu' maintenant), il trouve la rgle _return avec
711

Systme de rgles

l'arbre de requte :
SELECT s.nom_lacet, s.dispo_lacet,
s.couleur_lacet, s.longueur_lacet, s.unite_lacet,
s.longueur_lacet * u.facteur_unite AS longueur_lacet_cm
FROM lacet old, lacet new,
donnees_lacet s, unit u
WHERE s.unite_lacet = u.nom_unite;
Pour tendre la vue, la rcriture cre simplement une entre de la table d'chelle de sous-requte contenant l'arbre de requte de
l'action de la rgle et substitue cette entre avec l'original rfrenc dans la vue. L'arbre d'chelle rsultant de la rcriture est pratiquement identique celui que vous avez saisi :
SELECT lacet.nom_lacet, lacet.dispo_lacet,
lacet.couleur_lacet, lacet.longueur_lacet,
lacet.unite_lacet, lacet.longueur_lacet_cm
FROM (SELECT s.nom_lacet,
s.dispo_lacet,
s.couleur_lacet,
s.longueur_lacet,
s.unite_lacet,
s.longueur_lacet * u.facteur_unite AS longueur_lacet_cm
FROM donnees_lacet s, unit u
WHERE s.unite_lacet = u.nom_unite) lacet;
Nanmoins, il y a une diffrence : la table d'chelle de la sous-requte a deux entres supplmentaires, lacet old et lacet
new. ces entres ne participent pas directement dans la requte car elles ne sont pas rfrences par l'arbre de jointure de la sousrequte ou par la liste cible. La rcriture les utilise pour enregistrer l'information de vrification des droits d'accs qui taient prsents l'origine dans l'entre de table d'chelle rfrence par la vue. De cette faon, l'excution vrifiera toujours que l'utilisateur
a les bons droits pour accder la vue mme s'il n'y a pas d'utilisation directe de la vue dans la requte rcrite.
C'tait la premire rgle applique. Le systme de rgles continuera de vrifier les entres restantes de la table d'chelle dans la requte principale (dans cet exemple, il n'en existe pas plus), et il vrifiera rcursivement les entres de la table d'chelle dans la
sous-requte ajoute pour voir si une d'elle rfrence les vues. (Mais il n'tendra ni old ni new -- sinon nous aurions une rcursion infinie !) Dans cet exemple, il n'existe pas de rgles de rcriture pour donnees_lacet ou unit, donc la rcriture est termine et ce qui est ci-dessus est le rsultat final donn au planificateur.
Maintenant, nous voulons crire une requte qui trouve les chaussures en magasin dont nous avons les lacets correspondants
(couleur et longueur) et pour lesquels le nombre total de pairs correspondants exactement est suprieur ou gal deux.
SELECT * FROM chaussure_prete WHERE total_avail >= 2;
nom_chaussure | dispo | nom_lacet | dispo_lacet | total_avail
---------------+-------+-----------+-------------+------------sh1
|
2 | sl1
|
5 |
2
sh3
|
4 | sl7
|
7 |
4
(2 rows)
Cette fois, la sortie de l'analyseur est l'arbre de requte :
SELECT chaussure_prete.nom_chaussure, chaussure_prete.dispo,
chaussure_prete.nom_lacet, chaussure_prete.dispo_lacet,
chaussure_prete.total_avail
FROM chaussure_prete chaussure_prete
WHERE chaussure_prete.total_avail >= 2;
La premire rgle applique sera celle de la vue chaussure_prete et cela rsultera en cet arbre de requte :
SELECT chaussure_prete.nom_chaussure, chaussure_prete.dispo,
chaussure_prete.nom_lacet, chaussure_prete.dispo_lacet,
chaussure_prete.total_avail
FROM (SELECT rsh.nom_chaussure,
rsh.dispo,
rsl.nom_lacet,
rsl.dispo_lacet,
min(rsh.dispo, rsl.dispo_lacet) AS total_avail
FROM chaussure rsh, lacet rsl
WHERE rsl.couleur_lacet = rsh.couleur
AND rsl.longueur_lacet_cm >= rsh.long_min_chaussure_cm
AND rsl.longueur_lacet_cm <= rsh.long_max_chaussure_cm) chaussure_prete
WHERE chaussure_prete.total_avail >= 2;
712

Systme de rgles

De faon similaire, les rgles pour chaussure et lacet sont substitues dans la table d'chelle de la sous-requte, amenant
l'arbre de requte final trois niveaux :
SELECT chaussure_prete.nom_chaussure, chaussure_prete.dispo,
chaussure_prete.nom_lacet, chaussure_prete.dispo_lacet,
chaussure_prete.total_avail
FROM (SELECT rsh.nom_chaussure,
rsh.dispo,
rsl.nom_lacet,
rsl.dispo_lacet,
min(rsh.dispo, rsl.dispo_lacet) AS total_avail
FROM (SELECT sh.nom_chaussure,
sh.dispo,
sh.couleur,
sh.long_min_chaussure,
sh.long_min_chaussure * un.facteur_unite AS
long_min_chaussure_cm,
sh.long_max_chaussure,
sh.long_max_chaussure * un.facteur_unite AS
long_max_chaussure_cm,
sh.unite_long_chaussure
FROM donnees_chaussure sh, unit un
WHERE sh.unite_long_chaussure = un.nom_unite) rsh,
(SELECT s.nom_lacet,
s.dispo_lacet,
s.couleur_lacet,
s.longueur_lacet,
s.unite_lacet,
s.longueur_lacet * u.facteur_unite AS longueur_lacet_cm
FROM donnees_lacet s, unit u
WHERE s.unite_lacet = u.nom_unite) rsl
WHERE rsl.couleur_lacet = rsh.couleur
AND rsl.longueur_lacet_cm >= rsh.long_min_chaussure_cm
AND rsl.longueur_lacet_cm <= rsh.long_max_chaussure_cm) chaussure_prete
WHERE chaussure_prete.total_avail > 2;
Il s'avre que le planificateur rduira cet arbre en un arbre de requte deux niveaux : les commandes select du bas seront
remontes dans le select du milieu car il n'est pas ncessaire de les traiter sparment. Mais le select du milieu restera spar
du haut car il contient des fonctions d'agrgat. Si nous les avions mont, cela aurait modifi le comportement du select de haut niveau, ce qui n'est pas ce que nous voulons. Nanmoins, rduire l'arbre de requte est une optimisation qui ne concerne pas le systme de rcriture.

37.2.2. Rgles de vue dans des instructions autres que select


Deux dtails de l'arbre de requte n'ont pas t abords dans la description des rgles de vue ci-dessus. Ce sont le type de commande et le relation rsultante. En fait, le type de commande n'est pas ncessaire pour les rgles de la vue mais la relation rsultante pourrait affecter la faon dont la requte sera rcrite car une attention particulire doit tre prise si la relation rsultante est
une vue.
Il existe seulement quelques diffrences entre un arbre de requte pour un select et un pour une autre commande. de faon vidente, ils ont un type de commande diffrent et pour une commande autre qu' un select, la relation rsultante pointe vers l'entre
de table d'chelle o le rsultat devrait arriver. Tout le reste est absolument identique. Donc, avec deux tables t1 et t2 avec les
colonnes a et b, les arbres de requtes pour les deux commandes :
SELECT t2.b FROM t1, t2 WHERE t1.a = t2.a;
UPDATE t1 SET b = t2.b FROM t2 WHERE t1.a = t2.a;
sont pratiquement identiques. En particulier :

Les tables d'chelle contiennent des entres pour les tables t1 et t2.

Les listes cibles contiennent une variable pointant vers la colonne b de l'entre de la table d'chelle pour la table t2.

Les expressions de qualification comparent les colonnes a des deux entres de table d'chelle pour une galit.

Les arbres de jointure affichent une jointure simple entre t1 et t2.

713

Systme de rgles

La consquence est que les deux arbres de requte rsultent en des plans d'excution similaires : ce sont tous les deux des jointures
sur les deux tables. Pour l'update, les colonnes manquantes de t1 sont ajoutes la liste cible par le planificateur et l'arbre de requte final sera lu de cette faon :
UPDATE t1 SET a = t1.a, b = t2.b FROM t2 WHERE t1.a = t2.a;
et, du coup, l'excuteur lanc sur la jointure produira exactement le mme rsultat qu'un :
SELECT t1.a, t2.b FROM t1, t2 WHERE t1.a = t2.a;
Mais il existe un petit problme dans UPDATE : la partie du plan d'excution qui fait la jointure ne prte pas attention l'intrt
des rsultats de la jointure. Il produit un ensemble de lignes. Le fait qu'il y a une commande SELECT et une commande UPDATE est gr plus haut dans l'excuteur o cette partie sait qu'il s'agit d'une commande UPDATE, et elle sait que ce rsultat va
aller dans la table t1. Mais lesquels de ces lignes vont tre remplaces par la nouvelle ligne ?
Pour rsoudre ce problme, une autre entre est ajoute dans la liste cible de l'update (et aussi dans les instructions delete) :
l'identifiant actuel du tuple (ctid, acronyme de current tuple ID). cette colonne systme contient le numro de bloc du fichier et la
position dans le bloc pour cette ligne. Connaissant la table, le ctid peut tre utilis pour rcuprer la ligne originale de t1 mettre
jour. aprs avoir ajout le ctid dans la liste cible, la requte ressemble ceci :
SELECT t1.a, t2.b, t1.ctid FROM t1, t2 WHERE t1.a = t2.a;
Maintenant, un autre dtail de PostgreSQL entre en jeu. Les anciennes lignes de la table ne sont pas surcharges et cela explique
pourquoi rollback est rapide. avec un update, la nouvelle ligne rsultat est insre dans la table (aprs avoir enlev le ctid) et,
dans le nouvel en-tte de ligne de l'ancienne ligne, vers o pointe le ctid, les entres cmax et xmax sont configures par le compteur de commande actuel et par l'identifiant de transaction actuel. Du coup, l'ancienne ligne est cache et, aprs validation de la
transaction, le nettoyeur (vacuum) peut ventuellement la supprimer.
Connaissant tout ceci, nous pouvons simplement appliquer les rgles de vues de la mme faon que toute autre commande. Il n'y a
pas de diffrence.

37.2.3. Puissance des vues dans PostgreSQL


L'exemple ci-dessus dmontre l'incorporation des dfinitions de vues par le systme de rgles dans l'arbre de requte original.
Dans le deuxime exemple, un simple select d'une vue a cr un arbre de requte final qui est une jointure de quatre tables (unit
a t utilis deux fois avec des noms diffrents).
Le bnfice de l'implmentation des vues avec le systme de rgles est que le planificateur a toute l'information sur les tables
parcourir et sur les relations entre ces tables et les qualifications restrictives partir des vues et les qualifications partir de la requte originale dans un seule arbre de requte. Et c'est toujours la situation quand la requte originale est dj une jointure sur des
vues. Le planificateur doit dcider du meilleur chemin pour excuter la requte et plus le planificateur a d'informations, meilleure
sera la dcision. Le systme de rgles implment dans PostgreSQL s'en assure, c'est toute l'information disponible sur la requte ce moment.

37.2.4. Mise jour d'une vue


Qu'arrive-t'il si une vue est nomme comme la relation cible d'un insert, update ou delete ? Faire simplement les substitutions dcrites ci-dessus donnerait un arbre de requtes dont le rsultat pointerait vers une entre de la table en sous-requte. Cela ne fonctionnera pas. la place, la rcriture assume que l'opration sera gre par un trigger INSTEAD OF sur la vue. (Si un tel trigger
n'existe pas, l'excuteur renverra une erreur quand l'excution commence.) La rcriture fonctionne lgrement diffremment dans
ce cas. Pour INSERT, la rcriture ne fait rien du tout avec la vue, la laissant comme relation rsultante de la requte. Pour UPDATE et DELETE, il est toujours ncessaire d'tendre la requte de la vue pour rcuprer les anciennes lignes que la commande va essayer de mettre jour ou supprimer. Donc la vue est tendue comme d'ahbitude mais une autre entre de table non
tendue est ajoute la requte pour reprsenter la vue en tant que relation rsultante.
Le problme qui survient maintenant est d'identifier les lignes mettre jour dans la vue. Rappelez-vous que, quand la relation rsultante est une table, une entre CTID spciale est ajoute la liste cible pour identifier les emplacements physiques des lignes
mettre jour. Ceci ne fonctionne pas si la relation rsultante est une vue car une vue n'a pas de CTID, car ses lignes n'ont pas
d'emplacements physiques rels. la place, pour une opration UPDATE ou DELETE, une entre wholerow (ligne complte)
spciale est ajoute la liste cible, qui s'tend pour inclure toutes les colonnes d'une vue. L'excuteur utilise cette valeur pour fournir l' ancienne ligne au trigger INSTEAD OF. C'est au trigger de savoir ce que la mise jour est suppose faire sur les valeurs
des anciennes et nouvelles lignes.
S'il n'y a pas de triggers INSTEAD OF pour mettre jour la vue, l'excuteur va afficher une erreur car il ne peut pas mettre jour
la vue automatiquement de lui-mme. Pour modifier cela, nous pouvons dfinir des rgles qui modifient le comportement des
commandes INSERT, UPDATE et DELETE sur une vue. Ces rgles vont rcrire la commande, typiquement en une commande
qui met jour une ou plusieurs tables, plutt que des vues. C'est le thme de la section suivante.

714

Systme de rgles

Notez que les rgles sont values en premier, rcrivant la requte originale avant qu'elle ne soit optimise et excute. Du coup,
si une vue a des triggers INSTEAD OF en plus de rgles sur INSERT, UPDATE ou DELETE, alors les rgles seront values
en premier et, suivant le rsultat, les triggers pourraient tre utiliss.

37.3. Rgles sur insert, update et delete


Les rgles dfinies sur insert, update et delete sont significativement diffrentes des rgles de vue dcrites dans la section prcdente. Tout d'abord, leur commande create rule permet plus de choses :

Elles peuvent n'avoir aucune action.

Elles peuvent avoir plusieurs actions.

Elles peuvent tre de type instead ou also (valeur par dfaut).

Les pseudo relations new et old deviennent utiles.

Elles peuvent avoir des qualifications de rgles.

Ensuite, elles ne modifient pas l'arbre de requte en place. la place, elles crent de nouveaux arbres de requtes et peuvent abandonner l'original.

37.3.1. Fonctionnement des rgles de mise jour


Gardez en tte la syntaxe :
CREATE [ OR REPLACE ] RULE nom as on evenement
TO table [ where condition ]
DO [ ALSO | INSTEAD ] { NOTHING | commande | ( commande ; commande ... ) }
Dans la suite, rgles de mise jour signifie les rgles qui sont dfinies sur insert, update ou delete.
Les rgles de mise jour sont appliques par le systme de rgles lorsque la relation rsultante et le type de commande d'un arbre
de requte sont gaux pour l'objet et l'vnement donn dans la commande create RULE. pour les rgles de mise jour, le systme de rgles cre une liste d'arbres de requtes. Initialement, la liste d'arbres de requtes est vide. Il peut y avoir aucune (mot cl
nothing), une ou plusieurs actions. Pour simplifier, nous verrons une rgle avec une action. Cette rgle peut avoir une qualification et peut tre de type instead ou also (valeur par dfaut).
Qu'est-ce qu'une qualification de rgle ? C'est une restriction indiquant le moment o doivent tre raliss les actions de la rgle.
Cette qualification peut seulement rfrencer les pseudo relations new et/ou old, qui reprsentent basiquement la relation qui a
t donn comme objet (mais avec une signification spciale).
Donc, nous avons trois cas qui produisent les arbres de requtes suivants pour une rgle une seule action.
sans qualification avec soit ALSO soit INSTEAD
l'arbre de requte partir de l'action de la rgle avec l'ajout de la qualification de l'arbre de requte original
qualification donne et also
l'arbre de requte partir de l'action de la rgle avec l'ajout de la qualification de la rgle et de la qualification de l'arbre de requte original
qualification donne avec instead
l'arbre de requte partir de l'action de la rgle avec la qualification de la requte et la qualification de l'arbre de requte original ; et l'ajout de l'arbre de requte original avec la qualification inverse de la rgle
Enfin, si la rgle est also, l'arbre de requte original est ajout la liste. Comme seules les rgles qualifies instead ont dj
ajout l'arbre de requte original, nous finissons avec un ou deux arbres de requte en sortie pour une rgle avec une action.
Pour les rgles on insert, la requte originale (si elle n'est pas supprime par instead) est ralise avant toute action ajoute
par les rgles. Ceci permet aux actions de voir les lignes insres. Mais pour les rgles on update et on delete, la requte
originale est ralise aprs les actions ajoutes par les rgles. Ceci nous assure que les actions pourront voir les lignes mettre
jour ou supprimer ; sinon, les actions pourraient ne rien faire parce qu'elles ne trouvent aucune ligne correspondant leurs qualifications.
Les arbres de requtes gnrs partir des actions de rgles sont envoys de nouveau dans le systme de rcriture et peut-tre que
d'autres rgles seront appliques rsultant en plus ou moins d'arbres de requtes. Donc, les actions d'une rgle doivent avoir soit un
type de commande diffrent soit une relation rsultante diffrente de celle o la rgle elle-mme est active, sinon ce processus rcursif se terminera dans une boucle infinie. (L'expansion rcursive d'une rgle sera dtecte et rapporte comme une erreur.)
Les arbres de requte trouvs dans les actions du catalogue systme pg_rewrite sont seulement des modles. comme ils peuvent
715

Systme de rgles

rfrencer les entres de la table d'chelle pour new et old, quelques substitutions ont d tre faites avant qu'elles ne puissent tre
utilises. Pour toute rfrence de new, une entre correspondante est recherche dans la liste cible de la requte originale. Si elle
est trouve, cette expression de l'entre remplace la rfrence. Sinon, new signifie la mme chose que old (pour un update) ou
est remplac par une valeur null (pour un insert). toute rfrence old est remplace par une rfrence l'entre de la table
d'chelle qui est la relation rsultante.
Aprs que le systme a termin d'appliquer des rgles de mise jour, il applique les rgles de vues pour le(s) arbre(s) de requte
produit(s). Les vues ne peuvent pas insrer de nouvelles actions de mise jour, donc il n'est pas ncessaire d'appliquer les rgles
de mise jour la sortie d'une rcriture de vue.

37.3.1.1. Une premire requte tape par tape


Disons que nous voulons tracer les modifications dans la colonne dispo_lacet de la relation donnees_lacet. donc, nous
allons configurer une table de traces et une rgle qui va crire une entre lorsqu'un update est lanc sur donnees_lacet.
CREATE TABLE lacet_log (
nom_lacet
text,
dispo_lacet
integer,
log_who
text,
log_when
timestamp
);

-- modification de lacet
-- nouvelle valeur disponible
-- qui l'a modifi
-- quand

CREATE RULE log_lacet AS ON UPDATE TO donnees_lacet


WHERE NEW.dispo_lacet <> OLD.dispo_lacet
DO INSERT INTO lacet_log VALUES (
NEW.nom_lacet,
NEW.dispo_lacet,
current_user,
current_timestamp
);
Maintenant, quelqu'un excute :
UPDATE donnees_lacet SET dispo_lacet = 6 WHERE nom_lacet = 'sl7';
et voici le contenu de la table des traces :
SELECT * FROM lacet_log;
nom_lacet | dispo_lacet | log_who | log_when
-----------+-------------+---------+---------------------------------sl7
|
6 | Al
| Tue Oct 20 16:14:45 1998 MET DST
(1 row)
C'est ce quoi nous nous attendions. Voici ce qui s'est pass en tche de fond. L'analyseur a cr l'arbre de requte :
UPDATE donnees_lacet SET dispo_lacet = 6
FROM donnees_lacet donnees_lacet
WHERE donnees_lacet.nom_lacet = 'sl7';
Il existe une rgle log_lacet qui est on UPDATE avec l'expression de qualification de la rgle :
NEW.dispo_lacet <> OLD.dispo_lacet
et l'action :
INSERT INTO lacet_log VALUES (
new.nom_lacet, new.dispo_lacet,
current_user, current_timestamp )
FROM donnees_lacet new, donnees_lacet old;
(ceci semble un peu trange car, normalement, vous ne pouvez pas crire insert ... values ... from. ici, la clause
from indique seulement qu'il existe des entres de la table d'chelle dans l'arbre de requte pour new et old. elles sont ncessaires pour qu'elles puissent tre rfrences par des variables dans l'arbre de requte de la commande insert).
La rgle est une rgle qualifie also de faon ce que le systme de rgles doit renvoyer deux arbres de requtes : l'action de la
rgle modifie et l'arbre de requte original. Dans la premire tape, la table d'chelle de la requte originale est incorpore dans
l'arbre de requte d'action de la rgle. Ceci a pour rsultat :
INSERT INTO lacet_log VALUES (
new.nom_lacet, new.dispo_lacet,
current_user, current_timestamp )
716

Systme de rgles

FROM donnees_lacet new, donnees_lacet old,


donnees_lacet donnees_lacet;
Pour la deuxime tape, la qualification de la rgle lui est ajoute, donc l'ensemble de rsultat est restreint aux lignes o dispo_lacet a chang :
INSERT INTO lacet_log VALUES (
new.nom_lacet, new.dispo_lacet,
current_user, current_timestamp )
FROM donnees_lacet new, donnees_lacet old,
donnees_lacet donnees_lacet
where new.dispo_lacet <> old.dispo_lacet;
(Ceci semble encore plus trange car insert ... values n'a pas non plus une clause where mais le planificateur et
l'excuteur n'auront pas de difficults avec a. Ils ont besoin de supporter cette mme fonctionnalit pour insert ... select.)
l'tape 3, la qualification de l'arbre de requte original est ajoute, restreignant encore plus l'ensemble de rsultats pour les
seules lignes qui auront t modifies par la requte originale :
INSERT INTO lacet_log VALUES (
new.nom_lacet, new.dispo_lacet,
current_user, current_timestamp )
FROM donnees_lacet new, donnees_lacet old,
donnees_lacet donnees_lacet
WHERE new.dispo_lacet <> old.dispo_lacet
and donnees_lacet.nom_lacet = 'sl7';
La quatrime tape remplace les rfrences new par les entres de la liste cible partir de l'arbre de requte original ou par les
rfrences de la variable correspondante partir de la relation rsultat :
INSERT INTO lacet_log VALUES (
donnees_lacet.nom_lacet, 6,
current_user, current_timestamp )
FROM donnees_lacet new, donnees_lacet old,
donnees_lacet donnees_lacet
WHERE 6 <> old.dispo_lacet
AND donnees_lacet.nom_lacet = 'sl7';
L'tape 5 modifie les rfrences old en rfrence de la relation rsultat :
INSERT INTO lacet_log VALUES (
donnees_lacet.nom_lacet, 6,
current_user, current_timestamp )
FROM donnees_lacet new, donnees_lacet old,
donnees_lacet donnees_lacet
WHERE 6 <> donnees_lacet.dispo_lacet
AND donnees_lacet.nom_lacet = 'sl7';
C'est tout. Comme la rgle est de type also, nous affichons aussi l'arbre de requtes original. En bref, l'affichage partir du systme de rgles est une liste de deux arbres de requtes est une liste de deux arbres de requtes correspondant ces instructions :
INSERT INTO lacet_log VALUES (
donnees_lacet.nom_lacet, 6,
current_user, current_timestamp )
FROM donnees_lacet
WHERE 6 <> donnees_lacet.dispo_lacet
AND donnees_lacet.nom_lacet = 'sl7';
UPDATE donnees_lacet SET dispo_lacet = 6
WHERE nom_lacet = 'sl7';
Elles sont excutes dans cet ordre et c'est exactement le but de la rgle.
Les substitutions et les qualifications ajoutes nous assurent que, si la requte originale tait :
UPDATE donnees_lacet SET couleur_lacet = 'green'
WHERE nom_lacet = 'sl7';
aucune trace ne serait crite. Dans ce cas, l'arbre de requte original ne contient pas une entre dans la liste cible pour dispo_lacet, donc new.dispo_lacet sera remplac par donnees_lacet.dispo_lacet. Du coup, la commande supplmentaire gnre par la rgle est :
717

Systme de rgles

INSERT INTO lacet_log VALUES (


donnees_lacet.nom_lacet, donnees_lacet.dispo_lacet,
current_user, current_timestamp )
FROM donnees_lacet
WHERE donnees_lacet.dispo_lacet <> donnees_lacet.dispo_lacet
AND donnees_lacet.nom_lacet = 'sl7';
et la qualification ne sera jamais vraie.
Si la requte originale modifie plusieurs lignes, cela fonctionne aussi. Donc, si quelqu'un a lanc la commande :
UPDATE donnees_lacet SET dispo_lacet = 0
WHERE couleur_lacet = 'black';
en fait, quatre lignes sont modifies (sl1, sl2, sl3 et sl4). mais sl3 a dj dispo_lacet = 0. dans ce cas, la qualification des arbres de requtes originaux sont diffrents et cela produit un arbre de requte supplmentaire :
INSERT INTO lacet_log
SELECT donnees_lacet.nom_lacet, 0,
current_user, current_timestamp
FROM donnees_lacet
WHERE 0 <> donnees_lacet.dispo_lacet
AND donnees_lacet.couleur_lacet = 'black';
gnrer par la rgle. Cet arbre de requte aura srement insr trois nouvelles lignes de traces. Et c'est tout fait correct.
Ici, nous avons vu pourquoi il est important que l'arbre de requte original soit excut en premier. Si l'update a t excut avant,
toutes les lignes pourraient aussi tre initialises zro, donc le insert trac ne trouvera aucune ligne 0 <> donnees_lacet.dispo_lacet.

37.3.2. Coopration avec les vues


Une faon simple de protger les vues d'une excution d'insert, d'update ou de delete sur elles est de laisser s'abandonner ces
arbres de requte. Donc, nous pourrions crer les rgles :
CREATE
DO
CREATE
DO
CREATE
DO

RULE chaussure_ins_protect AS ON INSERT TO chaussure


INSTEAD NOTHING;
RULE chaussure_upd_protect AS ON UPDATE TO chaussure
INSTEAD NOTHING;
RULE chaussure_del_protect AS ON DELETE TO chaussure
INSTEAD NOTHING;

Maintenant, si quelqu'un essaie de faire une de ces oprations sur la vue chaussure, le systme de rgles appliquera ces rgles.
Comme les rgles n'ont pas d'action et sont de type instead, la liste rsultante des arbres de requtes sera vide et la requte entire deviendra vide car il ne reste rien optimiser ou excuter aprs que le systme de rgles en ait termin avec elle.
Une faon plus sophistique d'utiliser le systme de rgles est de crer les rgles qui rcrivent l'arbre de requte en un arbre faisant la bonne opration sur les vraies tables. Pour raliser cela sur la vue lacet, nous crons les rgles suivantes :
CREATE RULE lacet_ins AS ON INSERT TO lacet
DO INSTEAD
INSERT INTO donnees_lacet VALUES (
NEW.nom_lacet,
NEW.dispo_lacet,
NEW.couleur_lacet,
NEW.longueur_lacet,
NEW.unite_lacet
);
CREATE RULE lacet_upd AS ON UPDATE TO lacet
DO INSTEAD
UPDATE donnees_lacet
SET nom_lacet = NEW.nom_lacet,
dispo_lacet = NEW.dispo_lacet,
couleur_lacet = NEW.couleur_lacet,
longueur_lacet = NEW.longueur_lacet,
unite_lacet = NEW.unite_lacet
WHERE nom_lacet = OLD.nom_lacet;
CREATE RULE lacet_del AS ON DELETE TO lacet
DO INSTEAD
DELETE FROM donnees_lacet
718

Systme de rgles

WHERE nom_lacet = OLD.nom_lacet;


Si vous voulez supporter les requtes RETURNING sur la vue, vous devrez faire en sorte que les rgles incluent les clauses RETURNING qui calcule les lignes de la vue. Ceci est assez simple pour des vues sur une seule table mais cela devient rapidement
complexe pour des vues de jointure comme lacet. Voici un exemple pour le cas d'un INSERT :
CREATE RULE lacet_ins AS ON INSERT TO lacet
DO INSTEAD
INSERT INTO donnees_lacet VALUES (
NEW.nom_lacet,
NEW.dispo_lacet,
NEW.couleur_lacet,
NEW.longueur_lacet,
NEW.unite_lacet
)
RETURNING
donnees_lacet.*,
(SELECT donnees_lacet.longueur_lacet * u.facteur_unite
FROM unite u WHERE donnees_lacet.unite_lacet = u.nom_unite);
Notez que cette seule rgle supporte la fois les INSERT et les INSERT RETURNING sur la vue -- la clause RETURNING est
tout simplement ignor pour un INSERT.
Maintenant, supposons que, quelque fois, un paquet de lacets arrive au magasin avec une grosse liste. Mais vous ne voulez pas
mettre jour manuellement la vue lacet chaque fois. la place, nous configurons deux petites tables, une o vous pouvez insrer les lments de la liste et une avec une astuce spciale. Voici les commandes de cration :
CREATE TABLE lacet_arrive (
arr_name
text,
arr_quant
integer
);
CREATE TABLE lacet_ok (
ok_name
text,
ok_quant
integer
);
CREATE RULE lacet_ok_ins AS ON INSERT TO lacet_ok
DO INSTEAD
UPDATE lacet
SET dispo_lacet = dispo_lacet + NEW.ok_quant
WHERE nom_lacet = NEW.ok_name;
Maintenant, vous pouvez remplir la table lacet_arrive avec les donnes de la liste :
SELECT * FROM lacet_arrive;
arr_name | arr_quant
----------+----------sl3
|
10
sl6
|
20
sl8
|
20
(3 rows)
Jetez un il rapidement aux donnes actuelles :
SELECT * FROM lacet;

nom_lacet | dispo_lacet | couleur_lacet | longueur_lacet | unite_lacet |


longueur_lacet_cm
------------+-------------+---------------+----------------+-------------+-----------------sl1
|
5 | black
|
80 | cm
|
80
sl2
|
6 | black
|
100 | cm
|
100
sl7
|
6 | brown
|
60 | cm
|
60
sl3
|
0 | black
|
35 | inch
|
88.9
sl4
|
8 | black
|
40 | inch
|
101.6
719

Systme de rgles

sl8
101.6
sl5
100
sl6
90
(8 rows)

1 | brown

40 | inch

4 | brown

1 | m

0 | brown

0.9 | m

Maintenant, dplacez les lacets arrivs dans :


INSERT INTO lacet_ok SELECT * FROM lacet_arrive;
et vrifiez le rsultat :
SELECT * FROM lacet ORDER BY nom_lacet;

nom_lacet | dispo_lacet | couleur_lacet | longueur_lacet | unite_lacet |


longueur_lacet_cm
------------+-------------+---------------+----------------+-------------+-----------------sl1
|
5 | black
|
80 | cm
|
80
sl2
|
6 | black
|
100 | cm
|
100
sl7
|
6 | brown
|
60 | cm
|
60
sl4
|
8 | black
|
40 | inch
|
101.6
sl3
|
10 | black
|
35 | inch
|
88.9
sl8
|
21 | brown
|
40 | inch
|
101.6
sl5
|
4 | brown
|
1 | m
|
100
sl6
|
20 | brown
|
0.9 | m
|
90
(8 rows)
SELECT * FROM lacet_log;
nom_lacet | dispo_lacet | log_who| log_when
-----------+-------------+--------+---------------------------------sl7
|
6 | Al
| Tue Oct 20 19:14:45 1998 MET DST
sl3
|
10 | Al
| Tue Oct 20 19:25:16 1998 MET DST
sl6
|
20 | Al
| Tue Oct 20 19:25:16 1998 MET DST
sl8
|
21 | Al
| Tue Oct 20 19:25:16 1998 MET DST
(4 rows)
C'est un long chemin du insert ... select ces rsultats. Et la description de la transformation de l'arbre de requtes sera
la dernire dans ce chapitre. Tout d'abord, voici la sortie de l'analyseur :
INSERT INTO lacet_ok
SELECT lacet_arrive.arr_name, lacet_arrive.arr_quant
FROM lacet_arrive lacet_arrive, lacet_ok lacet_ok;
Maintenant, la premire rgle lacet_ok_ins est applique et transforme ceci en :
UPDATE lacet
SET dispo_lacet = lacet.dispo_lacet + lacet_arrive.arr_quant
FROM lacet_arrive lacet_arrive, lacet_ok lacet_ok,
lacet_ok old, lacet_ok new,
lacet lacet
WHERE lacet.nom_lacet = lacet_arrive.arr_name;
et jette l'insert actuel sur lacet_ok. la requte rcrite est passe de nouveau au systme de rgles et la seconde rgle applique
lacet_upd produit :
UPDATE donnees_lacet
SET nom_lacet = lacet.nom_lacet,
dispo_lacet = lacet.dispo_lacet + lacet_arrive.arr_quant,
couleur_lacet = lacet.couleur_lacet,
longueur_lacet = lacet.longueur_lacet,
unite_lacet = lacet.unite_lacet
720

Systme de rgles

FROM lacet_arrive lacet_arrive, lacet_ok lacet_ok,


lacet_ok old, lacet_ok new,
lacet lacet, lacet old,
lacet new, donnees_lacet donnees_lacet
WHERE lacet.nom_lacet = lacet_arrive.arr_name
AND donnees_lacet.nom_lacet = lacet.nom_lacet;
De nouveau, il s'agit d'une rgle instead et l'arbre de requte prcdent est jet. Notez que cette requte utilise toujours la vue
lacet. mais le systme de rgles n'a pas fini cette tape, donc il continue et lui applique la rgle _return. Nous obtenons :
UPDATE donnees_lacet
SET nom_lacet = s.nom_lacet,
dispo_lacet = s.dispo_lacet + lacet_arrive.arr_quant,
couleur_lacet = s.couleur_lacet,
longueur_lacet = s.longueur_lacet,
unite_lacet = s.unite_lacet
FROM lacet_arrive lacet_arrive, lacet_ok lacet_ok,
lacet_ok old, lacet_ok new,
lacet lacet, lacet old,
lacet new, donnees_lacet donnees_lacet,
lacet old, lacet new,
donnees_lacet s, unit u
WHERE s.nom_lacet = lacet_arrive.arr_name
AND donnees_lacet.nom_lacet = s.nom_lacet;
Enfin, la rgle log_lacet est applique, produisant l'arbre de requte supplmentaire :
INSERT INTO lacet_log
SELECT s.nom_lacet,
s.dispo_lacet + lacet_arrive.arr_quant,
current_user,
current_timestamp
FROM lacet_arrive lacet_arrive, lacet_ok lacet_ok,
lacet_ok old, lacet_ok new,
lacet lacet, lacet old,
lacet new, donnees_lacet donnees_lacet,
lacet old, lacet new,
donnees_lacet s, unit u,
donnees_lacet old, donnees_lacet new
lacet_log lacet_log
WHERE s.nom_lacet = lacet_arrive.arr_name
AND donnees_lacet.nom_lacet = s.nom_lacet
AND (s.dispo_lacet + lacet_arrive.arr_quant) <> s.dispo_lacet;
une fois que le systme de rgles tombe en panne de rgles et renvoie les arbres de requtes gnrs.
Donc, nous finissons avec deux arbres de requtes finaux qui sont quivalents aux instructions SQL :
INSERT INTO lacet_log
SELECT s.nom_lacet,
s.dispo_lacet + lacet_arrive.arr_quant,
current_user,
current_timestamp
FROM lacet_arrive lacet_arrive, donnees_lacet donnees_lacet,
donnees_lacet s
WHERE s.nom_lacet = lacet_arrive.arr_name
AND donnees_lacet.nom_lacet = s.nom_lacet
AND s.dispo_lacet + lacet_arrive.arr_quant <> s.dispo_lacet;
UPDATE donnees_lacet
SET dispo_lacet = donnees_lacet.dispo_lacet + lacet_arrive.arr_quant
FROM lacet_arrive lacet_arrive,
donnees_lacet donnees_lacet,
donnees_lacet s
WHERE s.nom_lacet = lacet_arrive.nom_lacet
AND donnees_lacet.nom_lacet = s.nom_lacet;
Le rsultat est que la donne provenant d'une relation insre dans une autre, modifie en mise jour dans une troisime, modifie
en mise jour dans une quatrime, cette dernire tant trace dans une cinquime, se voit rduite deux requtes.
Il y a un petit dtail assez horrible. En regardant les deux requtes, nous nous apercevons que la relation donnees_lacet apparat deux fois dans la table d'chelle o cela pourrait tre rduit une seule occurrence. Le planificateur ne gre pas ceci et, du
721

Systme de rgles

coup, le plan d'excution de la sortie du systme de rgles pour insert sera :


Nested Loop
-> Merge Join
-> Seq Scan
-> Sort
-> Seq Scan on s
-> Seq Scan
-> Sort
-> Seq Scan on lacet_arrive
-> Seq Scan on donnees_lacet
alors qu'omettre la table d'chelle supplmentaire rsulterait en un :
Merge Join
-> Seq Scan
-> Sort
->
-> Seq Scan
-> Sort
->

Seq Scan on s
Seq Scan on lacet_arrive

qui produit exactement les mmes entres dans la table des traces. Du coup, le systme de rgles a caus un parcours supplmentaire dans la table donnees_lacet qui n'est absolument pas ncessaire. et le mme parcours redondant est fait une fois de plus
dans l'update. mais ce fut rellement un travail difficile de rendre tout ceci possible.
Maintenant, nous faisons une dmonstration finale du systme de rgles de PostgreSQL et de sa puissance. disons que nous
ajoutons quelques lacets avec des couleurs extraordinaires votre base de donnes :
INSERT INTO lacet VALUES ('sl9', 0, 'pink', 35.0, 'inch', 0.0);
INSERT INTO lacet VALUES ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0);
Nous voulons crer une vue vrifiant les entres lacet qui ne correspondent aucune chaussure pour la couleur. Voici la vue :
CREATE VIEW lacet_mismatch AS
SELECT * FROM lacet WHERE NOT EXISTS
(SELECT nom_chaussure FROM chaussure WHERE couleur = couleur_lacet);
Sa sortie est :
SELECT * FROM lacet_mismatch;

nom_lacet | dispo_lacet | couleur_lacet | longueur_lacet | unite_lacet |


longueur_lacet_cm
-----------+-------------+---------------+----------------+-------------+------------------sl9
|
0 | pink
|
35 | inch
|
88.9
sl10
|
1000 | magenta
|
40 | inch
|
101.6
Maintenant, nous voulons la configurer pour que les lacets qui ne correspondent pas et qui ne sont pas en stock soient supprims
de la base de donnes. Pour rendre la chose plus difficile PostgreSQL, nous ne les supprimons pas directement. la place,
nous crons une vue supplmentaire :
CREATE VIEW lacet_can_delete AS
SELECT * FROM lacet_mismatch WHERE dispo_lacet = 0;
et le faisons de cette faon :
DELETE FROM lacet WHERE EXISTS
(SELECT * FROM lacet_can_delete
WHERE nom_lacet = lacet.nom_lacet);
voil :
SELECT * FROM lacet;

nom_lacet | dispo_lacet | couleur_lacet | longueur_lacet | unite_lacet |


longueur_lacet_cm
-----------+-------------+---------------+----------------+-------------+------------------sl1
|
5 | black
|
80 | cm
|
80
sl2
|
6 | black
|
100 | cm
|
100
722

Systme de rgles

sl7
60
sl4
101.6
sl3
88.9
sl8
101.6
sl10
101.6
sl5
100
sl6
90
(9 rows)

6 | brown

60 | cm

8 | black

40 | inch

10 | black

35 | inch

21 | brown

40 | inch

1000 | magenta

40 | inch

4 | brown

1 | m

20 | brown

0.9 | m

Un delete sur une vue, avec une qualification de sous-requte qui utilise au total quatre vues imbriques/jointes, o l'une d'entre
elles a une qualification de sous-requte contenant une vue et o les colonnes des vues calcules sont utilises, est rcrite en un
seul arbre de requte qui supprime les donnes demandes sur la vraie table.
Il existe probablement seulement quelques situations dans le vrai monde o une telle construction est ncessaire. Mais, vous vous
sentez mieux quand cela fonctionne.

37.4. Rgles et droits


cause de la rcriture des requtes par le systme de rgles de PostgreSQL, d'autres tables/vues que celles utilises dans la requte originale pourraient tre accdes. Lorsque des rgles de mise jour sont utilises, ceci peut inclure des droits d'criture sur
les tables.
Les rgles de rcriture n'ont pas de propritaire spar. Le propritaire d'une relation (table ou vue) est automatiquement le propritaire des rgles de rcriture qui lui sont dfinies. Le systme de rgles de PostgreSQL modifie le comportement du systme
de contrle d'accs par dfaut. Les relations qui sont utilises cause des rgles se voient vrifier avec les droits du propritaire de
la rgle, et non avec ceux de l'utilisateur appelant cette rgle. Ceci signifie qu'un utilisateur a seulement besoin des droits requis
pour les tables/vues qu'il nomme explicitement dans ses requtes.
Par exemple : un utilisateur a une liste de numros de tlphone dont certains sont privs, les autres tant d'intrt pour la secrtaire du bureau. Il peut construire de cette faon :
CREATE TABLE phone_data (person text, phone text, private boolean);
CREATE VIEW phone_number AS
SELECT person, CASE WHEN NOT private THEN phone END AS phone
FROM phone_data;
GRANT SELECT ON phone_number TO secretary;
Personne sauf lui (et les superutilisateurs de la base de donnes) ne peut accder la table phone_data. mais, cause du grant,
la secrtaire peut lancer un select sur la vue phone_number. le systme de rgles rcrira le select sur phone_number en un
select sur phone_data. Comme l'utilisateur est le propritaire de phone_number et du coup le propritaire de la rgle, le
droit de lecture de phone_data est maintenant vrifi avec ses propres privilges et la requte est autorise. La vrification de
l'accs phone_number est aussi ralise mais ceci est fait avec l'utilisateur appelant, donc personne sauf l'utilisateur et la secrtaire ne peut l'utiliser.
Les droits sont vrifis rgle par rgle. Donc, la secrtaire est actuellement la seule pouvoir voir les numros de tlphone publiques. Mais la secrtaire peut configurer une autre vue et autoriser l'accs au public. Du coup, tout le monde peut voir les donnes de phone_number via la vue de la secrtaire. ce que la secrtaire ne peut pas faire est de crer une vue qui accde directement phone_data (en fait, elle le peut mais cela ne fonctionnera pas car tous les accs seront refuss lors de la vrification des
droits). Ds que l'utilisateur s'en rendra compte, du fait que la secrtaire a ouvert la vue phone_number tout le monde, il peut
rvoquer son accs. Immdiatement, tous les accs de la vue de la secrtaire choueront.
Il pourrait tre dit que cette vrification rgle par rgle est une brche de scurit mais ce n'est pas le cas. Si cela ne fonctionne pas
de cette faon, la secrtaire pourrait copier une table avec les mmes colonnes que phone_number et y copier les donnes une
fois par jour. du coup, ce sont ces propres donnes et elle peut accorder l'accs tout le monde si elle le souhaite. Une commande
grant signifie j'ai confiance en vous . si quelqu'un en qui vous avez confiance se comporte ainsi, il est temps d'y rflchir et
d'utiliser revoke.
Notez que, bien que les vues puissent tre utilises pour cacher le contenu de certaines colonnes en utilisant la technique montre
ci-dessus, elles ne peuvent pas tre utilises de manire fiable pour cacher des donnes dans des lignes invisibles. Par exemple, la
vue suivante n'est pas scurise :
723

Systme de rgles

CREATE VIEW phone_number AS


SELECT person, phone FROM phone_data WHERE phone NOT LIKE '412%';
Cette vue peut sembler scurise car le systme de rgles va rcrire tout SELECT partir de phone_number dans un SELECT partir de phone_data et ajouter la qualification permettant de filter les enregistrements dont la colonne phone ne
commence pas par 412. Mais si l'utilisateur peut crer ses propres fonctions, il n'est pas difficile de convaincre le planificateur
d'excuter la fonction dfinie par l'utilisateur avant l'expression NOT LIKE.
CREATE FUNCTION tricky(text, text) RETURNS bool AS $$
BEGIN
RAISE NOTICE '% => %', $1, $2;
RETURN true;
END
$$ LANGUAGE plpgsql COST 0.0000000000000000000001;
SELECT * FROM phone_number WHERE tricky(person, phone);
Chaque personne et chaque numro de tlphone de la table phone_data sera affich dans un NOTICE car le planificateur choisira d'excuter la procdure tricky avant le NOT LIKE car elle est moins coteuse. Mme si l'utilisateur ne peut pas dfinir des
nouvelles fonctions, les fonctions internes peuvent tre utilises pour des attaques similaires. (Par exemple, la plupart des fonctions de conversions affichent les valeurs en entre dans le message d'erreur qu'elles fournissent.)
Des considrations similaires s'appliquent aussi aux rgles de mise jour. Dans les exemples de la section prcdente, le propritaire des tables de la base de donnes d'exemple pourrait accorder les droits select, insert, update et delete sur la vue
lacet quelqu'un d'autre mais seulement select sur lacet_log. l'action de la rgle pourrait crire des entres de trace qui
seraient toujours excutes avec succs et que l'autre utilisateur pourrait voir. Mais il ne peut pas crer d'entres fausses, pas plus
qu'il ne peut manipuler ou supprimer celles qui existent. Dans ce cas, il n'existe pas de possibilit de subvertir les rgles en
convaincant le planificateur de modifier l'ordre des oprations car la seule rgle qui fait rfrence shoelace_log est un INSERT non qualifi. Ceci pourrait ne plus tre vrai dans les scnarios complexes.

37.5. Rgles et statut de commande


Le serveur PostgreSQL renvoie une chane de statut de commande, comme insert 149592 1, pour chaque commande qu'il
reoit. C'est assez simple lorsqu'il n'y a pas de rgles impliques. Mais qu'arrive-t'il lorsque la requte est rcrite par des rgles ?
Les rgles affectent le statut de la commande de cette faon :

S'il n'y a pas de rgle instead inconditionnelle pour la requte, alors la requte donne originellement sera excute et son
statut de commande sera renvoy comme d'habitude. (Mais notez que s'il y avait des rgles instead conditionnelles, la ngation de leur qualifications sera ajout la requte initiale. Ceci pourrait rduire le nombre de lignes qu'il traite et, si c'est le cas,
le statut rapport en sera affect.)

S'il y a des rgles instead inconditionnelles pour la requte, alors la requte originale ne sera pas excute du tout. Dans ce
cas, le serveur renverra le statut de la commande pour la dernire requte qui a t insre par une rgle instead
(conditionnelle ou non) et est du mme type de commande (insert, update ou delete) que la requte originale. si aucune requte ne rencontrant ces pr-requis n'est ajoute une rgle, alors le statut de commande renvoy affiche le type de requte
original et annule le compteur de ligne et le champ OID.

(Ce systme a t tabli pour PostgreSQL 7.3. Dans les versions prcdentes, le statut de commande pouvait afficher des rsultats diffrents lorsque les rgles existaient.)
Le programmeur peut s'assurer que toute rgle instead dsire est celle qui initialise le statut de commande dans le deuxime
cas en lui donnant un nom de rgle tant le dernier en ordre alphabtique parmi les rgles actives pour qu'elle soit applique en
dernier.

37.6. Rgles contre dclencheurs


Beaucoup de choses pouvant se faire avec des dclencheurs peuvent aussi tre implmentes en utilisant le systme de rgles de
PostgreSQL. un des points qui ne pourra pas tre implment par les rgles en certains types de contraintes, notamment les cls
trangres. Il est possible de placer une rgle qualifie qui rcrit une commande en nothing si la valeur d'une colonne
n'apparat pas dans l'autre table. Mais alors les donnes sont jetes et ce n'est pas une bonne ide. Si des vrifications de valeurs
valides sont requises et dans le cas o il y a une erreur invalide, un message d'erreur devrait tre gnr et cela devra se faire avec
un dclencheur.
Dans ce chapitre, nous avons cibl l'utilisation des rgles pour mettre jour des vues. Tous les exemples de rgles de mise jour
724

Systme de rgles

de ce chapitre peuvent aussi tre implments en utilisant les triggers INSTEAD OF sur les vues. crire ce type de triggers est
souvent plus facile qu'crire des rgles, tout particulirement si une logique complexe est requise pour raliser la mise jour.
Pour les lments qui peuvent tre implments par les deux, ce qui sera le mieux dpend de l'utilisation de la base de donnes. Un
dclencheur est excut une fois pour chaque ligne affecte. Une rgle modifie la requte ou en gnre une autre. Donc, si un
grand nombre de lignes sont affectes pour une instruction, une rgle lanant une commande supplmentaire sera certainement
plus rapide qu'un dclencheur appel pour chaque ligne et qui devra excuter ces oprations autant de fois. Nanmoins, l'approche
du dclencheur est conceptuellement plus simple que l'approche de la rgle et est plus facile utiliser pour les novices.
Ici, nous montrons un exemple o le choix d'une rgle ou d'un dclencheur joue sur une situation. Voici les deux tables :
CREATE TABLE ordinateur (
nom_hote
text,
constructeur
text
);

-- index
-- index

CREATE TABLE logiciel (


logiciel
text,
nom_hote
text
);

-- index
-- index

Les deux tables ont plusieurs milliers de lignes et les index sur nom_hote sont uniques. la rgle ou le dclencheur devrait implmenter une contrainte qui supprime les lignes de logiciel rfrenant un ordinateur supprim. Le dclencheur utiliserait cette
commande :
DELETE FROM logiciel WHERE nom_hote = $1;
Comme le dclencheur est appel pour chaque ligne individuelle supprime partir de ordinateur, il peut prparer et sauvegarder le plan pour cette commande et passer la valeur nom_hote dans le paramtre. La rgle devra tre rcrite ainsi :
CREATE RULE ordinateur_del AS ON DELETE TO ordinateur
DO DELETE FROM logiciel WHERE nom_hote = OLD.nom_hote;
Maintenant, nous apercevons diffrents types de suppressions. Dans le cas d'un :
DELETE FROM ordinateur WHERE nom_hote = 'mypc.local.net';
la table ordinateur est parcourue par l'index (rapide), et la commande lance par le dclencheur pourrait aussi utiliser un parcours d'index (aussi rapide). La commande supplmentaire provenant de la rgle serait :
DELETE FROM logiciel WHERE ordinateur.nom_hote = 'mypc.local.net'
AND logiciel.nom_hote = ordinateur.nom_hote;
Comme il y a une configuration approprie des index, le planificateur crera un plan :
Nestloop
-> Index Scan using comp_hostidx on ordinateur
-> Index Scan using soft_hostidx on logiciel
Donc, il n'y aurait pas trop de diffrence de performance entre le dclencheur et l'implmentation de la rgle.
Avec la prochaine suppression, nous voulons nous dbarrasser des 2000 ordinateurs o nom_hote commence avec old. il existe
deux commandes possibles pour ce faire. Voici l'une d'elle :
DELETE FROM ordinateur WHERE nom_hote >= 'old'
AND nom_hote < 'ole'
La commande ajoute par la rgle sera :
DELETE FROM logiciel WHERE ordinateur.nom_hote >= 'old'
AND ordinateur.nom_hote < 'ole'
AND logiciel.nom_hote = ordinateur.nom_hote;
avec le plan :
Hash Join
-> Seq Scan on logiciel
-> Hash
-> Index Scan using comp_hostidx on ordinateur
L'autre commande possible est :
DELETE FROM ordinateur WHERE nom_hote ~ '^old';
ce qui finira dans le plan d'excution suivant pour la commande ajoute par la rgle :
725

Systme de rgles

Nestloop
-> Index Scan using comp_hostidx on ordinateur
-> Index Scan using soft_hostidx on logiciel
Ceci monte que le planificateur ne ralise pas que la qualification pour nom_hote dans ordinateur pourrait aussi tre utilise
pour un parcours d'index sur logiciel quand il existe plusieurs expressions de qualifications combines avec and, ce qui correspond ce qu'il fait dans la version expression rationnelle de la commande. Le dclencheur sera appel une fois pour chacun des
2000 anciens ordinateurs qui doivent tre supprimes, et ceci rsultera en un parcours d'index sur ordinateur et 2000 parcours
d'index sur logiciel. l'implmentation de la rgle le fera en deux commandes qui utilisent les index. Et cela dpend de la taille
globale de la table logiciel, si la rgle sera toujours aussi rapide dans la situation du parcours squentiel. 2000 excutions de
commandes partir du dclencheur sur le gestionnaire SPI prend un peu de temps, mme si tous les blocs d'index seront rapidement dans le cache.
La dernire commande que nous regardons est :
DELETE FROM ordinateur WHERE constructeur = 'bim';
De nouveau, ceci pourrait rsulter en de nombreuses lignes supprimer dans ordinateur. donc, le dclencheur lancera de nouveau de nombreuses commandes via l'excuteur. La commande gnre par la rgle sera :
DELETE FROM logiciel WHERE ordinateur.constructeur = 'bim'
AND logiciel.nom_hote = ordinateur.nom_hote;
Le plan pour cette commande sera encore la boucle imbrique sur les deux parcours d'index, en utilisant seulement un index diffrent sur ordinateur :
Nestloop
-> Index Scan using comp_manufidx on ordinateur
-> Index Scan using soft_hostidx on logiciel
Dans chacun de ces cas, les commandes supplmentaires provenant du systme de rgles seront plus ou moins indpendantes du
nombre de lignes affectes en une commande.
Voici le rsum, les rgles seront seulement significativement plus lentes que les dclencheurs si leur actions rsultent en des jointures larges et mal qualifies, une situation o le planificateur choue.

726

Chapitre 38. Langages de procdures


PostgreSQL permet l'criture de fonctions et de procdures dans des langages diffrents du SQL et du C. Ces autres langages
sont appels gnriquement des langages de procdures (LP, PL en anglais). Le serveur ne possde pas d'interprteur interne
des fonctions crites dans un langage de procdures. La tche est donc dvolue un gestionnaire particulier qui, lui, connait les
dtails du langage. Le gestionnaire peut prendre en charge le travail de dcoupage, d'analyse syntaxique, d'excution, etc., ou
simplement servir de colle entre PostgreSQL et une implmentation existante d'un langage de programmation. Le gestionnaire est lui-mme une fonction en langage C compile dans une bibliothque partage et charge la demande, comme toute
autre fonction C.
Il existe ce jour quatre langages de procdures dans la distribution standard de PostgreSQL : PL/pgSQL (Chapitre 39, PL/
pgSQL - Langage de procdures SQL), PL/Tcl (Chapitre 40, PL/Tcl - Langage de procdures Tcl), PL/Perl (Chapitre 41, PL/
Perl - Langage de procdures Perl) et PL/Python (Chapitre 42, PL/Python - Langage de procdures Python).
Il existe d'autres langages de procdures qui ne sont pas inclus dans la distribution principale. L'Annexe G, Projets externes propose des pistes pour les trouver. De plus, d'autres langages peuvent tre dfinis par les utilisateurs. Les bases de dveloppement
d'un nouveau langage de procdures sont couvertes dans le Chapitre 49, crire un gestionnaire de langage procdural.

38.1. Installation des langages de procdures


Un langage de procdures doit tre install dans toute base de donnes amene l'utiliser. Les langages de procdures installs dans la base de donnes template1 sont automatiquement disponibles dans toutes les bases de donnes cres par la suite.
CREATE DATABASE recopie en effet toutes les informations disponibles dans la base template1. Il est ainsi possible pour
l'administrateur de dfinir, par base, les langages disponibles et d'en rendre certains disponibles par dfaut.
Pour les langages fournis avec la distribution standard, l'installation dans la base courante se fait simplement par l'excution de
la commande CREATE EXTENSION langage. On peut galement utiliser le programme createlang(1) pour installer le langage en ligne de commande. Par exemple, pour installer le langage PL/Perl dans la base de donnes template1, on crit :
createlang plperl template1
La procdure manuelle dcrite ci-dessous n'est recommande que pour installer des langages qui ne sont pas disponibles sous la
forme d'extensions.
Procdure 38.1. Installation manuelle de langages de procdures

Un langage de procdures s'installe en cinq tapes effectues obligatoirement par le superutilisateur des bases de donnes. Dans
la plupart des cas, les commandes SQL ncessaires doivent tre places dans un script d'installation d'une extension , pour
que la commande CREATE EXTENSION puisse tre utilis pour installer le langage.
1.

La bibliothque partage du gestionnaire de langage doit tre compile et installe dans le rpertoire de bibliothques appropri. Cela se droule comme la construction et l'installation de modules de classiques fonctions C utilisateur ; voir la
Section 35.9.6, Compiler et lier des fonctions charges dynamiquement . Il arrive souvent que le gestionnaire du langage dpende d'une bibliothque externe fournissant le moteur de langage ; dans ce cas, elle doit aussi tre installe.

2.

Le gestionnaire doit tre dclar par la commande


CREATE FUNCTION nom_fonction_gestionnaire()
RETURNS gestionnaire_langage
AS 'chemin-vers-objet-partag'
LANGUAGE C STRICT;
Le type de retour spcial gestionnaire_langage indique au systme que cette fonction ne renvoie pas un type de donnes
SQL et n'est, de ce fait, pas utilisable directement dans des expressions SQL.

3.

En option, le gestionnaire de langages peut fournir une fonction de gestion en ligne qui permet l'excution de blocs de
code anonyme (commandes DO(7)) crits dans ce langage. Si une fonction de gestion en ligne est fourni par le langage, dclarez-le avec une commande comme
CREATE FUNCTION nom_fonction_en_ligne(internal)
RETURNS void
AS 'chemin-vers-objet-partag'
LANGUAGE C;

4.

En option, le gestionnaire de langages peut fournir une fonction de validation qui vrifie la dfinition d'une fonction
727

Langages de procdures

sans rellement l'excuter. La fonction de validation, si elle existe, est appele par CREATE FUNCTION. Si une telle fonction est fournie par le langage, elle sera dclare avec une commande de la forme
CREATE FUNCTION nom_fonction_validation(oid)
RETURNS void
AS 'chemin-vers-objet-partag'
LANGUAGE C;
5.

Le LP doit tre dclar par la commande


CREATE [TRUSTED] [PROCEDURAL] LANGUAGE nom_langage
HANDLER nom_fonction_gestionnaire
[INLINE nom_fonction_en_ligne]
[VALIDATOR nom_fonction_valideur] ;
Le mot cl optionnel TRUSTED (autrement dit, digne de confiance) indique que le langage n'autorise pas l'accs des donnes normalement inaccessible cet utilisateur. Les langages de confiance sont conus pour les utilisateurs standards de la
base de donnes, c'est--dire ceux qui ne sont pas superutilisateurs, et les autorisent crer en tout scurit des fonctions et
des procdures pour triggers. Les fonctions en langage de procdures tant excutes au sein du serveur, le paramtre TRUSTED ne devrait tre positionn que pour les langages n'accdant pas aux organes internes du serveur ou au systme de fichiers. Les langages PL/pgSQL, PL/Tcl, et PL/Perl sont considrs comme dignes de confiance ; les langages PL/TclU, PL/
PerlU, et PL/PythonU sont conus pour fournir des fonctionnalits illimites et ne devraient pas tre marqus dignes de
confiance.

L'Exemple 38.1, Installation manuelle de PL/Perl prsente le fonctionnement de la procdure d'installation manuelle du langage PL/Perl.
Exemple 38.1. Installation manuelle de PL/Perl

La commande suivante indique au serveur l'emplacement de la bibliothque partage pour la fonction de gestion des appels du
langage PL/Perl.
CREATE FUNCTION plperl_call_handler() RETURNS language_handler AS
'$libdir/plperl' LANGUAGE C;
PL/Perl a une fonction de gestion en ligne et une fonction de validation, donc nous dclarons aussi celles-ci :
CREATE FUNCTION plperl_inline_handler(internal) RETURNS void AS
'$libdir/plperl' LANGUAGE C;
CREATE FUNCTION plperl_validator(oid) RETURNS void AS
'$libdir/plperl' LANGUAGE C STRICT;
La commande :
CREATE TRUSTED PROCEDURAL LANGUAGE plperl
HANDLER plperl_call_handler
INLINE plperl_inline_handler
VALIDATOR plperl_validator;
indique l'vocation des fonctions prcdentes pour les fonctions et procdures de dclencheur lorsque l'attribut de langage est plperl.
Lors de l'installation par dfaut de PostgreSQL, le gestionnaire du langage PL/pgSQL est compil et install dans le rpertoire
des bibliothques ( lib ) ; de plus, le langage PL/pgSQL est install dans toutes les bases de donnes. Si le support de Tcl est
configur, les gestionnaires pour PL/Tcl et PL/TclU sont construits et installs dans le rpertoire des bibliothques mais le langage
lui-mme n'est pas install par dfaut dans les bases de donnes. De la mme faon, les gestionnaires pour PL/Perl et PL/PerlU
sont construits et installs si le support de Perl est configur et le gestionnaire pour PL/PythonU est install si le support de Python
est configur mais ces langages ne sont pas installs par dfaut.

728

Chapitre 39. PL/pgSQL - Langage de procdures


SQL
39.1. Aperu
PL/pgSQL est un langage de procdures chargeable pour le systme de bases de donnes PostgreSQL. Les objectifs de la
conception de PL/pgSQL ont t de crer un langage de procdures chargeable qui

est utilis pour crer des fonctions standards et triggers,

ajoute des structures de contrle au langage SQL,

permet d'effectuer des traitements complexes,

hrite de tous les types, fonctions et oprateurs dfinis par les utilisateurs,

est dfini comme digne de confiance par le serveur,

est facile utiliser.

Les fonctions PL/pgSQL acceptent un nombre variable d'arguments en utilisant le marqueur VARIADIC. Cela fonctionne exactement de la mme faon pour les fonctions SQL, comme indiqu dans Section 35.4.5, Fonctions SQL avec un nombre variables d'arguments .
Les fonctions crites en PL/pgSQL peuvent tre utilises partout o une fonction intgre peut l'tre. Par exemple, il est possible
de crer des fonctions complexes de traitement conditionnel et, par la suite, de les utiliser pour dfinir des oprateurs ou de les
utiliser dans des expressions d'index.
partir de la version 9.0 de PostgreSQL, PL/pgSQL est install par dfaut. Il reste toutefois un module chargeable et les administrateurs craignant pour la scurit de leur instance pourront le retirer.

39.1.1. Avantages de l'utilisation de PL/pgSQL


SQL est le langage que PostgreSQL et la plupart des autres bases de donnes relationnelles utilisent comme langage de requte. Il est portable et facile apprendre, mais chaque expression SQL doit tre excute individuellement par le serveur de
bases de donnes.
Cela signifie que votre application client doit envoyer chaque requte au serveur de bases de donnes, attendre que celui-ci la
traite, recevoir et traiter les rsultats, faire quelques calculs, et enfin envoyer d'autres requtes au serveur. Tout ceci induit des
communications interprocessus et induit aussi une surcharge du rseau si votre client est sur une machine diffrente du serveur
de bases de donnes.
Grce PL/pgSQL vous pouvez grouper un bloc de traitement et une srie de requtes au sein du serveur de bases de donnes,
et bnficier ainsi de la puissance d'un langage de procdures, mais avec de gros gains en terme de communication client/serveur.

Les allers/retours entre le client et le serveur sont limins

Il n'est pas ncessaire de traiter ou transfrer entre le client et le serveur les rsultats intermdiaires dont le client n'a pas besoin

Les va-et-vient des analyses de requtes peuvent tre vits

Ceci a pour rsultat une augmentation considrable des performances en comparaison une application qui n'utilise pas les procdures stockes.
Ainsi, avec PL/pgSQL vous pouvez utiliser tous les types de donnes, oprateurs et fonctions du SQL.

39.1.2. Arguments supports et types de donnes rsultats


Les fonctions crites en PL/pgSQL peuvent accepter en argument n'importe quel type de donnes support par le serveur, et
peuvent renvoyer un rsultat de n'importe lequel de ces types. Elles peuvent aussi accepter ou renvoyer n'importe quel type composite (type ligne) spcifi par nom. Il est aussi possible de dclarer une fonction PL/pgSQL renvoyant un type record, signifiant
que le rsultat est un type ligne dont les colonnes sont dtermines par spcification dans la requte appelante (voir la Section 7.2.1.4, Fonctions de table ).
729

PL/pgSQL - Langage de procdures SQL

Les fonctions PL/pgSQL acceptent en entre et en sortie les types polymorphes anyelement, anyarray, anynonarray et anyenum.
Le type de donnes rel gr par une fonction polymorphe peut varier d'appel en appel (voir la Section 35.2.5, Types et fonctions polymorphes ). Voir l'exemple de la Section 39.3.1, Dclarer des paramtres de fonctions .
Les fonctions PL/pgSQL peuvent aussi renvoyer un ensemble de lignes (ou une table) de n'importe lequel des type de donnes
dont les fonctions peuvent renvoyer une instance unique. Ces fonctions gnrent leur sortie en excutant RETURN NEXT pour
chaque lment dsir de l'ensemble rsultat ou en utilisant RETURN QUERY pour afficher le rsultat de l'valuation d'une requte.
Enfin, une fonction PL/pgSQL peut tre dclare comme renvoyant void si elle n'a pas de valeur de retour utile.
Les fonctions PL/pgSQL peuvent aussi tre dclares avec des paramtres en sortie la place de la spcification explicite du code
de retour. Ceci n'ajoute pas de fonctionnalit fondamentale au langage mais c'est un moyen agrable principalement pour renvoyer
plusieurs valeurs. La notation RETURNS TABLE peut aussi tre utilis la place de RETURNS SETOF.
Des exemples spcifiques apparaissent dans la Section 39.3.1, Dclarer des paramtres de fonctions et la Section 39.6.1,
Retour d'une fonction .

39.2. Structure de PL/pgSQL


PL/pgSQL est un langage structur en blocs. Le texte complet de la dfinition d'une fonction doit tre un bloc. Un bloc est dfini
comme :
[ <<label>> ]
[ DECLARE
dclarations ]
BEGIN
instructions
END [ label ];
Chaque dclaration et chaque expression au sein du bloc est termin par un point-virgule. Un bloc qui apparat l'intrieur d'un
autre bloc doit avoir un point-virgule aprs END (voir l'exemple ci-dessus) ; nanmoins, le END final qui conclut le corps d'une
fonction n'a pas besoin de point-virgule.

Astuce
Une erreur habituelle est d'crire un point-virgule immdiatement aprs BEGIN. C'est incorrect et a comme rsultat
une erreur de syntaxe.
Un label est seulement ncessaire si vous voulez identifier le bloc utiliser dans une instruction EXIT ou pour qualifier les
noms de variable dclares dans le bloc. Si un label est crit aprs END, il doit correspondre au label donn au dbut du bloc.
Tous les mots cls sont insensibles la casse. Les identifiants sont convertis implicitement en minuscule sauf dans le cas de
l'utilisation de guillemets doubles. Le comportement est donc identique celui des commandes SQL habituelles.
Les commentaires fonctionnent de la mme manire tant dans du PL/pgSQL que dans le code SQL. Un double tiret (--) commence un commentaire et celui-ci continue jusqu' la fin de la ligne. Un /* commence un bloc de commentaire qui continue jusqu'au */ correspondant. Les blocs de commentaires peuvent imbriquer les uns dans les autres.
Chaque expression de la section expression d'un bloc peut tre un sous-bloc. Les sous-blocs peuvent tre utiliss pour des groupements logiques ou pour situer des variables locales dans un petit groupe d'instructions. Les variables dclares dans un sous-bloc
masquent toute variable nomme de faon similaire dans les blocs externes pendant toute la dure du sous-bloc. Cependant, vous
pouvez accder aux variables externes si vous qualifiez leur nom du label de leur bloc. Par exemple :
CREATE FUNCTION une_fonction() RETURNS integer AS $$
<< blocexterne >>
DECLARE
quantite integer := 30;
BEGIN
RAISE NOTICE 'quantit vaut ici %', quantite; -- affiche 30
quantite := 50;
--- Cre un sous-bloc
-DECLARE
quantite integer := 80;
BEGIN
RAISE NOTICE 'quantite vaut ici %', quantite; -- affiche 80
730

PL/pgSQL - Langage de procdures SQL

RAISE NOTICE 'la quantit externe vaut ici %', blocexterne.quantite;


affiche 50
END;
RAISE NOTICE 'quantit vaut ici %', quantite;

--

-- affiche 50

RETURN quantite;
END;
$$ LANGUAGE plpgsql;

Note
Il existe un bloc externe cach entourant le corps de toute fonction PL/pgSQL. Ce bloc fournit la dclaration des
paramtres de la fonction ainsi que quelques variables spciales comme FOUND (voir la Section 39.5.5, Obtention
du statut du rsultat ). Le bloc externe a pour label le nom de la fonction. Cela a pour consquence que les paramtres et les variables spciales peuvent tre qualifis du nom de la fonction.
Il est important de ne pas confondre l'utilisation de BEGIN/END pour grouper les instructions dans PL/pgSQL avec les commandes pour le contrle des transactions. Les BEGIN/END de PL/pgSQL ne servent qu'au groupement ; ils ne dbutent ni ne terminent une transaction. Les fonctions standards et les fonctions triggers sont toujours excutes l'intrieur d'une transaction tablie par une requte extrieure -- ils ne peuvent pas tre utiliss pour commencer ou valider une transaction car ils n'auraient pas
de contexte pour s'excuter. Nanmoins, un bloc contenant une clause EXCEPTION forme rellement une sous-transaction qui
peut tre annule sans affecter la transaction externe. Pour plus d'informations sur ce point, voir la Section 39.6.6, Rcuprer les
erreurs .

39.3. Dclarations
Toutes les variables utilises dans un bloc doivent tre dclares dans la section dclaration du bloc. Les seules exceptions sont
que la variable de boucle d'une boucle FOR effectuant une itration sur des valeurs entires est automatiquement dclare comme
variable entire (type integer), et de la mme faon une variable de boucle FOR effectuant une itration sur le rsultat d'un curseur
est automatiquement dclare comme variable de type record.
Les variables PL/pgSQL peuvent tre de n'importe quel type de donnes tels que integer, varchar et char.
Quelques exemples de dclaration de variables :
id_utilisateur integer;
quantit numeric(5);
url varchar;
ma_ligne nom_table%ROWTYPE;
mon_champ nom_table.nom_colonne%TYPE;
une_ligne RECORD;
La syntaxe gnrale d'une dclaration de variable est :
nom [ CONSTANT ] type [ COLLATE nom_collationnement ] [ NOT NULL ] [ { DEFAULT | := }
expression ];
La clause DEFAULT, si indique, spcifie la valeur initiale affecte la variable quand on entre dans le bloc. Si la clause DEFAULT n'est pas indique, la variable est initialise la valeur SQL NULL. L'option CONSTANT empche la modification de la
variable aprs initialisation, de sorte que sa valeur reste constante pour la dure du bloc. L'option COLLATE indique le collationnement utiliser pour la variable (voir Section 39.3.6, Collationnement des variables PL/pgSQL ). Si NOT NULL est spcifi,
l'affectation d'une valeur NULL aboutira une erreur d'excution. Les valeurs par dfaut de toutes les variables dclares NOT
NULL doivent tre prcises, donc non NULL.
La valeur par dfaut d'une variable est value et affecte la variable chaque entre du bloc (pas seulement une fois lors de
l'appel de la fonction). Ainsi, par exemple, l'affectation de now() une variable de type timestamp donnera la variable l'heure
de l'appel de la fonction courante, et non l'heure au moment o la fonction a t prcompile.
Exemples :
quantit integer DEFAULT 32;
url varchar := 'http://mysite.com';
id_utilisateur CONSTANT integer := 10;

39.3.1. Dclarer des paramtres de fonctions


731

PL/pgSQL - Langage de procdures SQL

Les paramtres passs aux fonctions sont nomms par les identifiants $1, $2, etc. ventuellement, des alias peuvent tre dclars
pour les noms de paramtres de type $n afin d'amliorer la lisibilit. L'alias ou l'identifiant numrique peuvent tre utiliss indiffremment pour se rfrer la valeur du paramtre.
Il existe deux faons de crer un alias. La faon prfre est de donner un nom au paramtre dans la commande CREATE FUNCTION, par exemple :
CREATE FUNCTION taxe_ventes(sous_total real) RETURNS real AS $$
BEGIN
RETURN sous_total * 0.06;
END;
$$ LANGUAGE plpgsql;
L'autre faon, la seule disponible pour les versions antrieures PostgreSQL 8.0, est de dclarer explicitement un alias en utilisant la syntaxe de dclaration :
nom ALIAS FOR $n;
Le mme exemple dans ce style ressemble ceci :
CREATE FUNCTION taxe_ventes(real) RETURNS real AS $$
DECLARE
sous_total ALIAS FOR $1;
BEGIN
RETURN sous_total * 0.06;
END;
$$ LANGUAGE plpgsql;

Note
Ces deux exemples ne sont pas compltement identiques. Dans le premier cas, sous_total peut tre rfrenc
comme taxe_ventes.sous_total, alors que ce n'est pas possible dans le second cas. (Si nous avions attach
un label au bloc interne, sous_total aurait pu utiliser ce label la place.)
Quelques exemples de plus :
CREATE FUNCTION instr(varchar, integer) RETURNS integer AS $$
DECLARE
v_string ALIAS FOR $1;
index ALIAS FOR $2;
BEGIN
-- quelques traitements utilisant ici v_string et index
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION concat_champs_selectionnes(in_t un_nom_de_table) RETURNS text AS $$
BEGIN
RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;
END;
$$ LANGUAGE plpgsql;
Quand une fonction PL/pgSQL est dclare avec des paramtres en sortie, ces derniers se voient attribus les noms $n et des alias
optionnels de la mme faon que les paramtres en entre. Un paramtre en sortie est une variable qui commence avec la valeur
NULL ; il devrait se voir attribuer une valeur lors de l'excution de la fonction. La valeur finale du paramtre est ce qui est renvoye. Par exemple, l'exemple taxe_ventes peut s'crire de cette faon :
CREATE FUNCTION taxe_ventes(sous_total real, OUT taxe real) AS $$
BEGIN
taxe := sous_total * 0.06;
END;
$$ LANGUAGE plpgsql;
Notez que nous avons omis RETURNS real. Nous aurions pu l'inclure mais cela aurait t redondant.
Les paramtres en sortie sont encore plus utiles lors du retour de plusieurs valeurs. Un exemple trivial est :
CREATE FUNCTION somme_n_produits(x int, y int, OUT somme int, OUT produit int) AS $$
BEGIN
somme := x + y;
732

PL/pgSQL - Langage de procdures SQL

produit := x * y;
END;
$$ LANGUAGE plpgsql;
D'aprs ce qui a t vu dans la Section 35.4.4, Fonctions SQL avec des paramtres en sortie , ceci cre rellement un type
d'enregistrement anonyme pour les rsultats de la fonction. Si une clause RETURNS est donne, elle doit spcifier RETURNS record.
Voici une autre faon de dclarer une fonction PL/pgSQL, cette fois avec RETURNS TABLE :
CREATE FUNCTION extended_sales(p_itemno int)
RETURNS TABLE(quantity int, total numeric) AS $$
BEGIN
RETURN QUERY SELECT quantity, quantity * price FROM sales
WHERE itemno = p_itemno;
END;
$$ LANGUAGE plpgsql;
C'est exactement quivalent dclarer un ou plusieurs paramtres OUT et spcifier RETURNS SETOF un_type.
Lorsque le type de retour d'une fonction PL/pgSQL est dclar comme type polymorphe (anyelement, anyarray, anynonarray et
anyenum), un paramtre spcial $0 est cr. Son type de donne est le type effectif de retour de la fonction, dduit d'aprs les
types en entre (voir la Section 35.2.5, Types et fonctions polymorphes ). Ceci permet la fonction d'accder son type de retour rel comme on le voit ici avec la Section 39.3.3, Copie de types . $0 est initialis NULL et peut tre modifi par la fonction, de sorte qu'il peut tre utilis pour contenir la variable de retour si besoin est, bien que cela ne soit pas requis. On peut aussi
donner un alias $0. Par exemple, cette fonction s'excute comme un oprateur + pour n'importe quel type de donnes :
CREATE FUNCTION ajoute_trois_valeurs(v1 anyelement, v2 anyelement, v3 anyelement)
RETURNS anyelement AS $$
DECLARE
resultat ALIAS FOR $0;
BEGIN
resultat := v1 + v2 + v3;
RETURN resultat;
END;
$$ LANGUAGE plpgsql;
Le mme effet peut tre obtenu en dclarant un ou plusieurs paramtres polymorphes en sortie de types. Dans ce cas, le paramtre
spcial $0 n'est pas utilis ; les paramtres en sortie servent ce mme but. Par exemple :
CREATE FUNCTION ajoute_trois_valeurs(v1 anyelement, v2 anyelement, v3 anyelement,
OUT somme anyelement)
AS $$
BEGIN
somme := v1 + v2 + v3;
END;
$$ LANGUAGE plpgsql;

39.3.2. ALIAS
nouveaunom ALIAS FOR anciennom;
La syntaxe ALIAS est plus gnrale que la section prcdente pourrait faire croire : vous pouvez dclarer un alias pour n'importe
quelle variable et pas seulement des paramtres de fonction. L'utilisation principale de cette instruction est l'attribution d'un autre
nom aux variables aux noms prdtermins, telles que NEW ou OLD au sein d'une procdure trigger.
Exemples:
DECLARE
anterieur ALIAS FOR old;
misajour ALIAS FOR new;
ALIAS crant deux manires diffrentes de nommer le mme objet, son utilisation outrance peut prter confusion. Il vaut
mieux ne l'utiliser uniquement pour se passer des noms prdtermins.

39.3.3. Copie de types


733

PL/pgSQL - Langage de procdures SQL

variable%TYPE
%TYPE fournit le type de donnes d'une variable ou d'une colonne de table. Vous pouvez l'utiliser pour dclarer des variables qui
contiendront des valeurs de base de donnes. Par exemple, disons que vous avez une colonne nomme id_utilisateur dans
votre table utilisateurs. Pour dclarer une variable du mme type de donnes que utilisateurs.id_utilisateur,
vous pouvez crire :
id_utilisateur utilisateurs.id_utilisateur%TYPE;
En utilisant %TYPE vous n'avez pas besoin de connatre le type de donnes de la structure laquelle vous faites rfrence et, plus
important, si le type de donnes de l'objet rfrenc change dans le futur (par exemple : vous changez le type de
id_utilisateur de integer real), vous pouvez ne pas avoir besoin de changer votre dfinition de fonction.
%TYPE est particulirement utile dans le cas de fonctions polymorphes puisque les types de donnes ncessaires aux variables internes peuvent changer d'un appel l'autre. Des variables appropries peuvent tre cres en appliquant %TYPE aux arguments de
la fonction ou la variable fictive de rsultat.

39.3.4. Types ligne


nom nom_table%ROWTYPE;
nom nom_type_composite;
Une variable de type composite est appele variable ligne (ou variable row-type). Une telle variable peut contenir une ligne entire
de rsultat de requte SELECT ou FOR, du moment que l'ensemble de colonnes de la requte correspond au type dclar de la
variable. Les champs individuels de la valeur row sont accessibles en utilisant la notation pointe, par exemple varligne.champ.
Une variable ligne peut tre dclare de faon avoir le mme type que les lignes d'une table ou d'une vue existante, en utilisant la
notation nom_table%ROWTYPE. Elle peut aussi tre dclare en donnant un nom de type composite. Chaque table ayant un type
de donnes associ du mme nom, il importe peu dans PostgreSQL que vous criviez %ROWTYPE ou pas. Cependant, la forme
utilisant %ROWTYPE est plus portable.
Les paramtres d'une fonction peuvent tre des types composites (lignes compltes de tables). Dans ce cas, l'identifiant correspondant $n sera une variable ligne partir de laquelle les champs peuvent tre slectionns avec la notation pointe, par exemple
$1.id_utilisateur.
Seules les colonnes dfinies par l'utilisateur sont accessibles dans une variable de type ligne, et non l'OID ou d'autres colonnes
systmes (parce que la ligne pourrait tre issue d'une vue). Les champs du type ligne hritent des tailles des champs de la table ou
de leur prcision pour les types de donnes tels que char(n).
Voici un exemple d'utilisation des types composites. table1 et table2 sont des tables ayant au moins les champs mentionns :
CREATE FUNCTION assemble_champs(t_ligne table1) RETURNS text AS $$
DECLARE
t2_ligne table2%ROWTYPE;
BEGIN
SELECT * INTO t2_ligne FROM table2 WHERE ... ;
RETURN t_ligne.f1 || t2_ligne.f3 || t_ligne.f5 || t2_ligne.f7;
END;
$$ LANGUAGE plpgsql;
SELECT assemble_champs(t.*) FROM table1 t WHERE ... ;

39.3.5. Types record


nom RECORD;
Les variables record sont similaires aux variables de type ligne mais n'ont pas de structure prdfinie. Elles empruntent la structure
effective de type ligne de la ligne laquelle elles sont affectes durant une commande SELECT ou FOR. La sous-structure d'une
variable record peut changer chaque fois qu'on l'affecte. Une consquence de cela est qu'elle n'a pas de sous-structure jusqu' ce
qu'elle ait t affecte, et toutes les tentatives pour accder un de ses champs entranent une erreur d'excution.
Notez que RECORD n'est pas un vrai type de donnes mais seulement un paramtre fictif (placeholder). Il faut aussi raliser que
lorsqu'une fonction PL/pgSQL est dclare renvoyer un type record, il ne s'agit pas tout fait du mme concept qu'une variable record, mme si une telle fonction peut aussi utiliser une variable record pour contenir son rsultat. Dans les deux cas, la structure
relle de la ligne n'est pas connue quand la fonction est crite mais, dans le cas d'une fonction renvoyant un type record, la struc734

PL/pgSQL - Langage de procdures SQL

ture relle est dtermine quand la requte appelante est analyse, alors qu'une variable record peut changer sa structure de ligne
la vole.

39.3.6. Collationnement des variables PL/pgSQL


Quand une fonction PL/pgSQL a un ou plusieurs paramtres dont le type de donnes est collationnable, un collationnement est
identifi pour chaque appel de fonction dpendant des collationnements affects aux arguments rels, comme dcrit dans Section 22.2, Support des collations . Si un collationnement est identifi avec succs (autrement dit, qu'il n'y a pas de conflit de
collationnements implicites parmi les arguments), alors tous les paramtres collationnables sont traits comme ayant un collationnement implicite. Ceci affectera le comportement des oprations sensibles au collationnement dans la fonction. Par exemple, avec
cette fonction
CREATE FUNCTION plus_petit_que(a text, b text) RETURNS boolean AS $$
BEGIN
RETURN a < b;
END;
$$ LANGUAGE plpgsql;
SELECT plus_petit_que(champ_text_1, champ_text_2) FROM table1;
SELECT plus_petit_que(champ_text_1, champ_text_2 COLLATE "C") FROM table1;
La premire utilisation de less_than utilisera le collationnement par dfaut de champ_text_1 et de champ_text_2 pour
la comparaison alors que la seconde utilisation prendra le collationnement C.
De plus, le collationnement identifi est aussi considr comme le collationnement de toute variable locale de type collationnable.
Du coup, cette procdure stocke ne fonctionnera pas diffremment de celle-ci :
CREATE FUNCTION plus_petit_que(a text, b text) RETURNS boolean AS $$
DECLARE
local_a text := a;
local_b text := b;
BEGIN
RETURN local_a < local_b;
END;
$$ LANGUAGE plpgsql;
S'il n'y a pas de paramtres pour les types de donnes collationnables ou qu'aucun collationnement commun ne peut tre identifi
pour eux, alors les paramtres et les variables locales utilisent le collationnement par dfaut de leur type de donnes (qui est habituellement le collationnement par dfaut de la base de donnes mais qui pourrait tre diffrent pour les variables des types domaines).
Une variable locale d'un type de donnes collationnable peut avoir un collationnement diffrent qui lui est associ en incluant
l'option COLLATE dans sa dclaration, par exemple
DECLARE
local_a text COLLATE "en_US";
Cette option surcharge le collationnement qui serait normalement donn la variable d'aprs les rgles ci-dessus.
De plus, les clauses COLLATE explicites peuvent tre crites l'intrieur d'une fonction si forcer l'utilisation d'un collationnement
particulier est souhait pour une opration particulire. Par exemple,
CREATE FUNCTION plus_petit_que_c(a text, b text) RETURNS boolean AS $$
BEGIN
RETURN a < b COLLATE "C";
END;
$$ LANGUAGE plpgsql;
Ceci surcharge les collationnements associs avec les colonnes de la table, les paramtres ou la variables locales utilises dans
l'expression, comme cela arriverait dans une commande SQL simple.

39.4. Expressions
Toutes les expressions utilises dans les instructions PL/pgSQL sont traites par l'excuteur SQL classique du serveur. En effet,
une requte comme
SELECT expression
735

PL/pgSQL - Langage de procdures SQL

est trait par le moteur SQL principal. Bien qu'utilisant la commande SELECT, tout nom de variable PL/pgSQL est remplac par
des paramtres (ceci est expliqu en dtail dans la Section 39.10.1, Substitution de variables ). Cela permet au plan de requte
du SELECT d'tre prpar une seule fois, puis d'tre rutilis pour les valuations suivantes avec diffrentes valeurs des variables.
Du coup, ce qui arrive rellement la premire utilisation d'une expression est simplement une commande PREPARE. Par
exemple, si nous dclarons deux variables de type integer, x et y, et que nous crivons :
IF x < y THEN ...
ce qui se passe en arrire plan est quivalent :
PREPARE nom_instruction(integer, integer) AS SELECT $1 < $2;
puis cette instruction prpare est excute (via EXECUTE) pour chaque excution de l'instruction IF, avec les valeurs actuelles
des variables PL/pgSQL fournies en tant que valeurs des paramtres. Le plan de requte prpar de cette faon est sauvegard
pour toute la dure de la connexion la base, comme le dcrit la Section 39.10.2, Mise en cache du plan . Gnralement, ces
dtails ne sont pas importants pour un utilisateur de PL/pgSQL, mais ils sont utiles connatre pour diagnostiquer un problme.

39.5. Instructions de base


Dans cette section ainsi que les suivantes, nous dcrirons tous les types d'instructions explicitement compris par PL/pgSQL. Tout
ce qui n'est pas reconnu comme l'un de ces types d'instruction est prsum tre une commande SQL et est envoy au moteur principal de bases de donnes pour tre excute comme dcrit dans la Section 39.5.2, Excuter une commande sans rsultats et
dans la Section 39.5.3, Excuter une requte avec une seule ligne de rsultats .

39.5.1. Affectation
L'affectation d'une valeur une variable PL/pgSQL s'crit ainsi :
variable := expression;
Comme expliqu prcdemment, l'expression dans cette instruction est value au moyen de la commande SQL SELECT envoye au moteur principal de bases de donnes. L'expression ne doit manier qu'une seule valeur (ventuellement une valeur de
range, si cette variable est une variable de range ou d'enrengistrement). La variable cible peut tre une simple varible
(ventuellement qualifie avec un nom de bloc), un champ d'une range ou variable d'enrengistrement ou un lment de tableau
qui se trouve tre une simple variable ou champ.
Si le type de donnes du rsultat de l'expression ne correspond pas au type de donne de la variable, ou que la variable a une taille
ou une prcision (comme char(20)), la valeur rsultat sera implicitement convertie par l'interprteur PL/pgSQL en utilisant la
fonction d'criture (output-function) du type du rsultat, et la fonction d'entre (input-function) du type de la variable. Notez que
cela peut conduire des erreurs d'excution gnres par la fonction d'entre si la forme de la chane de la valeur rsultat n'est pas
acceptable pour cette fonction.
Exemples :
taxe := sous_total * 0.06;
mon_enregistrement.id_utilisateur := 20;

39.5.2. Excuter une commande sans rsultats


Pour toute commande SQL qui ne renvoie pas de lignes, par exemple INSERT sans clause RETURNING, vous pouvez excuter la
commande l'intrieur d'une fonction PL/pgSQL rien qu'en crivant la commande.
Tout nom de variable PL/pgSQL apparaissant dans le texte de la commande est trait comme un paramtre, puis la valeur actuelle
de la variable est fournie comme valeur du paramtre l'excution. C'est le traitement exact dcrit prcdemment pour les expressions. Pour les dtails, voir la Section 39.10.1, Substitution de variables .
Lors de l'excution d'une commande SQL de cette faon, PL/pgSQL planifie la commande une fois et r-utilise ce plan lors des
prochaines excutions, pour la dure de vie de la connexion. Les implications de ceci sont discutes en dtail dans la Section 39.10.2, Mise en cache du plan .
Parfois, il est utile d'valuer une expression ou une requte SELECT mais sans rcuprer le rsultat, par exemple lors de l'appel
d'une fonction qui a des effets de bord mais dont la valeur du rsultat n'est pas utile. Pour faire cela en PL/pgSQL, utilisez
l'instruction PERFORM :
PERFORM requte;
Ceci excute la requte et ne tient pas compte du rsultat. crivez la requte de la mme faon que vous cririez une com736

PL/pgSQL - Langage de procdures SQL

mande SELECT mais remplacez le mot cl initial SELECT avec PERFORM. Pour les requtes WITH, utilisez PERFORM
puis placez la requte entre parenthses. (De cette faon, la requte peut seulement renvoyer une ligne.) Les variables PL/pgSQL
seront substitues dans la requte comme pour les commandes qui ne renvoient pas de rsultat. Le plan est mis en cache de la
mme faon. La variable spciale FOUND est configure true si la requte a produit au moins une ligne, false dans le cas
contraire (voir la Section 39.5.5, Obtention du statut du rsultat ).

Note
Vous pourriez vous attendre ce que l'utilisation directe de SELECT aboutisse au mme rsultat mais, actuellement, la seule faon accepte de le faire est d'utiliser PERFORM. Une commande SQL qui peut renvoyer des
lignes comme SELECT sera rejete comme une erreur si elle n'a pas de clause INTO, ce qui est discut dans la
section suivante.
Un exemple :
PERFORM creer_vuemat('cs_session_page_requests_mv', ma_requete);

39.5.3. Excuter une requte avec une seule ligne de rsultats


Le rsultat d'une commande SQL ne ramenant qu'une seule ligne (mais avec une ou plusieurs colonnes) peut tre affect une variable de type record, row ou une liste de variables scalaires. Ceci se fait en crivant la commande SQL de base et en ajoutant
une clause INTO. Par exemple,
SELECT
INSERT
UPDATE
DELETE

expressions_select INTO [STRICT] cible FROM ...;


... RETURNING expressions INTO [STRICT] cible;
... RETURNING expressions INTO [STRICT] cible;
... RETURNING expressions INTO [STRICT] cible;

o cible peut tre une variable de type record, row ou une liste de variables ou de champs record/row spares par des virgules.
Les variables PL/pgSQL seront substitues dans le reste de la requte, et le plan est mis en cache comme dcrit ci-dessus pour les
commandes qui ne renvoient pas de lignes. Ceci fonctionne pour SELECT, INSERT/UPDATE/DELETE avec RETURNING, et
les commandes utilitaires qui renvoient des rsultats de type rowset (comme EXPLAIN). Sauf pour la clause INTO, la commande
SQL est identique celle qui aurait t crite en dehors de PL/pgSQL.

Astuce
Notez que cette interprtation de SELECT avec INTO est assez diffrente de la commande habituelle SELECT
INTO o la cible INTO est une table nouvellement cre. Si vous voulez crer une table partir du rsultat d'un
SELECT l'intrieur d'une fonction PL/pgSQL, utilisez la syntaxe CREATE TABLE ... AS SELECT.
Si une ligne ou une liste de variables est utilise comme cible, les colonnes du rsultat de la requte doivent correspondre exactement la structure de la cible (nombre de champs et types de donnes). Dans le cas contraire, une erreur sera rapporte
l'excution. Quand une variable record est la cible, elle se configure automatiquement avec le type row des colonnes du rsultat de
la requte.
La clause INTO peut apparatre pratiquement partout dans la commande SQL. Elle est crite soit juste avant soit juste aprs la
liste d'expressions_select dans une commande SELECT, ou la fin de la commande pour d'autres types de commande. Il
est recommand de suivre cette convention au cas o l'analyseur PL/pgSQL devient plus strict dans les versions futures.
Si STRICT n'est pas spcifi dans la clause INTO, alors cible sera configur avec la premire ligne renvoye par la requte ou
NULL si la requte n'a renvoy aucune ligne. (Notez que la premire ligne n'est bien dfinie que si vous avez utilis ORDER
BY.) Toute ligne rsultat aprs la premire ligne est annule. Vous pouvez vrifier la valeur de la variable spciale FOUND (voir la
Section 39.5.5, Obtention du statut du rsultat ) pour dterminer si une ligne a t renvoye :
SELECT * INTO monrec FROM emp WHERE nom = mon_nom;
IF NOT FOUND THEN
RAISE EXCEPTION 'employ % introuvable', mon_nom;
END IF;
Si l'option STRICT est indique, la requte doit renvoyer exactement une ligne. Dans le cas contraire, une erreur sera rapporte
l'excution, soit NO_DATA_FOUND (aucune ligne) soit TOO_MANY_ROWS (plus d'une ligne). Vous pouvez utiliser un bloc
d'exception si vous souhaitez rcuprer l'erreur, par exemple :
BEGIN
SELECT * INTO STRICT monrec FROM emp WHERE nom = mon_nom;
EXCEPTION
WHEN NO_DATA_FOUND THEN
737

PL/pgSQL - Langage de procdures SQL

RAISE EXCEPTION 'employ % introuvable', mon_nom;


WHEN TOO_MANY_ROWS THEN
RAISE EXCEPTION 'employ % non unique', mon_nom;
END;
Une excution russie de la commande avec STRICT renvoie toujours true pour FOUND.
Pour INSERT/UPDATE/DELETE avec RETURNING, PL/pgSQL rapporte une erreur si plus d'une ligne est renvoye, mme
quand STRICT n'est pas spcifi. Ceci est d au fait qu'il n'y a pas d'option comme ORDER BY qui pourrait dterminer la ligne
renvoyer.

Note
L'option STRICT correspond au comportement du SELECT INTO d'Oracle PL/SQL et des instructions relatives.
Pour grer les cas o vous avez besoin de traiter plusieurs lignes de rsultat partir d'une requte SQL, voir la Section 39.6.4,
Boucler dans les rsultats de requtes .

39.5.4. Excuter des commandes dynamiques


Crer dynamique des requtes SQL est un besoin habituel dans les fonctions PL/pgSQL, par exemple des requtes qui impliquent
diffrentes tables ou diffrents types de donnes chaque fois qu'elles sont excutes. Les tentatives normales de PL/pgSQL pour
garder en cache les planifications des commandes (voir la Section 39.10.2, Mise en cache du plan ) ne fonctionneront pas dans
de tels scnarios. Pour grer ce type de problme, l'instruction EXECUTE est propose :
EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ...] ];
o chane-commande est une expression manipulant une chane (de type text) contenant la commande excuter. La cible
optionnelle est une variable record ou ligne ou mme une liste de variables simples ou de champs de lignes/enregistrements spares par des virgules, dans lesquels les rsultats de la commande seront enregistrs. Les expressions USING optionnelles fournissent des valeurs insrer dans la commande.
Aucune substitution des variables PL/pgSQL ne se fait dans la chane de commande calcule. Toutes les valeurs des variables requises doivent tre insres dans la chane de commande au moment de sa construction ; ou vous pouvez utiliser des paramtres
comme dcrits ci-dessous.
De plus, il n'y a pas mise en cache des commandes excutes via EXECUTE. la place, la commande est prpare chaque fois
que l'instruction est lance. La chane commande peut tre cre dynamiquement l'intrieur de la fonction pour agir sur des
tables ou colonnes diffrentes.
La clause INTO spcifie o devraient tre affects les rsultats d'une commande SQL renvoyant des lignes. Si une ligne ou une
liste de variable est fournie, elle doit correspondre exactement la structure des rsultats de la requte (quand une variable de type
record est utilise, elle sera automatiquement type pour correspondre la structure du rsultat). Si plusieurs lignes sont renvoyes, alors seule la premire sera assigne la variable INTO. Si aucune ligne n'est renvoye, NULL est affecte la variable
INTO. Si aucune clause INTO n'est spcifie, les rsultats de la requte sont ignors.
Si l'option STRICT est indique, une erreur est rapporte sauf si la requte produit exactement une ligne.
La chane de commande peut utiliser des valeurs de paramtres, rfrences dans la commande avec $1, $2, etc. Ces symboles
font rfrence aux valeurs fournies dans la clause USING. Cette mthode est souvent prfrable l'insertion des valeurs en texte
dans une chane de commande : cela vite la surcharge l'excution pour la conversion des valeurs en texte et vice-versa. C'est
aussi moins sensible aux attaques par injection SQL car il n'est pas ncessaire de mettre entre guillemets ou d'chapper les valeurs.
Voici un exemple :
EXECUTE 'SELECT count(*) FROM matable WHERE insere_par = $1 AND insere <= $2'
INTO c
USING utilisateur_verifie, date_verifiee;
Notez que les symboles de paramtres peuvent seulement tre utiliss pour des valeurs de donnes -- si vous voulez utiliser des
noms de tables et/ou colonnes dtermins dynamiquement, vous devez les insrer dans la chane de commande en texte. Par
exemple, si la requte prcdente devait se faire avec une table slectionne dynamiquement, vous devriez faire ceci :
EXECUTE 'SELECT count(*) FROM '
|| tabname::regclass
|| ' WHERE insere_par = $1 AND insere <= $2'
INTO c
USING utilisateur_verifie, date_verifiee;
738

PL/pgSQL - Langage de procdures SQL

Une autre restriction sur les symboles de paramtres est qu'ils ne marchent que dans les commandes SELECT, INSERT, UPDATE et DELETE. Dans les autres types d'instructions (appells de manire gnrique commandes utilitaires), vous devez insrer les valeurs sous forme de texte mme si ce ne sont que des donnes.
Un EXECUTE avec une chane de commande constante et des paramtres USING, comme dans le premier exemple ci-dessus, est
quivalent fonctionnellement l'criture simple d'une commande directement dans PL/pgSQL et permet le remplacement automatique des variables PL/pgSQL. La diffrence importante est que EXECUTE va planifier de nouveau la commande pour chaque
excution, gnrant un plan qui est spcifique aux valeurs actuelles des paramtres ; alors que PL/pgSQL cre habituellement un
plan gnrique et le stocke pour le rutiliser. Dans des situations o le meilleur plan dpend fortement des valeurs des paramtres,
EXECUTE peut tre beaucoup plus rapide : alors que lorsque le plan n'est pas sensible aux valeurs des paramtres, la replanification sera une perte.
SELECT INTO n'est actuellement pas support l'intrieur de EXECUTE ; la place, excutez une commande SELECT et
spcifiez INTO comme faisant parti lui-mme d'EXECUTE.

Note
L'instruction EXECUTE de PL/pgSQL n'a pas de relation avec l'instruction SQL EXECUTE(7) supporte par le
serveur PostgreSQL. L'instruction EXECUTE du serveur ne peut pas tre utilise directement dans les fonctions
PL/pgSQL. En fait, elle n'est pas ncessaire.
Exemple 39.1. Mettre entre guillemets des valeurs dans des requtes dynamiques

En travaillant avec des commandes dynamiques, vous aurez souvent grer des chappements de guillemets simples. La mthode
recommande pour mettre entre guillemets un texte fixe dans le corps de votre fonction est d'utiliser les guillemets dollar (si votre
code n'utilise pas les guillemets dollar, rfrez-vous l'aperu dans la Section 39.11.1, Utilisation des guillemets simples
(quotes) , ce qui peut vous faire gagner des efforts lors du passage de ce code un schma plus raisonnable).
Les valeurs dynamiques qui sont insrer dans la requte construite requirent une gestion spciale car elles pourraient ellesmme contenir des guillemets. Un exemple (ceci suppose que vous utilisez les guillemets dollar pour la fonction dans sa globalit,
du coup les guillemets n'ont pas besoin d'tre doubls) :
EXECUTE 'UPDATE tbl SET '
|| quote_ident(nom_colonne)
|| ' = '
|| quote_literal(nouvelle_valeur)
|| ' WHERE cle = '
|| quote_literal(valeur_cle);
Cet exemple dmontre l'utilisation des fonctions quote_ident et quote_literal (voir Section 9.4, Fonctions et oprateurs de chanes ). Pour plus de sret, les expressions contenant les identifiants des colonnes et des tables doivent tre passes
la fonction quote_ident avant l'insertion dans une requte dynamique. Les expressions contenant des valeurs de type chane de
caractres doivent tre passes quote_literal. Ce sont les tapes appropries pour renvoyer le texte en entre entour par
des guillemets doubles ou simples respectivement, en chappant tout caractre spcial.
Comme quote_literal est labelis STRICT, elle renverra toujours NULL lorsqu'elle est appele avec un argument NULL.
Dans l'exemple ci-dessus, si nouvelle_valeur ou valeur_cl taient NULL, la requte dynamique entire deviendrait
NULL, amenant une erreur partir du EXECUTE. Vous pouvez viter ce problme en utilisant la fonction quote_nullable
qui fonctionne de faon identique quote_literal sauf si elle est appele avec un argument NULL, elle renvoie la chane
NULL. Par exemple,
EXECUTE 'UPDATE tbl SET '
|| quote_ident(nom_colonne)
|| ' = '
|| quote_nullable(nouvelle_valeur)
|| ' WHERE key = '
|| quote_nullable(valeur_cl);
Si vous travaillez avez des valeurs qui peuvent tre NULL, vous devez utiliser quote_nullable la place de
quote_literal.
Comme toujours, il faut s'assurer que les valeurs NULL d'une requte ne ramnent pas des valeurs inattendues. Par exemple, la
clause WHERE

739

PL/pgSQL - Langage de procdures SQL

'WHERE key = ' || quote_nullable(valeur_cl)


ne sera jamais vrai si valeur_cl est NULL car le rsultat de l'oprateur d'galit, =, avec au moins un des oprandes NULL
est toujours NULL. Si vous souhaitez que NULL fonctionne comme toute autre valeur de cl ordinaire, vous devez r-crire la
clause ci-dessus de cette faon :
'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue)
(Actuellement, IS NOT DISTINCT FROM est gr moins efficacement que =, donc ne l'utilisez pas sauf en cas d'extrme ncessit. Voir Section 9.2, Oprateurs de comparaison pour plus d'informations sur les NULL et IS DISTINCT.)
Notez que les guillemets dollar sont souvent utiles pour placer un texte fixe entre guillemets. Ce serait une trs mauvaise ide
d'crire l'exemple ci-dessus de cette faon :
EXECUTE 'UPDATE tbl SET '
|| quote_ident(nom_colonne)
|| ' = $$'
|| nouvelle_valeur
|| '$$ WHERE cle = '
|| quote_literal(valeur_cle);
car cela casserait si le contenu de nouvelle_valeur pouvait contenir $$. La mme objection s'applique tout dlimiteur dollar que vous pourriez choisir. Donc, pour mettre un texte inconnu entre guillemets de faon sr, vous devez utiliser
quote_literal, quote_nullable ou quote_ident, comme appropri.
Les requtes SQL dynamiques peuvent aussi tre construites en toute scurit en utilisant la fonction format (voir Section 9.4,
Fonctions et oprateurs de chanes ). Par exemple :
EXECUTE format('UPDATE tbl SET %I = %L WHERE key = %L', colname, newvalue, keyvalue);
La fonction format peut tre utilise avec la clause USING :
EXECUTE format('UPDATE tbl SET %I = $1 WHERE cle = $2', nom_colonne)
USING nouvellevaleur, clevaleur;
Cette forme est plus efficace car les paramtres nouvellevaleur et clevaleur ne sont pas converties en texte.
Un exemple bien plus important d'une commande dynamique et d'EXECUTE est disponible dans l'Exemple 39.8, Portage d'une
fonction qui cre une autre fonction de PL/SQL vers PL/pgSQL , qui construit et excute une commande CREATE FUNCTION pour dfinir une nouvelle fonction.

39.5.5. Obtention du statut du rsultat


Il y a plusieurs moyens pour dterminer l'effet d'une commande. La premire mthode est d'utiliser GET DIAGNOSTICS :
GET DIAGNOSTICS variable = lment [ , ... ] ;
Cette commande permet la rcupration des indicateurs d'tat du systme. Chaque lment est un mot cl identifiant une valeur
d'tat devant tre affecte la variable indique (qui doit tre du bon type de donne pour que l'affectation puisse se faire sans erreur.) Les lments d'tat actuellement disponibles sont ROW_COUNT, le nombre de lignes traites par la dernire commande SQL
envoye au moteur SQL, et RESULT_OID, l'OID de la dernire ligne insre par la commande SQL la plus rcente. Notez que
RESULT_OID n'est utile qu'aprs une commande INSERT dans une table contenant des OID.
Exemple :
GET DIAGNOSTICS var_entier = ROW_COUNT;
La seconde mthode permettant de dterminer les effets d'une commande est la variable spciale nomme FOUND de type boolean. La variable FOUND est initialise false au dbut de chaque fonction PL/pgSQL. Elle est positionne par chacun des types
d'instructions suivants :

Une instruction SELECT INTO positionne FOUND true si une ligne est affecte, false si aucune ligne n'est renvoye.

Une instruction PERFORM positionne FOUND true si elle renvoie une ou plusieurs lignes, false si aucune ligne n'est produite.

Les instructions UPDATE, INSERT, et DELETE positionnent FOUND true si au moins une ligne est affecte, false si aucune ligne n'est affecte.
740

PL/pgSQL - Langage de procdures SQL

Une instruction FETCH positionne FOUND true si elle renvoie une ligne, false si aucune ligne n'est renvoye.

Une instruction MOVE initialise FOUND true si elle repositionne le curseur avec succs. Dans le cas contraire, elle le positionne false.

Une instruction FOR ou FOREACH initialise FOUND la valeur true s'il itre une ou plusieurs fois, et false dans les autres
cas. FOUND est initialis de cette faon quand la boucle se termine : pendant l'excution de la boucle, FOUND n'est pas modifi
par la boucle, bien qu'il pourrait tre modifi par l'excution d'autres requtes dans le corps de la boucle.

Les instructions RETURN QUERY et RETURN QUERY EXECUTE mettent jour la variable FOUND true si la requte
renvoie au moins une ligne, et false si aucune ligne n'est renvoye.

Les autres instructions PL/pgSQL ne changent pas l'tat de FOUND. Notez que la commande EXECUTE modifie la sortie de
GET DIAGNOSTICS mais ne change pas FOUND.
FOUND est une variable locale l'intrieur de chaque fonction PL/pgSQL ; chaque changement qui y est fait n'affecte que la fonction en cours.

39.5.6. Ne rien faire du tout


Quelque fois, une instruction qui ne fait rien est utile. Par exemple, elle indique qu'une partie de la chane IF/THEN/ELSE est dlibrment vide. Pour cela, utilisez l'instruction :
NULL;
Par exemple, les deux fragments de code suivants sont quivalents :
BEGIN
y := x / 0;
EXCEPTION
WHEN division_by_zero THEN
NULL; -- ignore l'erreur
END;
BEGIN
y := x / 0;
EXCEPTION
WHEN division_by_zero THEN
END;

-- ignore l'erreur

Ce qui est prfrable est une question de got.

Note
Dans le PL/SQL d'Oracle, les listes d'instructions vides ne sont pas autorises et, du coup, les instructions NULL
sont requises dans les situations telles que celles-ci. PL/pgSQL vous permet d'crire simplement rien.

39.6. Structures de contrle


Les structures de contrle sont probablement la partie la plus utile (et importante) de PL/pgSQL. Grce aux structures de contrle
de PL/pgSQL, vous pouvez manipuler les donnes PostgreSQL de faon trs flexible et puissante.

39.6.1. Retour d'une fonction


Il y a deux commandes disponibles qui vous permettent de renvoyer des donnes d'une fonction : RETURN et RETURN NEXT.

39.6.1.1. RETURN
RETURN expression;
RETURN accompagn d'une expression termine la fonction et renvoie le valeur de l'expression l'appelant. Cette forme doit
tre utilise avec des fonctions PL/pgSQL qui ne renvoient pas d'ensemble de valeurs.
Lorsqu'elle renvoie un type scalaire, n'importe quelle expression peut tre utilise. Le rsultat de l'expression sera automatiquement converti vers le type de retour de la fonction, comme dcrit pour les affectations. Pour renvoyer une valeur composite
(ligne), vous devez crire une variable record ou ligne comme expression.
Si vous dclarez la fonction avec des paramtres en sortie, crivez seulement RETURN sans expression. Les valeurs courantes
741

PL/pgSQL - Langage de procdures SQL

des paramtres en sortie seront renvoyes.


Si vous dclarez que la fonction renvoie void, une instruction RETURN peut tre utilise pour quitter rapidement la fonction ;
mais n'crivez pas d'expression aprs RETURN.
La valeur de retour d'une fonction ne peut pas tre laisse indfinie. Si le contrle atteint la fin du bloc de haut niveau de la fonction, sans parvenir une instruction RETURN, une erreur d'excution survient. Nanmoins, cette restriction ne s'applique pas aux
fonctions sans paramtre de sortie et aux fonctions renvoyant void. Dans ces cas, une instruction RETURN est automatiquement
excute si le bloc de haut niveau est termin.

39.6.1.2. RETURN NEXT et RETURN QUERY


RETURN NEXT expression;
RETURN QUERY requete;
RETURN QUERY EXECUTE command-string [ USING expression [, ...] ];
Quand une fonction PL/pgSQL dclare renvoyer SETOF un_certain_type, la procdure suivre est un peu diffrente. Dans
ce cas, les lments individuels renvoyer sont spcifis par une squence de commandes RETURN NEXT ou RETURN QUERY, suivies de la commande finale RETURN sans argument qui est utilise pour indiquer la fin de l'excution de la fonction. RETURN NEXT peut tre utilis avec des types de donnes scalaires comme composites ; avec un type de rsultat composite, une
table entire de rsultats sera renvoye. RETURN QUERY ajoute les rsultats de l'excution d'une requte l'ensemble des
rsultats de la fonction. RETURN NEXT et RETURN QUERY peuvent tre utiliss dans la mme fonction, auquel cas leurs rsultats seront concatnes.
RETURN NEXT et RETURN QUERY ne quittent pas rellement la fonction -- elles ajoutent simplement zro ou plusieurs
lignes l'ensemble de rsultats de la fonction. L'excution continue ensuite avec l'instruction suivante de la fonction PL/pgSQL.
Quand plusieurs commandes RETURN NEXT et/ou RETURN QUERY successives sont excutes, l'ensemble de rsultats augmente. Un RETURN, sans argument, permet de quitter la fonction mais vous pouvez aussi continuer jusqu' la fin de la fonction.
RETURN QUERY dispose d'une variante RETURN QUERY EXECUTE, qui spcifie la requte excuter dynamiquement.
Les expressions de paramtres peuvent tre insres dans la chane calcule via USING, de la mme faon que le fait la commande EXECUTE.
Si vous dclarez la fonction avec des paramtres en sortie, crivez RETURN NEXT sans expression. chaque excution, les valeurs actuelles des variables paramtres en sortie seront sauvegardes pour un renvoi ventuel en tant que rsultat en sortie. Notez
que vous devez dclarer la fonction en tant que SETOF record quand il y a plusieurs paramtres en sortie, ou SETOF
un_certain_type quand il y a un seul paramtre en sortie, et de type un_certain_type, pour crer une fonction SRF
avec des paramtres en sortie.
Voici un exemple d'une fonction utilisant RETURN NEXT :
CREATE TABLE truc (id_truc INT, sousid_truc INT, nom_truc TEXT);
INSERT INTO truc VALUES (1, 2, 'trois');
INSERT INTO truc VALUES (4, 5, 'six');
CREATE OR REPLACE FUNCTION obtenirTousLesTrucs() RETURNS SETOF foo AS
$BODY$
DECLARE
r truc%rowtype;
BEGIN
FOR r IN SELECT * FROM truc
WHERE id_truc > 0
LOOP
-- quelques traitements
RETURN NEXT r; -- renvoie la ligne courante du SELECT
END LOOP;
RETURN;
END
$BODY$
LANGUAGE 'plpgsql' ;
SELECT * FROM obtenirTousLesTrucs();

Note
L'implmentation actuelle de RETURN NEXT et de RETURN QUERY pour PL/pgSQL rcupre la totalit de
742

PL/pgSQL - Langage de procdures SQL

l'ensemble des rsultats avant d'effectuer le retour de la fonction, comme vu plus haut. Cela signifie que si une
fonction PL/pgSQL produit une structure rsultat trs grande, les performances peuvent tre faibles : les donnes
seront crites sur le disque pour viter un puisement de la mmoire mais la fonction en elle-mme ne renverra rien
jusqu' ce que l'ensemble complet des rsultats soit gnr. Une version future de PL/pgSQL permettra aux utilisateurs de dfinir des fonctions renvoyant des ensembles qui n'auront pas cette limitation. Actuellement, le point auquel les donnes commencent tre crites sur le disque est contrl par la variable de configuration work_mem.
Les administrateurs ayant une mmoire suffisante pour enregistrer des ensembles de rsultats plus importants en
mmoire doivent envisager l'augmentation de ce paramtre.

39.6.2. Contrles conditionnels


Les instructions IF et CASE vous permettent d'excuter des commandes bases sur certaines conditions. PL/pgSQL a trois formes
de IF :

IF ... THEN

IF ... THEN ... ELSE

IF ... THEN ... ELSIF ... THEN ... ELSE

et deux formes de CASE :

CASE ... WHEN ... THEN ... ELSE ... END CASE

CASE WHEN ... THEN ... ELSE ... END CASE

39.6.2.1. IF-THEN
IF expression-booleenne THEN
instructions
END IF;
Les instructions IF-THEN sont la forme la plus simple de IF. Les instructions entre THEN et END IF seront excutes si la
condition est vraie. Autrement, elles seront ignores.
Exemple :
IF v_id_utilisateur <> 0 THEN
UPDATE utilisateurs SET email = v_email WHERE id_utilisateur = v_id_utilisateur;
END IF;

39.6.2.2. IF-THEN-ELSE
IF expression-booleenne THEN
instructions
ELSE
instructions
END IF;
Les instructions IF-THEN-ELSE s'ajoutent au IF-THEN en vous permettant de spcifier un autre ensemble d'instructions excuter si la condition n'est pas vraie (notez que ceci inclut le cas o la condition s'value NULL.).
Exemples :
IF id_parent IS NULL OR id_parent = ''
THEN
RETURN nom_complet;
ELSE
RETURN hp_true_filename(id_parent) || '/' || nom_complet;
END IF;
IF v_nombre > 0 THEN
INSERT INTO nombre_utilisateurs (nombre) VALUES (v_nombre);
RETURN 't';
ELSE
RETURN 'f';
END IF;
743

PL/pgSQL - Langage de procdures SQL

39.6.2.3. IF-THEN-ELSIF
IF expression-booleenne THEN
instructions
[ ELSIF expression-booleenne THEN
instructions
[ ELSIF expression-booleenne THEN
instructions
...
]
]
[ ELSE
instructions ]
END IF;
Quelques fois, il existe plus de deux alternatives. IF-THEN-ELSIF fournit une mthode agrable pour vrifier diffrentes alternatives. Les conditions IF sont testes successivement jusqu' trouver la bonne. Alors les instructions associes sont excutes,
puis le contrle est pass la prochaine instruction aprs END IF. (Toute autre condition IF n'est pas teste.) Si aucune des
conditions IF n'est vraie, alors le bloc ELSE (s'il y en a un) est excut.
Voici un exemple :
IF nombre = 0 THEN
resultat := 'zero';
ELSIF nombre > 0 THEN
resultat := 'positif';
ELSIF nombre < 0 THEN
resultat := 'negatif';
ELSE
-- hmm, la seule possibilit est que le nombre soit NULL
resultat := 'NULL';
END IF;
Le mot cl ELSIF peut aussi s'crire ELSEIF.
Une faon alternative d'accomplir la mme tche est d'intgrer les instructions IF-THEN-ELSE, comme dans l'exemple suivant :
IF demo_row.sex = 'm' THEN
pretty_sex := 'man';
ELSE
IF demo_row.sex = 'f' THEN
pretty_sex := 'woman';
END IF;
END IF;
Nanmoins, cette mthode requiert d'crire un END IF pour chaque IF, donc c'est un peu plus compliqu que d'utiliser ELSIF
quand il y a beaucoup d'autres alternatives.

39.6.2.4. CASE simple


CASE expression_recherche
WHEN expression [, expression [ ... ]] THEN
instructions
[ WHEN expression [, expression [ ... ]] THEN
instructions
... ]
[ ELSE
instructions ]
END CASE;
La forme simple de CASE fournit une excution conditionnelle base sur l'galit des oprandes. L'expression-recherche
est value (une fois) puis compare successivement chaque expression dans les clauses WHEN. Si une correspondance est
trouve, alors les instructions correspondantes sont excutes, puis le contrle est pass la prochaine instruction aprs END
CASE. (Les autres expressions WHEN ne sont pas testes.) Si aucune correspondance n'est trouve, les instructions du bloc
ELSE sont excutes ; s'il n'y a pas de bloc ELSE, une exception CASE_NOT_FOUND est leve.
744

PL/pgSQL - Langage de procdures SQL

Voici un exemple simple :


CASE x
WHEN 1, 2 THEN
msg := 'un ou deux';
ELSE
msg := 'autre valeur que un ou deux';
END CASE;

39.6.2.5. CASE recherch


CASE
WHEN expression_boolenne THEN
instructions
[ WHEN expression_boolenne THEN
instructions
... ]
[ ELSE
instructions ]
END CASE;
La forme recherch de CASE fournit une excution conditionnelle base sur la vrification d'expressions boolennes. Chaque
expression-boolenne de la clause WHEN est value son tour jusqu' en trouver une qui est valide (true). Les instructions correspondantes sont excutes, puis le contrle est pass la prochaine instruction aprs END CASE. (Les expressions WHEN suivantes ne sont pas testes.) Si aucun rsultat vrai n'est trouv, les instructions du bloc ELSE sont excutes.
Si aucun bloc ELSE n'est prsent, une exception CASE_NOT_FOUND est leve.
Voici un exemple :
CASE
WHEN x BETWEEN 0 AND 10 THEN
msg := 'valeur entre zro et dix';
WHEN x BETWEEN 11 AND 20 THEN
msg := 'valeur entre onze et vingt';
END CASE;
Cette forme de CASE est entirement quivalente IF-THEN-ELSIF, sauf pour la rgle qui dit qu'atteindre une clause ELSE
omise rsulte dans une erreur plutt que ne rien faire.

39.6.3. Boucles simples


Grce aux instructions LOOP, EXIT, CONTINUE, WHILE FOR et FOREACH, vous pouvez faire en sorte que vos fonctions PL/
pgSQL rptent une srie de commandes.

39.6.3.1. LOOP
[<<label>>]
LOOP
instructions
END LOOP [ label ];
LOOP dfinit une boucle inconditionnelle rpte indfiniment jusqu' ce qu'elle soit termine par une instruction EXIT ou RETURN. Le label optionnel peut tre utilis par les instructions EXIT et CONTINUE dans le cas de boucles imbriques pour dfinir la boucle implique.

39.6.3.2. EXIT
EXIT [ label ] [ WHEN expression-boolenne ];
Si aucun label n'est donn, la boucle la plus imbrique se termine et l'instruction suivant END LOOP est excute. Si un label
est donn, ce doit tre le label de la boucle, du bloc courant ou d'un niveau moins imbriqu. La boucle ou le bloc nomm se termine alors et le contrle continue avec l'instruction situe aprs le END de la boucle ou du bloc correspondant.
Si WHEN est spcifi, la sortie de boucle ne s'effectue que si expression-boolenne est vraie. Sinon, le contrle passe
745

PL/pgSQL - Langage de procdures SQL

l'instruction suivant le EXIT.


EXIT peut tre utilis pour tous les types de boucles ; il n'est pas limit aux boucles non conditionnelles.
Lorsqu'il est utilis avec un bloc BEGIN, EXIT passe le contrle la prochaine instruction aprs la fin du bloc. Notez qu'un label
doit tre utilis pour cela ; un EXIT sans label n'est jamais pris en compte pour correspondre un bloc BEGIN. (Ceci est un changement de la version 8.4 de PostgreSQL. Auparavant, il tait permis de faire correspondre un EXIT sans label avec un bloc
BEGIN.)
Exemples :
LOOP
-- quelques traitements
IF nombre > 0 THEN
EXIT; -- sortie de boucle
END IF;
END LOOP;
LOOP
-- quelques traitements
EXIT WHEN nombre > 0;
END LOOP;
<<un_bloc>>
BEGIN
-- quelques traitements
IF stocks > 100000 THEN
EXIT un_bloc; -- cause la sortie (EXIT) du bloc BEGIN
END IF;
-- les traitements ici seront ignors quand stocks > 100000
END;

39.6.3.3. CONTINUE
CONTINUE [ label ] [ WHEN expression-boolenne ];
Si aucun label n'est donn, la prochaine itration de la boucle interne est commence. C'est--dire que toutes les instructions
restantes dans le corps de la boucle sont ignores et le contrle revient l'expression de contrle de la boucle pour dterminer si
une autre itration de boucle est ncessaire. Si le label est prsent, il spcifie le label de la boucle dont l'excution va tre continue.
Si WHEN est spcifi, la prochaine itration de la boucle est commence seulement si l'expression-boolenne est vraie. Sinon, le contrle est pass l'instruction aprs CONTINUE.
CONTINUE peut tre utilis avec tous les types de boucles ; il n'est pas limit l'utilisation des boucles inconditionnelles.
Exemples :
LOOP
-- quelques traitements
EXIT WHEN nombre > 100;
CONTINUE WHEN nombre < 50;
-- quelques traitements pour nombre IN [50 .. 100]
END LOOP;

39.6.3.4. WHILE
[<<label>>]
WHILE expression-boolenne LOOP
instructions
END LOOP [ label ];
L'instruction WHILE rpte une squence d'instructions aussi longtemps que expression-boolenne est value vrai.
L'expression est vrifie juste avant chaque entre dans le corps de la boucle.
Par exemple :
WHILE montant_possede > 0 AND balance_cadeau > 0 LOOP
-- quelques traitements ici
END LOOP;
746

PL/pgSQL - Langage de procdures SQL

WHILE NOT termine LOOP


-- quelques traitements ici
END LOOP;

39.6.3.5. FOR (variante avec entier)


[<<label>>]
FOR nom IN [ REVERSE ] expression .. expression [ BY expression ] LOOP
instruction
END LOOP [ label ];
Cette forme de FOR cre une boucle qui effectue une itration sur une plage de valeurs entires. La variable nom est automatiquement dfinie comme un type integer et n'existe que dans la boucle (toute dfinition de la variable est ignore l'intrieur de la
boucle). Les deux expressions donnant les limites infrieures et suprieures de la plage sont values une fois en entrant dans la
boucle. Si la clause BY n'est pas spcifie, l'tape d'itration est de 1, sinon elle est de la valeur spcifie dans la clause BY, qui est
value encore une fois l'entre de la boucle. Si REVERSE est indique, alors la valeur de l'tape est soustraite, plutt qu'ajoute,
aprs chaque itration.
Quelques exemples de boucles FOR avec entiers :
FOR i IN 1..10 LOOP
-- prend les valeurs 1,2,3,4,5,6,7,8,9,10 dans la boucle
END LOOP;
FOR i IN REVERSE 10..1 LOOP
-- prend les valeurs 10,9,8,7,6,5,4,3,2,1 dans la boucle
END LOOP;
FOR i IN REVERSE 10..1 BY 2 LOOP
-- prend les valeurs 10,8,6,4,2 dans la boucle
END LOOP;
Si la limite basse est plus grande que la limite haute (ou moins grande dans le cas du REVERSE), le corps de la boucle n'est pas
excut du tout. Aucune erreur n'est renvoye.
Si un label est attach la boucle FOR, alors la variable entire de boucle peut tre rfrence avec un nom qualifi en utilisant
ce label.

39.6.4. Boucler dans les rsultats de requtes


En utilisant un type de FOR diffrent, vous pouvez itrer au travers des rsultats d'une requte et par l-mme manipuler ces donnes. La syntaxe est la suivante :
[<<label>>]
FOR cible IN requte LOOP
instructions
END LOOP [ label ];
La cible est une variable de type record, row ou une liste de variables scalaires spares par une virgule. La cible est affecte
successivement chaque ligne rsultant de la requte et le corps de la boucle est excut pour chaque ligne. Voici un exemple :
CREATE FUNCTION cs_rafraichir_vuemat() RETURNS integer AS $$
DECLARE
vues_mat RECORD;
BEGIN
RAISE NOTICE 'Rafraichissement des vues matrialises...';
FOR vues_mat IN SELECT * FROM cs_vues_materialisees ORDER BY cle_tri LOOP
-- prsent vues_mat contient un enregistrement de cs_vues_materialisees
RAISE NOTICE 'Rafraichissement de la vue matrialise %s ...',
quote_ident(mviews.mv_name);
EXECUTE 'TRUNCATE TABLE ' || quote_ident(vues_mat.vm_nom);
EXECUTE 'INSERT INTO '
|| quote_ident(vues_mat.vm_nom) || ' '
|| vues_mat.vm_requete;
747

PL/pgSQL - Langage de procdures SQL

END LOOP;
RAISE NOTICE 'Fin du rafraichissement des vues matrialises.';
RETURN 1;
END;
$$ LANGUAGE plpgsql;
Si la boucle est termine par une instruction EXIT, la dernire valeur ligne affecte est toujours accessible aprs la boucle.
La requte utilise dans ce type d'instruction FOR peut tre toute commande SQL qui renvoie des lignes l'appelant : SELECT
est le cas le plus commun mais vous pouvez aussi utiliser INSERT, UPDATE ou DELETE avec une clause RETURNING. Certaines commandes comme EXPLAIN fonctionnent aussi.
Les variables PL/pgSQL sont substitues dans le texte de la requte et le plan de requte est mis en cache pour une rutilisation
possible. C'est couvert en dtail dans la Section 39.10.1, Substitution de variables et dans la Section 39.10.2, Mise en cache
du plan .
L'instruction FOR-IN-EXECUTE est un moyen d'itrer sur des lignes :
[<<label>>]
FOR target IN EXECUTE text_expression [ USING expression [, ...] ] LOOP
instructions
END LOOP [ label ];
Ceci est identique la forme prcdente, ceci prs que l'expression de la requte source est spcifie comme une expression
chane, value et replanifie chaque entre dans la boucle FOR. Ceci permet au dveloppeur de choisir entre la vitesse d'une requte prplanifie et la flexibilit d'une requte dynamique, uniquement avec l'instruction EXECUTE. Comme avec EXECUTE,
les valeurs de paramtres peuvent tre insres dans la commande dynamique via USING.
Une autre faon de spcifier la requte dont les rsultats devront tre itrs est de la dclarer comme un curseur. Ceci est dcrit
dans Section 39.7.4, Boucler dans les rsultats d'un curseur .

39.6.5. Boucler dans des tableaux


La boucle FOREACH ressemble beaucoup une boucle FOR mais, au lieu d'itrer sur les lignes renvoyes par une requtes SQL,
elle itre sur les lments d'une valeur de type tableau. (En gnral, FOREACH est fait pour boucler sur les composants d'une expression composite ; les variantes pour boucler sur des composites en plus des tableaux pourraient tre ajoutes dans le futur.)
L'instruction FOREACH pour boucler sur un tableau est :
[ <<label>> ]
FOREACH target [ SLICE nombre ] IN ARRAY expression LOOP
instructions
END LOOP [ label ];
Sans SLICE ou si SLICE 0 est indiqu, la boucle itre au niveau des lments individuels du tableau produit par l'valuation de
l'expression. La variable cible se voit affecte chaque valeur d'lment en squence, et le corps de la boucle est excut
pour chaque lment. Voici un exemple de boucle sur les lments d'un tableau d'entiers :
CREATE FUNCTION somme(int[]) RETURNS int8 AS $$
DECLARE
s int8 := 0;
x int;
BEGIN
FOREACH x IN ARRAY $1
LOOP
s := s + x;
END LOOP;
RETURN s;
END;
$$ LANGUAGE plpgsql;
Les lments sont parcourus dans l'ordre de leur stockage, quelque soit le nombre de dimensions du tableau. Bien que la cible
est habituellement une simple variable, elle peut tre une liste de variables lors d'une boucle dans un tableau de valeurs composites
(des enregistrements). Dans ce cas, pour chaque lment du tableau, les variables se voient affectes les colonnes de la valeur
composite.
Avec une valeur SLICE positive, FOREACH itre au travers des morceaux du tableau plutt que des lments seuls. La valeur de
SLICE doit tre un entier constant, moins large que le nombre de dimensions du tableau. La variable cible doit tre un tableau
748

PL/pgSQL - Langage de procdures SQL

et elle reoit les morceaux successifs de la valeur du tableau, o chaque morceau est le nombre de dimensions indiques par
SLICE. Voici un exemple d'itration sur des morceaux une dimension :
CREATE FUNCTION parcourt_lignes(int[]) RETURNS void AS $$
DECLARE
x int[];
BEGIN
FOREACH x SLICE 1 IN ARRAY $1
LOOP
RAISE NOTICE 'ligne = %', x;
END LOOP;
END;
$$ LANGUAGE plpgsql;
SELECT parcourt_lignes(ARRAY[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]);
NOTICE:
NOTICE:
NOTICE:
NOTICE:

ligne
ligne
ligne
ligne

=
=
=
=

{1,2,3}
{4,5,6}
{7,8,9}
{10,11,12}

39.6.6. Rcuprer les erreurs


Par dfaut, toute erreur survenant dans une fonction PL/pgSQL annule l'excution de la fonction mais aussi de la transaction qui
l'entoure. Vous pouvez rcuprer les erreurs en utilisant un bloc BEGIN avec une clause EXCEPTION. La syntaxe est une extension de la syntaxe habituelle pour un bloc BEGIN :
[ <<label>> ]
[ DECLARE
declarations ]
BEGIN
instructions
EXCEPTION
WHEN condition [ OR condition ... ] THEN
instructions_gestion_erreurs
[ WHEN condition [ OR condition ... ] THEN
instructions_gestion_erreurs
... ]
END;
Si aucune erreur ne survient, cette forme de bloc excute simplement toutes les instructions puis passe le contrle
l'instruction suivant END. Mais si une erreur survient l'intrieur des instructions, le traitement en cours des instructions est abandonn et le contrle est pass la liste d'EXCEPTION. Une recherche est effectue sur la liste pour la premire
condition correspondant l'erreur survenue. Si une correspondance est trouve, les instructions_gestion_erreurs
correspondantes sont excutes puis le contrle est pass l'instruction suivant le END. Si aucune correspondance n'est trouve,
l'erreur se propage comme si la clause EXCEPTION n'existait pas du tout : l'erreur peut tre rcupre par un bloc l'enfermant
avec EXCEPTION ou, s'il n'existe pas, elle annule le traitement de la fonction.
Les noms des condition sont indiques dans l'Annexe A, Codes d'erreurs de PostgreSQL. Un nom de catgorie correspond
toute erreur contenue dans cette catgorie. Le nom de condition spciale OTHERS correspond tout type d'erreur sauf QUERY_CANCELED (il est possible, mais pas recommand, de rcuprer QUERY_CANCELED par son nom). Les noms des conditions
ne sont pas sensibles la casse. De plus, une condition d'erreur peut tre indique par un code SQLSTATE ; par exemple, ces deux
cas sont quivalents :
WHEN division_by_zero THEN ...
WHEN SQLSTATE '22012' THEN ...
Si une nouvelle erreur survient l'intrieur des instructions_gestion_erreurs slectionnes, elle ne peut pas tre rcupre par cette clause EXCEPTION mais est propage en dehors. Une clause EXCEPTION l'englobant pourrait la rcuprer.
Quand une erreur est rcupre par une clause EXCEPTION, les variables locales de la fonction PL/pgSQL restent dans le mme
tat qu'au moment o l'erreur est survenue mais toutes les modifications l'tat persistant de la base de donnes l'intrieur du
bloc sont annules. Comme exemple, considrez ce fragment :
INSERT INTO mon_tableau(prenom, nom) VALUES('Tom', 'Jones');
BEGIN
UPDATE mon_tableau SET prenom = 'Joe' WHERE nom = 'Jones';
749

PL/pgSQL - Langage de procdures SQL

x := x + 1;
y := x / 0;
EXCEPTION
WHEN division_by_zero THEN
RAISE NOTICE 'rcupration de l''erreur division_by_zero';
RETURN x;
END;
Quand le contrle parvient l'affectation de y, il chouera avec une erreur division_by_zero. Elle sera rcupre par la
clause EXCEPTION. La valeur renvoye par l'instruction RETURN sera la valeur incrmente de x mais les effets de la commande UPDATE auront t annuls. La commande INSERT prcdant le bloc ne sera pas annule, du coup le rsultat final est
que la base de donnes contient Tom Jones et non pas Joe Jones.

Astuce
Un bloc contenant une clause EXCEPTION est significativement plus coteuse en entre et en sortie qu'un bloc
sans. Du coup, n'utilisez pas EXCEPTION sans besoin.
l'intrieur d'un gestionnaire d'exceptions, la variable SQLSTATE contient le code d'erreur correspondant l'exception qui a t
leve (rfrez-vous au Tableau A.1, Codes d'erreur de PostgreSQL pour une liste des codes d'erreurs possibles). La variable
SQLERRM contient le message d'erreur associ avec l'exception. Ces variables sont indfinies l'extrieur des gestionnaires
d'exceptions.
Exemple 39.2. Exceptions avec UPDATE/INSERT

Cet exemple utilise un gestionnaire d'exceptions pour raliser soit un UPDATE soit un INSERT, comme appropri :
CREATE TABLE base (a INT PRIMARY KEY, b TEXT);
CREATE FUNCTION fusionne_base(cle INT, donnee TEXT) RETURNS VOID AS
$$
BEGIN
LOOP
-- commenons par tenter la mise jour de la cl
UPDATE base SET b = donnee WHERE a = cle;
IF found THEN
RETURN;
END IF;
-- si elle n'est pas dispo, tentons l'insertion de la cl
-- si quelqu'un essaie d'insrer la mme cl en mme temps,
-- il y aura une erreur pour violation de cl unique
BEGIN
INSERT INTO base(a,b) VALUES (cle, donnee);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- ne rien faire, et tente de nouveau la mise jour
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;
SELECT fusionne_base(1, 'david');
SELECT fusionne_base(1, 'dennis');
Cet exemple suppose que l'erreur unique_violation est caus par la requte INSERT, et non pas par une fonction trigger sur
l'opration INSERT pour cette table.

39.7. Curseurs
Plutt que d'excuter la totalit d'une requte la fois, il est possible de crer un curseur qui encapsule la requte, puis en lit le rsultat quelques lignes la fois. Une des raisons pour faire de la sorte est d'viter les surcharges de mmoire quand le rsultat
contient un grand nombre de lignes (cependant, les utilisateurs PL/pgSQL n'ont gnralement pas besoin de se proccuper de cela
puisque les boucles FOR utilisent automatiquement un curseur en interne pour viter les problmes de mmoire). Un usage plus
intressant est de renvoyer une rfrence un curseur qu'une fonction a cr, permettant l'appelant de lire les lignes. C'est un
750

PL/pgSQL - Langage de procdures SQL

moyen efficace de renvoyer de grands ensembles de lignes partir des fonctions.

39.7.1. Dclaration de variables curseur


Tous les accs aux curseurs dans PL/pgSQL se font par les variables curseur, qui sont toujours du type de donnes spcial refcursor. Un des moyens de crer une variable curseur est de simplement la dclarer comme une variable de type refcursor. Un autre
moyen est d'utiliser la syntaxe de dclaration de curseur qui est en gnral :
nom [ [ NO ] SCROLL ] CURSOR [ ( arguments ) ] FOR requte;
(FOR peut tre remplac par IS pour la compatibilit avec Oracle). Si SCROLL est spcifi, le curseur sera capable d'aller en
sens inverse ; si NO SCROLL est indiqu, les rcuprations en sens inverses seront rejetes ; si rien n'est indiqu, cela dpend de
la requte. arguments est une liste de paires de nom type-de-donne qui dfinit les noms devant tre remplacs par les
valeurs des paramtres dans la requte donne. La valeur effective substituer pour ces noms sera indique plus tard lors de
l'ouverture du curseur.
Quelques exemples :
DECLARE
curs1 refcursor;
curs2 CURSOR FOR SELECT * FROM tenk1;
curs3 CURSOR (cle integer) IS SELECT * FROM tenk1 WHERE unique1 = cle;
Ces variables sont toutes trois du type de donnes refcursor mais la premire peut tre utilise avec n'importe quelle requte alors
que la seconde a une requte compltement spcifie qui lui est dj lie, et la dernire est lie une requte paramtre (cle sera
remplace par un paramtre de valeur entire lors de l'ouverture du curseur). La variable curs1 est dite non lie puisqu'elle n'est
pas lie une requte particulire.

39.7.2. Ouverture de curseurs


Avant qu'un curseur puisse tre utilis pour rapatrier des lignes, il doit tre ouvert (c'est l'action quivalente de la commande SQL
DECLARE CURSOR). PL/pgSQL dispose de trois formes pour l'instruction OPEN, dont deux utilisent des variables curseur
non lies et la dernire une variable curseur lie.

Note
Les variables des curseurs lis peuvent aussi tre utiliss sans les ouvrir explicitement, via l'instruction FOR dcrite
dans Section 39.7.4, Boucler dans les rsultats d'un curseur .

39.7.2.1. OPEN FOR requte


OPEN var_curseur_nonlie [ [ NO ] SCROLL ] FOR requete;
La variable curseur est ouverte et reoit la requte spcifie excuter. Le curseur ne peut pas tre dj ouvert, et il doit avoir t
dclar comme une variable de curseur non li (c'est--dire comme une simple variable refcursor). La requte doit tre un SELECT ou quelque chose d'autre qui renvoie des lignes (comme EXPLAIN). La requte est traite de la mme faon que les autres
commandes SQL dans PL/pgSQL : les noms de variables PL/pgSQL sont substitus et le plan de requte est mis en cache pour
une possible r-utilisation. Quand une variable PL/pgSQL est substitue dans une requte de type curseur, la valeur qui est substitue est celle qu'elle avait au moment du OPEN ; les modifications ultrieures n'auront pas affectes le comportement du curseur.
Les options SCROLL et NO SCROLL ont la mme signification que pour un curseur li.
Exemple :
OPEN curs1 FOR SELECT * FROM foo WHERE cle = ma_cle;

39.7.2.2. OPEN FOR EXECUTE


OPEN var_curseur_nonlie [ [ NO ] SCROLL ] FOR EXECUTE requete
[ USING expression [, ... ] ];
La variable curseur est ouverte et reoit la requte spcifie excuter. Le curseur ne peut pas tre dj ouvert et il doit avoir t
dclar comme une variable de curseur non li (c'est--dire comme une simple variable refcursor). La requte est spcifie comme
une expression chane de la mme faon que dans une commande EXECUTE. Comme d'habitude, ceci donne assez de flexibilit
pour que le plan de la requte puisse changer d'une excution l'autre (voir la Section 39.10.2, Mise en cache du plan ), et cela
signifie aussi que la substitution de variable n'est pas faite sur la chane de commande. Comme avec la commande EXECUTE, les
valeurs de paramtre peuvent tre insres dans la commande dynamique avec USING. Les options SCROLL et NO SCROLL ont
751

PL/pgSQL - Langage de procdures SQL

la mme signification que pour un curseur li.


Exemple :
OPEN curs1 FOR EXECUTE 'SELECT * FROM ' || quote_ident(tabname)
|| ' WHERE col1 = $1' USING keyvalue;
Dans cet exemple, le nom de la table est insre dans la requte textuellement et l'utilisation de quote_ident() est recommand afin de se prmunir contre des injections SQL. La valeur de comparaison pour col1 esr insre avec la paramtre USING et
n'a donc pas besoin d'tre protg.

39.7.2.3. Ouverture d'un curseur li


OPEN var_curseur_li [ ( arguments ) ];
Cette forme d'OPEN est utilise pour ouvrir une variable curseur laquelle la requte est lie au moment de la dclaration. Le
curseur ne peut pas tre dj ouvert. Une liste des expressions arguments doit apparatre si et seulement si le curseur a t dclar
comme acceptant des arguments. Ces valeurs seront remplaces dans la requte. Le plan de requte pour un curseur li est toujours
considr comme pouvant tre mis en cache ; il n'y a pas d'quivalent de la commande EXECUTE dans ce cas. Notez que
SCROLL et NO SCROLL ne peuvent pas tre indiqus car le comportement du curseur tait dj dtermin.
Notez que, parce que la substitution de variables est faite sur la requte du curseur li, il y a deux faon de passer des valeurs au
curseur : soit explicitement avec un argument pour OPEN soit implicitement en rfrenant une variable PL/pgSQL dans la requte. Nanmoins, seules les variables dclares avant la dclaration du curseur li pourront tre substitues. De toute faon, la valeur passer est dtermin au moment de l'excution de OPEN.
Exemples :
OPEN curs2;
OPEN curs3(42);

39.7.3. Utilisation des curseurs


Une fois qu'un curseur a t ouvert, il peut tre manipul grce aux instructions dcrites ci-dessous.
Ces manipulations n'ont pas besoin de se drouler dans la mme fonction que celle qui a ouvert le curseur. Vous pouvez renvoyer
une valeur refcursor partir d'une fonction et laisser l'appelant oprer sur le curseur (d'un point de vue interne, une valeur refcursor est simplement la chane de caractres du nom d'un portail contenant la requte active pour le curseur. Ce nom peut tre pass
d'autres, affect d'autres variables refcursor et ainsi de suite, sans dranger le portail).
Tous les portails sont implicitement ferms la fin de la transaction. C'est pourquoi une valeur refcursor est utilisable pour rfrencer un curseur ouvert seulement jusqu' la fin de la transaction.

39.7.3.1. FETCH
FETCH [ direction { FROM | IN } ] curseur INTO cible;
FETCH rcupre la prochaine ligne partir d'un curseur et la place dans une cible, qui peut tre une variable ligne, une variable
record ou une liste de variables simples spares par des virgules, comme dans un SELECT INTO. S'il n'y a pas de ligne suivante, la cible est mise NULL. Comme avec SELECT INTO, la variable spciale FOUND peut tre lue pour voir si une ligne a
t rcupre.
La clause direction peut tre une des variantes suivantes autorises pour la commande SQL FETCH(7) sauf celles qui peuvent
rcuprer plus d'une ligne ; nommment, cela peut tre NEXT, PRIOR, FIRST, LAST, ABSOLUTE nombre, RELATIVE
nombre, FORWARD ou BACKWARD. Omettre direction est identique spcifier NEXT. Les valeurs direction qui ncessitent d'aller en sens inverse risquent d'chouer sauf si le curseur a t dclar ou ouvert avec l'option SCROLL.
curseur doit tre le nom d'une variable refcursor qui rfrence un portail de curseur ouvert.
Exemples :
FETCH
FETCH
FETCH
FETCH

curs1 INTO rowvar;


curs2 INTO foo, bar, baz;
LAST FROM curs3 INTO x, y;
RELATIVE -2 FROM curs4 INTO x;

39.7.3.2. MOVE
752

PL/pgSQL - Langage de procdures SQL

MOVE [ direction { FROM | IN } ] curseur;


MOVE repositionne un curseur sans rcuprer de donnes. MOVE fonctionne exactement comme la commande FETCH sauf
qu'elle ne fait que repositionner le curseur et ne renvoie donc pas les lignes du dplacement. Comme avec SELECT INTO, la variable spciale FOUND peut tre lue pour vrifier s'il y avait bien les lignes correspondant au dplacement.
La clause de direction peut tre l'une des variantes autorises dna sla commande SQL FETCH(7), nommment NEXT,
PRIOR, FIRST, LAST, ABSOLUTE nombre, RELATIVE nombre, ALL, FORWARD [ nombre | ALL ], ou BACKWARD [
nombre | ALL ]. Omettre direction est identique spcifier NEXT. Les valeurs direction qui ncessitent de se dplacer
en arrire risquent d'chouer sauf si le curseur a t dclar ou ouvert avec l'option SCROLL.
Exemples :
MOVE
MOVE
MOVE
MOVE

curs1;
LAST FROM curs3;
RELATIVE -2 FROM curs4;
FORWARD 2 FROM curs4;

39.7.3.3. UPDATE/DELETE WHERE CURRENT OF


UPDATE table SET ... WHERE CURRENT OF curseur;
DELETE FROM table WHERE CURRENT OF curseur;
Quand un curseur est positionn sur une ligne d'une table, cette ligne peut tre mise jour ou supprime en utilisant le curseur qui
identifie la ligne. Il existe des restrictions sur ce que peut tre la requte du curseur (en particulier, pas de regroupement) et il est
mieux d'utiliser FOR UPDATE dans le curseur. Pour des informations supplmentaires, voir la page de rfrence DECLARE(7).
Un exemple :
UPDATE foo SET valdonnee = mavaleur WHERE CURRENT OF curs1;

39.7.3.4. CLOSE
CLOSE curseur;
CLOSE ferme le portail sous-tendant un curseur ouvert. Ceci peut tre utilis pour librer des ressources avant la fin de la transaction ou pour librer la variable curseur pour pouvoir la rouvrir.
Exemple :
CLOSE curs1;

39.7.3.5. Renvoi de curseurs


Les fonctions PL/pgSQL peuvent renvoyer des curseurs l'appelant. Ceci est utile pour renvoyer plusieurs lignes ou colonnes,
spcialement avec des ensembles de rsultats trs grands. Pour cela, la fonction ouvre le curseur et renvoie le nom du curseur
l'appelant (ou simplement ouvre le curseur en utilisant un nom de portail spcifi par ou autrement connu par l'appelant).
L'appelant peut alors rcuprer les lignes partir du curseur. Le curseur peut tre ferm par l'appelant ou il sera ferm automatiquement la fin de la transaction.
Le nom du portail utilis pour un curseur peut tre spcifi par le dveloppeur ou peut tre gnr automatiquement. Pour spcifier
un nom de portail, affectez simplement une chane la variable refcursor avant de l'ouvrir. La valeur de la variable refcursor sera
utilise par OPEN comme nom du portail sous-jacent. Nanmoins, si la variable refcursor est NULL, OPEN gnre automatiquement un nom qui n'entre pas en conflit avec tout portail existant et l'affecte la variable refcursor.

Note
Une variable curseur avec limites est initialise avec la valeur de la chane reprsentant son nom, de faon ce que
le nom du portail soit identique au nom de la variable curseur, sauf si le dveloppeur le surcharge par affectation
avant d'ouvrir le curseur. Mais, une variable curseur sans limite aura par dfaut la valeur NULL, dont il reoit un
nom unique gnr automatiquement sauf s'il est surcharg.

753

PL/pgSQL - Langage de procdures SQL

L'exemple suivant montre une faon de fournir un nom de curseur par l'appelant :
CREATE TABLE test (col text);
INSERT INTO test VALUES ('123');
CREATE FUNCTION fonction_reference(refcursor) RETURNS refcursor AS $$
BEGIN
OPEN $1 FOR SELECT col FROM test;
RETURN $1;
END;
$$ LANGUAGE plpgsql;
BEGIN;
SELECT fonction_reference('curseur_fonction');
FETCH ALL IN curseur_fonction;
COMMIT;
L'exemple suivant utilise la gnration automatique du nom du curseur :
CREATE FUNCTION fonction_reference2() RETURNS refcursor AS $$
DECLARE
ref refcursor;
BEGIN
OPEN ref FOR SELECT col FROM test;
RETURN ref;
END;
$$ LANGUAGE plpgsql;
-- Il faut tre dans une transaction pour utiliser les curseurs.
BEGIN;
SELECT fonction_reference2();
fonction_reference2
-------------------------<unnamed cursor 1>
(1 row)
FETCH ALL IN "<unnamed cursor 1>";
COMMIT;
L'exemple suivant montre une faon de renvoyer plusieurs curseurs une seule fonction :
CREATE FUNCTION ma_fonction(refcursor, refcursor) RETURNS SETOF refcursor AS $$
BEGIN
OPEN $1 FOR SELECT * FROM table_1;
RETURN NEXT $1;
OPEN $2 FOR SELECT * FROM table_2;
RETURN NEXT $2;
END;
$$ LANGUAGE plpgsql;
-- doit tre dans une transaction pour utiliser les curseurs.
BEGIN;
SELECT * FROM ma_fonction('a', 'b');
FETCH ALL FROM a;
FETCH ALL FROM b;
COMMIT;

39.7.4. Boucler dans les rsultats d'un curseur


C'est une variante de l'instruction FOR qui permet l'itration sur les lignes renvoyes par un curseur. La syntaxe est :
[ <<label>> ]
FOR var_record IN var_curseur_li [ ( valeurs_argument ) ] LOOP
instructions
END LOOP [ label ];
754

PL/pgSQL - Langage de procdures SQL

La variable curseur doit avoir t lie une requte lors de sa dclaration et il ne peut pas tre dj ouvert. L'instruction FOR
ouvre automatiquement le curseur, et il ferme le curseur en sortie de la boucle. Une liste des expressions de valeurs des arguments
doit apparatre si et seulement si le curseur a t dclar prendre des arguments. Ces valeurs seront substitutes dans la requte, de
la mme faon que lors d'un OPEN. La variable variable var_record est dfinie automatiquement avec le type record et existe
seulement dans la boucle (toute dfinition existante d'un nom de variable est ignore dans la boucle). Chaque ligne renvoye par le
curseur est successivement affecte la variable d'enregistrement et le corps de la boucle est excut.

39.8. Erreurs et messages


Utilisez l'instruction RAISE pour rapporter des messages et lever des erreurs.
RAISE
];
RAISE
RAISE
RAISE
RAISE

[ niveau ] 'format' [, expression [, ...]] [ USING option = expression [, ... ]


[ niveau ] nom_condition [ USING option = expression [, ... ] ];
[ niveau ] SQLSTATE 'tat_sql' [ USING option = expression [, ... ] ];
[ niveau ] USING option = expression [, ... ];
;

L'option niveau indique la svrit de l'erreur. Les niveaux autoriss sont DEBUG, LOG, INFO, NOTICE, WARNING et EXCEPTION, ce dernier tant la valeur par dfaut. EXCEPTION lve une erreur (ce qui annule habituellement la transaction en cours).
Les autres niveaux ne font que gnrer des messages aux diffrents niveaux de priorit. Les variables de configuration
log_min_messages et client_min_messages contrlent l'envoi de messages dans les traces, au client ou aux deux. Voir le Chapitre 18, Configuration du serveur pour plus d'informations.
Aprs niveau, vous pouvez crire un format (qui doit tre une chane litrale, pas une expression). La chane format indique le
texte du message d'erreur rapporter. Elle peut tre suivie par des expressions optionnelles insrer dans le message. Dans la
chane, % est remplac par la reprsentation de la valeur du prochain argument. crivez %% pour saisir un % litral.
Dans cet exemple, la valeur de v_job_id remplace le % dans la chane.
RAISE NOTICE 'Appel de cs_creer_job(%)', v_job_id;
Vous pouvez attacher des informations supplmentaires au rapport d'erreur en crivant USING suivi par des lments option =
expression. Les mots cls autorises pour option sont MESSAGE, DETAIL, HINT et ERRCODE, alors que chaque expression peut tre une expression de type chane. MESSAGE configure le texte de l'erreur (cette option ne peut pas tre utilise
sous la forme de RAISE qui inclut une chane de format avant USING). DETAIL fournit un message dtaill de l'erreur, HINT
propose une astuce. ERRCODE indique le code d'erreur (SQLSTATE) rapporter, soit par le nom de la condition comme indique
dans Annexe A, Codes d'erreurs de PostgreSQL, soit directement sous la forme d'un code SQLSTATE cinq caractres.
Cet exemple annulera la transaction avec le message d'erreur et l'astuce donns :
RAISE EXCEPTION 'Nonexistent ID --> %', user_id
USING HINT = 'Please check your user id';
Ces deux exemples affichent des faons quivalents pour initialiser SQLSTATE :
RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation';
RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505';
Il existe une deuxime syntaxe RAISE pour laquelle l'argument principale est le nom de la condition ou le SQLSTATE rapporter, par exemple :
RAISE division_by_zero;
RAISE SQLSTATE '22012';
Dans cette syntaxe, USING peut tre utilis pour fournir un message d'erreur, un dtail ou une astuce personnalis. Voici une autre
faon de faire l'exemple prcdent :
RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id;
Une autre variante est d'crire RAISE USING ou RAISE niveau USING et de placer tout le reste dans la liste USING.
La dernire variante de RAISE n'a aucun paramtre. Cette forme peut seulement tre utilise dans un bloc BEGIN d'une clause
EXCEPTION ; cela fait que l'erreur est renvoye.

755

PL/pgSQL - Langage de procdures SQL

Note
Avant PostgreSQL 9.1, RAISE sans paramtres tait interprt comme un renvoi de l'erreur partir du bloc
contenant le gestionnaire actif d'exceptions. Du coup, une clause EXCEPTION imbrique dans ce gestionnaire ne la
rcuprerait pas, mme si le RAISE tait intgre dans le bloc de la clause EXCEPTION. C'tait trs surprenant et
incompatible avec PL/SQL d'Oracle.
Si aucun nom de condition ou SQLSTATE n'est indiqu dans une commande RAISE EXCEPTION, la valeur par dfaut est
d'utiliser RAISE_EXCEPTION (P0001). Si aucun message texte n'est indiqu, la valeur par dfaut est d'utiliser le nom de la
condition ou le SQLSTATE comme texte de message.

Note
Lors de la spcification du code d'erreur par un code SQLSTATE, vous n'tes pas limit aux codes d'erreur prdfinis, mais pouvez slectionner tout code d'erreur consistant en cinq chiffres et/ou des lettres ASCII majuscules, autre
que 00000. Il est recommand d'viter d'envoyer des codes d'erreur qui se terminent avec trois zros car il y a des
codes de catgorie, et peuvent seulement tre rcuprs en filtrant la catgorie complte.

39.9. Procdures trigger


PL/pgSQL peut tre utilis pour dfinir des procdures trigger. Une procdure trigger est cre grce la commande CREATE
FUNCTION utilise comme fonction sans arguments ayant un type de retour trigger. Notez que la fonction doit tre dclare avec
aucun argument mme si elle s'attend recevoir les arguments spcifis dans CREATE TRIGGER -- les arguments trigger sont
passs via TG_ARGV, comme dcrit plus loin.
Quand une fonction PL/pgSQL est appele en tant que trigger, plusieurs variables spciales sont cres automatiquement dans le
bloc de plus haut niveau. Ce sont :
NEW
Type de donnes RECORD ; variable contenant la nouvelle ligne de base de donnes pour les oprations INSERT/UPDATE
dans les triggers de niveau ligne. Cette variable est NULL dans un trigger de niveau instruction et pour les oprations DELETE.
OLD
Type de donnes RECORD ; variable contenant l'ancienne ligne de base de donnes pour les oprations UPDATE/DELETE
dans les triggers de niveau ligne. Cette variable est NULL dans les triggers de niveau instruction et pour les oprations INSERT.
TG_NAME
Type de donnes name ; variable qui contient le nom du trigger rellement lanc.
TG_WHEN
Type de donnes text ; une chane, soit BEFORE soit AFTER, soit INSTEAD OF selon la dfinition du trigger.
TG_LEVEL
Type de donnes text ; une chane, soit ROW soit STATEMENT, selon la dfinition du trigger.
TG_OP
Type de donnes text ; une chane, INSERT, UPDATE, DELETE ou TRUNCATE indiquant pour quelle opration le trigger a
t lanc.
TG_RELID
Type de donnes oid ; l'ID de l'objet de la table qui a caus le dclenchement du trigger.
TG_RELNAME
Type de donnes name ; le nom de la table qui a caus le dclenchement. C'est obsolte et pourrait disparatre dans une prochaine version. la place, utilisez TG_TABLE_NAME.
TG_TABLE_NAME
Type de donnes name ; le nom de la table qui a dclench le trigger.
TG_TABLE_SCHEMA
Type de donnes name ; le nom du schma de la table qui a appel le trigger.
TG_NARGS
Type de donnes integer ; le nombre d'arguments donns la procdure trigger dans l'instruction CREATE TRIGGER.
756

PL/pgSQL - Langage de procdures SQL

TG_ARGV[]
Type de donne text ; les arguments de l'instruction CREATE TRIGGER. L'index dbute 0. Les indices invalides
(infrieurs 0 ou suprieurs ou gaux tg_nargs) auront une valeur NULL.
Une fonction trigger doit renvoyer soit NULL soit une valeur record ayant exactement la structure de la table pour laquelle le trigger a t lanc.
Les triggers de niveau ligne lancs BEFORE peuvent renvoyer NULL pour indiquer au gestionnaire de trigger de sauter le reste de
l'opration pour cette ligne (les triggers suivants ne sont pas lancs, et les INSERT/UPDATE/DELETE ne se font pas pour cette
ligne). Si une valeur non NULL est renvoye alors l'opration se droule avec cette valeur ligne. Renvoyer une valeur ligne diffrente de la valeur originale de NEW modifie la ligne qui sera insre ou mise jour. De ce fait, si la fonction de trigger veut que
l'action russise sans modifier la valeur de range, NEW (ou une valeur gale) doit tre renvoye. Pour modifier la range tre
stocke, il est possible de remplacer les valeurs directement dans NEW et renvoyer le NEW modifi ou de gnrer un nouvel enregistrement renvoyer. Dans le cas d'un before-trigger sur une commande DELETE, la valeur renvoye n'a aucun effet direct mais
doit tre non-nulle pour permettre l'action trigger de continuer. Notez que NEW est nul dans le cadre des triggers DELETE et
que renvoyer ceci n'est pas recommand dans les cas courants. Une pratique utile dans des triggers DELETE serait de renvoyer
OLD.
Les triggers INSTEAD OF (qui sont toujours des triggers au niveau ligne et peuvent seulement tre utiliss sur des vues) peuvent
renvoyer NULL pour signaler qu'ils n'ont fait aucune modification et que le reste de l'opration pour cette ligne doit tre ignor
(autrement dit, les triggers suivants ne sont pas dclenchs et la ligne n'est pas compte dans le statut des lignes affectes pour la
requte INSERT/UPDATE/DELETE). Une valeur diffrente de NULL doit tre renvoye pour indiquer que le trigger a trait
l'opration demande. Pour les oprations INSERT et UPDATE, la valeur de retour doit tre NEW, que la fonction trigger peut
modifier pour supporter une clause RETURNING d'une requte INSERT ou UPDATE (cela affectera aussi la valeur de la ligne
passe aux autres triggers). Pour les requtes DELETE, la valeur de retour doit tre OLD.
La valeur de retour d'un trigger de niveau range dclench AFTER ou un trigger de niveau instruction dclench BEFORE ou
AFTER est toujours ignor ; il pourrait aussi bien tre NULL. Nanmoins, tous les types de triggers peuvent toujours annuler
l'opration complte en envoyant une erreur.
L'Exemple 39.3, Une procdure trigger PL/pgSQL montre un exemple d'une procdure trigger dans PL/pgSQL.
Exemple 39.3. Une procdure trigger PL/pgSQL

Cet exemple de trigger assure qu' chaque moment o une ligne est insre ou mise jour dans la table, le nom de l'utilisateur courant et l'heure sont estampills dans la ligne. Et cela vous assure qu'un nom d'employ est donn et que le salaire est une valeur positive.
CREATE TABLE emp (
nom_employe text,
salaire integer,
date_dermodif timestamp,
utilisateur_dermodif text
);
CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
BEGIN
-- Verifie que nom_employe et salary sont donns
IF NEW.nom_employe IS NULL THEN
RAISE EXCEPTION 'nom_employe ne peut pas tre NULL';
END IF;
IF NEW.salaire IS NULL THEN
RAISE EXCEPTION '% ne peut pas avoir un salaire', NEW.nom_employe;
END IF;
-- Qui travaille pour nous si la personne doit payer pour cela ?
IF NEW.salaire < 0 THEN
RAISE EXCEPTION '% ne peut pas avoir un salaire ngatif', NEW.nom_employe;
END IF;
-- Rappelons-nous qui a chang le salaire et quand
NEW.date_dermodif := current_timestamp;
NEW.utilisateur_dermodif := current_user;
RETURN NEW;
END;
$emp_stamp$ LANGUAGE plpgsql;

757

PL/pgSQL - Langage de procdures SQL

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp


FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
Une autre faon de tracer les modifications sur une table implique la cration d'une nouvelle table qui contient une ligne pour
chaque insertion, mise jour ou suppression qui survient. Cette approche peut tre vue comme un audit des modifications sur une
table. L'Exemple 39.4, Une procdure d'audit par trigger en PL/pgSQL montre un exemple d'une procdure d'audit par trigger
en PL/pgSQL.
Exemple 39.4. Une procdure d'audit par trigger en PL/pgSQL

Cet exemple de trigger nous assure que toute insertion, modification ou suppression d'une ligne dans la table emp est enregistre
dans la table emp_audit. L'heure et le nom de l'utilisateur sont conserves dans la ligne avec le type d'opration ralis.
CREATE TABLE emp (
nom_employe
salaire
);

text NOT NULL,


integer

CREATE TABLE emp_audit(


operation
char(1)
tampon
timestamp
id_utilisateur
text
nom_employe
text
salaire
integer
);
CREATE
BEGIN
-----IF

NOT
NOT
NOT
NOT

NULL,
NULL,
NULL,
NULL,

OR REPLACE FUNCTION audit_employe() RETURNS TRIGGER AS $emp_audit$


Ajoute une ligne dans emp_audit pour reflter l'opration ralise
sur emp,
utilise la variable spciale TG_OP pour cette opration.

(TG_OP = 'DELETE') THEN


INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*;
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*;
RETURN NEW;
END IF;
RETURN NULL; -- le rsultat est ignor car il s'agit d'un trigger AFTER

END;
$emp_audit$ language plpgsql;
CREATE TRIGGER emp_audit
AFTER INSERT OR UPDATE OR DELETE ON emp
FOR EACH ROW EXECUTE PROCEDURE audit_employe();
Une variation de l'exemple prcdent utilise une vue joignant la table principale et la table d'audit pour montrer les derniers enregistrements modifis. Cette approche enregistre toujours toutes les modifications sur la table mais prsente aussi une vue simple
de l'audit, n'affichant que le date et heure de la dernire modification pour chaque enregistrement. Exemple 39.5, Une fonction
trigger en PL/pgSQL surune vue pour un audit montre un exemple d'un trigger d'audit sur une vue avec PL/pgSQL.
Exemple 39.5. Une fonction trigger en PL/pgSQL surune vue pour un audit

Cet exemple utilise un trigger sur une vue pour la rendre modifiable, et s'assure que toute insertion, mise jour ou suppression
d'une ligne dans la vue est enregistre (pour l'audit) dans la table emp_audit. La date et l'heure courante ainsi que le nom de
l'utilisateur sont enregistrs, avec le type d'opration ralis pour que la vue affiche la date et l'heure de la dernire modification de
chaque ligne.
CREATE TABLE emp (
758

PL/pgSQL - Langage de procdures SQL

nom_employe
salaire

text PRIMARY KEY,


integer

);
CREATE TABLE emp_audit(
operation
char(1)
id_utilisateur
text
nom_employe
text
salaire
integer,
dmodif
timestamp
);

NOT NULL,
NOT NULL,
NOT NULL,
NOT NULL

CREATE VIEW emp_vue AS


SELECT e.nom_employe,
e.salaire,
max(ea.dmodif) AS derniere_modification
FROM emp e
LEFT JOIN emp_audit ea ON ea.nom_employe = e.nom_employe
GROUP BY 1, 2;
CREATE OR REPLACE FUNCTION miseajour_emp_vue() RETURNS TRIGGER AS $$
BEGIN
--- Perform the required operation on emp, and create a row in emp_audit
-- to reflect the change made to emp.
-IF (TG_OP = 'DELETE') THEN
DELETE FROM emp WHERE nom_employe = OLD.nom_employe;
IF NOT FOUND THEN RETURN NULL; END IF;
OLD.derniere_modification = now();
INSERT INTO emp_audit VALUES('D', user, OLD.*);
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
UPDATE emp SET salary = NEW.salary WHERE nom_employe = OLD.nom_employe;
IF NOT FOUND THEN RETURN NULL; END IF;
NEW.derniere_modification = now();
INSERT INTO emp_audit VALUES('U', user, NEW.*);
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO emp VALUES(NEW.nom_employe, NEW.salaire);
NEW.derniere_modification = now();
INSERT INTO emp_audit VALUES('I', user, NEW.*);
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER emp_audit
INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_vue
FOR EACH ROW EXECUTE PROCEDURE miseajour_emp_vue();
Une utilisation des triggers est le maintien d'une table rsume d'une autre table. Le rsum rsultant peut tre utilis la place de
la table originale pour certaines requtes -- souvent avec des temps d'excution bien rduits. Cette technique est souvent utilise
pour les statistiques de donnes o les tables de donnes mesures ou observes (appeles des tables de faits) peuvent tre extrmement grandes. L'Exemple 39.6, Une procdure trigger PL/pgSQL pour maintenir une table rsume montre un exemple
d'une procdure trigger en PL/pgSQL maintenant une table rsume pour une table de faits dans un systme de donnes (data warehouse).
Exemple 39.6. Une procdure trigger PL/pgSQL pour maintenir une table rsume

Le schma dtaill ici est partiellement bas sur l'exemple du Grocery Store provenant de The Data Warehouse Toolkit par Ralph
Kimball.
-759

PL/pgSQL - Langage de procdures SQL

-- Tables principales - dimension du temps de ventes.


-CREATE TABLE time_dimension (
time_key
integer NOT NULL,
day_of_week
integer NOT NULL,
day_of_month
integer NOT NULL,
month
integer NOT NULL,
quarter
integer NOT NULL,
year
integer NOT NULL
);
CREATE UNIQUE INDEX time_dimension_key ON time_dimension(time_key);
CREATE TABLE sales_fact (
time_key
integer NOT NULL,
product_key
integer NOT NULL,
store_key
integer NOT NULL,
amount_sold
numeric(12,2) NOT NULL,
units_sold
integer NOT NULL,
amount_cost
numeric(12,2) NOT NULL
);
CREATE INDEX sales_fact_time ON sales_fact(time_key);
--- Table rsum - ventes sur le temps.
-CREATE TABLE sales_summary_bytime (
time_key
integer NOT NULL,
amount_sold
numeric(15,2) NOT NULL,
units_sold
numeric(12) NOT NULL,
amount_cost
numeric(15,2) NOT NULL
);
CREATE UNIQUE INDEX sales_summary_bytime_key ON sales_summary_bytime(time_key);
--- Fonction et trigger pour amender les colonnes rsumes
-- pour un UPDATE, INSERT, DELETE.
-CREATE OR REPLACE FUNCTION maint_sales_summary_bytime() RETURNS TRIGGER
AS $maint_sales_summary_bytime$
DECLARE
delta_time_key
integer;
delta_amount_sold
numeric(15,2);
delta_units_sold
numeric(12);
delta_amount_cost
numeric(15,2);
BEGIN
-- Travaille sur l'ajout/la suppression de montant(s).
IF (TG_OP = 'DELETE') THEN
delta_time_key = OLD.time_key;
delta_amount_sold = -1 * OLD.amount_sold;
delta_units_sold = -1 * OLD.units_sold;
delta_amount_cost = -1 * OLD.amount_cost;
ELSIF (TG_OP = 'UPDATE') THEN
---IF

interdit les mises jour qui modifient time_key (probablement pas trop cher, car DELETE + INSERT est la faon la plus
probable de raliser les modifications).
( OLD.time_key != NEW.time_key) THEN
RAISE EXCEPTION 'Update of time_key : % -> % not allowed',
OLD.time_key, NEW.time_key;
END IF;
delta_time_key = OLD.time_key;
delta_amount_sold = NEW.amount_sold - OLD.amount_sold;
delta_units_sold = NEW.units_sold - OLD.units_sold;
delta_amount_cost = NEW.amount_cost - OLD.amount_cost;

760

PL/pgSQL - Langage de procdures SQL

ELSIF (TG_OP = 'INSERT') THEN


delta_time_key = NEW.time_key;
delta_amount_sold = NEW.amount_sold;
delta_units_sold = NEW.units_sold;
delta_amount_cost = NEW.amount_cost;
END IF;
-- Insertion ou mise jour de la ligne de rsum avec les nouvelles valeurs.
<<insert_update>>
LOOP
UPDATE sales_summary_bytime
SET amount_sold = amount_sold + delta_amount_sold,
units_sold = units_sold + delta_units_sold,
amount_cost = amount_cost + delta_amount_cost
WHERE time_key = delta_time_key;
EXIT insert_update WHEN found;
BEGIN
INSERT INTO sales_summary_bytime (
time_key,
amount_sold,
units_sold,
amount_cost)
VALUES (
delta_time_key,
delta_amount_sold,
delta_units_sold,
delta_amount_cost
);
EXIT insert_update;
EXCEPTION
WHEN UNIQUE_VIOLATION THEN
-- do nothing
END;
END LOOP insert_update;
RETURN NULL;
END;
$maint_sales_summary_bytime$ LANGUAGE plpgsql;
CREATE TRIGGER maint_sales_summary_bytime
AFTER INSERT OR UPDATE OR DELETE ON sales_fact
FOR EACH ROW EXECUTE PROCEDURE maint_sales_summary_bytime();
INSERT
INSERT
INSERT
INSERT
SELECT
DELETE
SELECT
UPDATE
SELECT

INTO sales_fact VALUES(1,1,1,10,3,15);


INTO sales_fact VALUES(1,2,1,20,5,35);
INTO sales_fact VALUES(2,2,1,40,15,135);
INTO sales_fact VALUES(2,3,1,10,1,13);
* FROM sales_summary_bytime;
FROM sales_fact WHERE product_key = 1;
* FROM sales_summary_bytime;
sales_fact SET units_sold = units_sold * 2;
* FROM sales_summary_bytime;

39.10. Les dessous de PL/pgSQL


Cette section discute des dtails d'implmentation les plus importants connatre pour les utilisateurs de PL/pgSQL.

39.10.1. Substitution de variables


Les instructions et expressions SQL au sein d'une fonction PL/pgSQL peuvent faire appel aux variables et paramtres d'une fonc761

PL/pgSQL - Langage de procdures SQL

tion. En coulisses, PL/pgSQL remplace les paramtres de requtes par des rfrences. Les paramtres ne seront remplacs qu'aux
endroits o un paramtre ou une rfrence de colonne sont autoriss par la syntaxe. Pour un cas extrme, considerez cet exemple
de mauvaise programmation :
INSERT INTO foo (foo) VALUES (foo);
La premire occurrence de foo doit tre un nom de table, d'aprs la syntaxe et ne sera donc pas remplace, mme si la fonction a
une variable nomme foo. La deuxime occurrence doit tre le nom d'une colonne de la table et ne sera donc pas remplace non
plus. Seule la troisime occurrence peuvent tre une rfrence la variable de la fonction.

Note
Les versions de PostgreSQL avant la 9.0 remplaaient la variable dans les trois cas, donnant lieu des erreurs de
syntaxe.
Les noms de variables n'tant pas diffrents des noms de colonnes, d'aprs la syntaxe, il peut y avoir ambuiguit dans les instructions qui font rfrence aux deux : un nom donn fait-il rfrence un nom de colonne ou une variable ? Modifions l'exemple
prcdent.
INSERT INTO dest (col) SELECT foo + bar FROM src;
Ici, dest et src doivent tre des noms de table et col doit tre une colonne de dest mais foo et bar peuvent tre aussi bien
des variables de la fonction que des colonnes de src.
Par dfait, PL/pgSQL signalera une erreur si un nom dans une requte SQL peut faire rfrence la fois une variable et une colonne. Vous pouvez corriger ce problme en renommant la variable ou colonne, en qualifiant la rfrence ambige ou en prcisant
PL/pgSQL quelle est l'interpretation privilgier.
Le choix le plus simple est de renommer la variable ou colonne. Une rgle de codage rcurrente est d'utiliser une convention de
nommage diffrente pour les variables de PL/pgSQL que pour les noms de colonne. Par exemple, si vous utilisez toujours des variables de fonctions en v_quelquechose tout en vous assurant qu'aucun nom de colonne ne commence par v_, aucun conflit
ne sera possible.
Autrement, vous pouvez qualifier les rfrences ambiges pour les rendre plus claires. Dans l'exemple ci-dessus, src.foo serait
une rfrence sans amigit une colonne de table. Pour crer une rfrence sans amigit une variable, dclarez-la dans un
bloc nomm et utilisez le nom du bloc (voir Section 39.2, Structure de PL/pgSQL ). Par exemple,
<<bloc>>
DECLARE
foo int;
BEGIN
foo := ...;
INSERT INTO dest (col) SELECT bloc.foo + bar FROM src;
Ici, bloc.foo dsigne la variable mme s'il existe une colonne foo dans la base src. Les paramtres de fonction, ainsi que les
variables spciales tel que FOUND, peuvent tre qualifis par le nom de la fonction, parce qu'ils sont implicitement dclars dans
un bloc exterieur portant le nom de la fonction.
Quelque fois, il n'est pas envisageable de lever toutes les ambigits dans une grande quantit de code PL/pgSQL. Dans ces cas-ci,
vous pouvez spcifier PL/pgSQL qu'il doit traiter les rfrences ambiges comme tant une variable (ce qui est compatible avec
le comportement de PL/pgSQL avant PostgreSQL 9.0) ou comme tant la colonne d'une table (ce qui est compatible avec
d'autres systmes tels que Oracle).
Pour modifier ce comportement dans toute l'instance, mettez le paramtre de configuration plpgsql.variable_conflict
l'un de error, use_variable ou use_column (o error est la valeur par dfaut). Ce paramtre agit sur les compilations
posterieures d'instructions dans les fonctions PL/pgSQL mais pas les instructions dj compiles dans la session en cours. Pour
fixer ce paramtre avant le chargement de PL/pgSQL, vous devez ajouter plpgsql la liste custom_variable_classes dans
postgresql.conf. Cette modification pouvant affecter de manire inattendue le comportement des fonctions PL/pgSQL, elle
ne peut tre fate que par un administrateur.
Vous pouvez modifier ce comportement fonction par fonction, en insrant l'une de ces commandes spciales au dbut de la fonction :
#variable_conflict error
#variable_conflict use_variable
762

PL/pgSQL - Langage de procdures SQL

#variable_conflict use_column
Ces commandes n'agissent que sur les fonctions qui les contient et surchargent la valeur de plpgsql.variable_conflict.
Un exemple est
CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$
#variable_conflict use_variable
DECLARE
curtime timestamp := now();
BEGIN
UPDATE users SET last_modified = curtime, comment = comment
WHERE users.id = id;
END;
$$ LANGUAGE plpgsql;
Dans la commande UPDATE, curtime, comment, et id font rfrence aux variables et paramtres de la fonction, que la table
users ait ou non des colonnes portant ces noms. Notez qu'il a fallu qualifier la rfrence users.id dans la clause WHERE
pour qu'elle fasse rfrence la colonne. Mais nous ne qualifions pas la rfrence comment comme cible dans la liste UPDATE
car, d'aprs la syntaxe, elle doit tre une colonne de users. Nous pourrions crire la mme fonction sans dpendre de la valeur de
variable_conflict de cette manire :
CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$
<<fn>>
DECLARE
curtime timestamp := now();
BEGIN
UPDATE users SET last_modified = fn.curtime, comment = stamp_user.comment
WHERE users.id = stamp_user.id;
END;
$$ LANGUAGE plpgsql;
La substitution de variable n'arrive pas dans la chane de commande donne EXECUTE ou une de ces variantes. Si vous avez
besoin d'insrer une valeur dans une telle commande, faites-le lors de la construction d'une valeur de chane, illustre dans la Section 39.5.4, Excuter des commandes dynamiques , ou utilisez USING.
La substitution de variable fonctionne seulement dans les commandes SELECT, INSERT, UPDATE et DELETE parce que le
moteur SQL principal autorise les paramtres de la requte seulement dans ces commandes. Pour utiliser un nom variable ou une
valeur dans les autres types d'instructions (gnralement appeles des instructions utilitaires), vous devez construire l'instruction
en question comme une chane et l'excuter via EXECUTE.

39.10.2. Mise en cache du plan


L'interprteur PL/pgSQL analyse le source d'une fonction et produit un arbre binaire interne d'instructions la premire fois que la
fonction est appele ( l'intrieur de chaque session). L'arbre des instructions se traduit compltement par la structure
d'instructions PL/pgSQL mais les expressions et les commandes SQL individuelles utilises dans la fonction ne sont pas traduites
immdiatement.
Au moment o chaque expression et commande SQL est excute en premier lieu dans la fonction, l'interprteur PL/pgSQL cre
un plan d'excution prpare (en utilisant les fonctions SPI_prepare et SPI_saveplan du gestionnaire SPI ). Les appels suivants cette expression ou commande rutilisent le plan prpar. Du coup, une fonction avec du code conditionnel contenant de
nombreuses instructions pour lesquels les plans d'excutions pourraient tre requis vont seulement prparer et sauvegarder ces
plans qui sont utiliss tout au long de la dure de vie de la connexion la base de donnes. Ceci peut rduire substantiellement le
temps total requis pour analyser et gnrer les plans d'excution pour les instructions d'une fonction PL/pgSQL. Un inconvnient
est que les erreurs dans une expression ou commande spcifique ne peuvent pas tre dtectes avant que la fonction a atteint son
excution. (Les erreurs de syntaxe triviales seront dtectes la premire passe d'analyse mais quelque chose de plus complexe ne
sera pas dtect avant son excution.)
Un plan sauvegard sera regnr automatiquement s'il y a des changements dans le schma de n'importe quelle table utilise dans
la requte ou si une fonction utilise dans la requte et dfinie par un utilisateur est redefinie Ceci rend la re-utilisation d'un plan
prpar transparent dans la plupart des cas mais il existe des cas particuliers ou un plan obsolte peut tre re-utilis. Par exemple,
la suppression et la re-cration d'un oprateur defini par un utilisateur n'affectera pas les plans dj en cache; ils continueront
d'appeler la fonction sous-jacente de l'oprateur d'origine, si celle-ci n'a pas t modifie. Lorsque c'est ncessaure, le cache peut
tre vid en commenant une nouvelle session.
Comme PL/pgSQL sauvegarde les plans d'excution de cette faon, les commandes SQL qui apparaissent directement dans une
fonction PL/pgSQL doivent faire rfrence aux mme tables et aux mmes colonnes chaque excution ; c'est--dire que vous ne
763

PL/pgSQL - Langage de procdures SQL

pouvez pas utiliser un paramtre comme le nom d'une table ou d'une colonne dans une commande SQL. Pour contourner cette restriction, vous pouvez construire des commandes dynamiques en utilisant l'instruction EXECUTE de PL/pgSQL -- au prix de la
construction d'un nouveau plan d'excution chaque excution.
Un autre point important est que les plans prpars utilisent des paramtres pour permettre le changement des valeurs des variables PL/pgSQL entre chaque excution, comme indiqu en dtail ci-dessus. Quelque fois, cela signifie qu'un plan est moins efficace que s'il avait t gnr avec une valeur spcifique. Comme exemple, regardez :
SELECT * INTO mon_enregistrement FROM dictionnaire WHERE mot LIKE terme_recherche;
o terme_recherche est une variable PL/pgSQL. Le plan cach pour cette requte n'utilisera jamais un index sur une variable. Le plan cach pour cette requte n'utilisera jamais un index sur un mot car le planificateur ne peut pas savoir si le modle
LIKE comprendra une ancre gauche l'excution. Pour utiliser un index, la requte doit tre planifie avec un modle spcifique
pour LIKE. C'est un autre cas o EXECUTE peut tre utilis pour forcer la gnration d'un nouveau plan chaque excution.
La nature muable des variables de type record prsente un autre problme dans cette connexion. Quand les champs d'une variable
record sont utiliss dans les expressions ou instructions, les types de donnes des champs ne doivent pas modifier d'un appel de la
fonction un autre car chaque expression sera planifie en utilisant le type de donnes qui est prsent quand l'expression est atteinte en premier. EXECUTE peut tre utilis pour contourner ce problme si ncessaire.
Si la mme fonction est utilise comme trigger pour plus d'une table, PL/pgSQL prpare et met en cache les plans indpendament
pour chacune de ses tables -- c'est--dire qu'il y a un cache pour chaque combinaison fonction trigger/table, pas uniquement pour
chaque fonction. Ceci diminue certains des problmes avec les types de donnes variables ; par exemple, une fonction trigger
pourra fonctionner correctement avec une colonne nomme cle mme si cette colonne a diffrents types dans diffrentes tables.
De la mme faon, les fonctions ayant des types polymorphiques pour les arguments ont un cache spar des plans pour chaque
combinaison des types d'argument rl avec lesquels elles ont t appeles, donc les diffrences de type de donnes ne causent pas
d'checs inattendus.
La mise en cache du plan peut parfois avoir des effets surprenants sur l'interprtation des valeurs sensibles l'heure. Par exemple,
il y a une diffrence entre ce que font ces deux fonctions :
CREATE FUNCTION logfunc1(logtxt text) RETURNS void AS $$
BEGIN
INSERT INTO logtable VALUES (logtxt, 'now');
END;
$$ LANGUAGE plpgsql;
et :
CREATE FUNCTION logfunc2(logtxt text) RETURNS void AS $$
DECLARE
curtime timestamp;
BEGIN
curtime := 'now';
INSERT INTO logtable VALUES (logtxt, curtime);
END;
$$ LANGUAGE plpgsql;
Dans le cas de logfunc1, l'analyseur principal de PostgreSQL sait que, au moment de la prparation du plan pour INSERT,
la chane 'now' devra tre interprte comme une valeur de type timestamp car la colonne cible de logtable est de ce type.
Du coup, 'now' sera converti en une constante quand INSERT est planifi, puis utilis dans tous les appels logfunc1 lors de
la dure de vie de la session. Il n'est pas ncessaire de prciser que ce n'est pas le souhait du dveloppeur.
Dans le cas de logfunc2, l'analyseur principal de PostgreSQL ne connat pas le type que deviendra 'now' et, du coup, il renvoie une valeur de type text contenant la chane now. Lors de l'affectation la variable curtime locale, l'interprteur PL/pgSQL
convertie cette chane dans le type timestamp en appelant les fonctions text_out et timestamp_in pour la conversion. Du
coup, l'heure calcule est mise jour chaque excution comme le suppose le dveloppeur.

39.11. Astuces pour dvelopper en PL/pgSQL


Un bon moyen de dvelopper en PL/pgSQL est d'utiliser l'diteur de texte de votre choix pour crer vos fonctions, et d'utiliser psql
dans une autre fentre pour charger et tester ces fonctions. Si vous procdez ainsi, une bonne ide est d'crire la fonction en utilisant CREATE OR REPLACE FUNCTION. De cette faon vous pouvez simplement recharger le fichier pour mettre jour la
dfinition de la fonction. Par exemple :

764

PL/pgSQL - Langage de procdures SQL

CREATE OR REPLACE FUNCTION fonction_test(integer) RETURNS integer AS $$


....
$$ LANGUAGE plpgsql;
Pendant que psql s'excute, vous pouvez charger ou recharger des dfinitions de fonction avec :
\i nom_fichier.sql
puis immdiatement soumettre des commandes SQL pour tester la fonction.
Un autre bon moyen de dvelopper en PL/pgSQL est d'utiliser un outil d'accs la base de donnes muni d'une interface graphique qui facilite le dveloppement dans un langage de procdures. Un exemple d'un tel outil est pgAdmin, bien que d'autres
existent. Ces outils fournissent souvent des fonctionnalits pratiques telles que la dtection des guillemets ouverts et facilitent la
re-cration et le dbogage des fonctions.

39.11.1. Utilisation des guillemets simples (quotes)


Le code d'une fonction PL/pgSQL est spcifi dans la commande CREATE FUNCTION comme une chane de caractres. Si
vous crivez la chane littrale de la faon ordinaire en l'entourant de guillemets simples, alors tout guillemet simple dans le corps
de la fonction doit tre doubl ; de la mme faon, les antislashs doivent tre doubls (en supposant que la syntaxe d'chappement
de chanes est utilise). Doubler les guillemets devient rapidement difficile et, dans la plupart des cas compliqus, le code peut devenir rapidement incomprhensible parce que vous pouvez facilement vous trouver avec une douzaine, voire plus, de guillemets
adjacents. la place, il est recommand d'crire le corps de la fonction en tant qu'une chane littrale avec guillemets dollar
(voir la Section 4.1.2.4, Constantes de chanes avec guillemet dollar ). Dans cette approche, vous ne doublez jamais les
marques de guillemets mais vous devez faire attention choisir un dlimiteur dollar diffrent pour chaque niveau d'imbrication
dont vous avez besoin. Par exemple, vous pouvez crire la commande CREATE FUNCTION en tant que :
CREATE OR REPLACE FUNCTION fonction_test(integer) RETURNS integer AS $PROC$
....
$PROC$ LANGUAGE plpgsql;
l'intrieur de ceci, vous pouvez utiliser des guillemets pour les chanes littrales simples dans les commandes SQL et $$ pour
dlimiter les fragments de commandes SQL que vous assemblez comme des chanes. Si vous avez besoin de mettre entre guillemets du texte qui inclut $$, vous pouvez utiliser $Q$, et ainsi de suite.
Le graphe suivant montre ce que vous devez faire lors de l'criture de guillemets simples sans guillemets dollar. Cela pourrait tre
utile lors de la traduction de code avec guillemets simples en quelque chose de plus comprhensible.
1 guillemet simple
Pour commencer et terminer le corps de la fonction, par exemple :
CREATE FUNCTION foo() RETURNS integer AS '
.....
' LANGUAGE plpgsql;
Partout au sein du corps de la fonction entour de guillemets simples, les guillemets simples doivent aller par paires.
2 guillemets simples
Pour les chanes de caractres l'intrieur du corps de la fonction, par exemple :
une_sortie := ''Blah'';
SELECT * FROM utilisateurs WHERE f_nom=''foobar'';
Dans l'approche du guillemet dollar, vous devriez juste crire :
une_sortie := 'Blah';
SELECT * FROM utilisateurs WHERE f_nom='foobar';
ce qui serait exactement ce que l'analyseur PL/pgSQL verrait dans les deux cas.
4 guillemets simples
Quand vous avez besoin d'un guillemet simple dans une chane constante l'intrieur du corps de la fonction, par exemple :
une_sortie := une_sortie || '' AND nom LIKE ''''foobar'''' AND xyz''
La valeur effectivement concatne une_sortie est : AND nom LIKE 'foobar' AND xyz.
Dans l'approche du guillemet dollar, vous auriez crit :
une_sortie := une_sortie || $$ AND nom LIKE 'foobar' AND xyz$$
Faites attention que chaque dlimiteur en guillemet dollar ne soient pas simplement $$.
765

PL/pgSQL - Langage de procdures SQL

6 guillemets simples
Quand un simple guillemet dans une chane l'intrieur du corps d'une fonction est adjacent la fin de cette chane constante,
par exemple :
une_sortie := une_sortie || '' AND nom LIKE ''''foobar''''''
La valeur effectivement concatne une_sortie est alors : AND nom LIKE 'foobar'.
Dans l'approche guillemet dollar, ceci devient :
une_sortie := une_sortie || $$ AND nom LIKE 'foobar'$$
10 guillemets simples
Lorsque vous voulez deux guillemets simples dans une chane constante (qui compte pour huit guillemets simples) et qu'elle
est adjacente la fin de cette chane constante (deux de plus). Vous n'aurez probablement besoin de ceci que si vous crivez
une fonction qui gnre d'autres fonctions comme dans l'Exemple 39.8, Portage d'une fonction qui cre une autre fonction
de PL/SQL vers PL/pgSQL . Par exemple :
une_sortie := une_sortie || '' if v_'' ||
referrer_keys.kind || '' like ''''''''''
|| referrer_keys.key_string || ''''''''''
then return '''''' || referrer_keys.referrer_type
|| ''''''; end if;'';
La valeur de une_sortie sera alors :
if v_... like ''...'' then return ''...''; end if;
Dans l'approche du guillemet dollar, ceci devient :
une_sortie := une_sortie || $$ if v_$$ || referrer_keys.kind || $$ like '$$
|| referrer_keys.key_string || $$'
then return '$$ || referrer_keys.referrer_type
|| $$'; end if;$$;
o nous supposons que nous avons seulement besoin de placer des marques de guillemets simples dans une_sortie parce
que les guillemets seront recalculs avant utilisation.

39.12. Portage d'Oracle PL/SQL


Cette section explicite les diffrences entre le PL/pgSQL de PostgreSQL et le langage PL/SQL d'Oracle, afin d'aider les dveloppeurs qui portent des applications d'Oracle vers PostgreSQL.
PL/pgSQL est similaire PL/SQL sur de nombreux aspects. C'est un langage itratif structur en blocs et toutes les variables
doivent tre dclares. Les affectations, boucles, conditionnelles sont similaires. Les principales diffrences que vous devez garder
l'esprit quand vous portez de PL/SQL vers PL/pgSQL sont:

Si un nom utilis dans une commande SQL peut tre soit un nom de colonne d'une table soit une rfrence une variable de la
fonction, PL/SQL le traite comme un nom de commande. Cela correspond au comportement de PL/pgSQL lorsque plpgsql.variable_conflict = use_column, ce qui n'est pas la valeur par dfaut, comme expliqu dans Section 39.10.1,
Substitution de variables . Il est prfreable d'viter de tels ambigits des le dbut mais si vous devez migrer une grande
quantit de code qui dpend de ce comportement, paramtrer variable_conflict peut s'avrer tre la meilleure solution.

Dans PostgreSQL, le corps de la fonction doit tre crit comme une chane litrale. Du coup, vous avez besoin d'utiliser les
guillemets dollar ou l'chappement des simples guillemets dans le corps de la fonction. Voir la Section 39.11.1, Utilisation
des guillemets simples (quotes) .

la place des paquetages, utilisez des schmas pour organiser vos fonctions en groupes.

Comme il n'y a pas de paquetages, il n'y a pas non plus de variables au niveau paquetage. Ceci est un peu ennuyant. Vous
pourriez tre capable de conserver un tat par session dans les tables temporaires la place.

Les boucles FOR d'entiers en ordre inverse (REVERSE) fonctionnent diffremment ; PL/SQL compte du second numro jusqu'au premier alors que PL/pgSQL compte du premier jusqu'au second, ceci rclamant que les limites de la boucle soient
changes lors du portage. Cette incompatibilit est malheureuse mais a peu de chance d'tre change. (Voir Section 39.6.3.5,
FOR (variante avec entier) .)

Les boucles FOR sur des requtes (autres que des curseurs) fonctionnent aussi diffremment : la variable cible doit avoir t
dclare alors que PL/SQL les dclare toujours implicitement. Un avantage de ceci est que les valeurs des variables sont tou766

PL/pgSQL - Langage de procdures SQL

jours accessibles la sortie de la boucle.

Il existe plusieurs diffrences de notation pour l'utilisation des variables curseurs.

39.12.1. Exemples de portages


L'Exemple 39.7, Portage d'une fonction simple de PL/SQL vers PL/pgSQL montre comment porter une simple fonction de PL/
SQL vers PL/pgSQL.
Exemple 39.7. Portage d'une fonction simple de PL/SQL vers PL/pgSQL

Voici une fonction en PL/SQL Oracle :


CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar, v_version varchar)
RETURN varchar IS
BEGIN
IF v_version IS NULL THEN
RETURN v_name;
END IF;
RETURN v_name || '/' || v_version;
END;
/
show errors;
Parcourons cette fonction et voyons les diffrences avec PL/pgSQL :

Le mot cl RETURN dans le prototype de la fonction (pas dans le corps de la fonction) devient RETURNS dans PostgreSQL.
De plus, IS devient AS et vous avez besoin d'ajouter une clause LANGUAGE parce que PL/pgSQL n'est pas le seul langage de
procdures disponible.

Dans PostgreSQL, le corps de la fonction est considr comme une chane littrale, donc vous avez besoin d'utiliser les
guillemets simples ou les guillemets dollar tout autour. Ceci se substitue au / de fin dans l'approche d'Oracle.

La commande show errors n'existe pas dans PostgreSQL et n'est pas ncessaire car les erreurs sont rapportes automatiquement.

Voici de quoi aurait l'air cette fonction porte sous PostgreSQL :


CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar, v_version varchar)
RETURNS varchar AS $$
BEGIN
IF v_version IS NULL THEN
return v_name;
END IF;
RETURN v_name || '/' || v_version;
END;
$$ LANGUAGE plpgsql;
L'Exemple 39.8, Portage d'une fonction qui cre une autre fonction de PL/SQL vers PL/pgSQL montre comment porter une
fonction qui cre une autre fonction et comment grer les problmes de guillemets rsultants.
Exemple 39.8. Portage d'une fonction qui cre une autre fonction de PL/SQL vers PL/pgSQL

La procdure suivante rcupre des lignes d'une instruction SELECT et construit une grande fonction dont les rsultats sont dans
une instruction IF pour favoriser l'efficacit.
Voici la version Oracle :
CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc IS
referrer_keys CURSOR IS
SELECT * FROM cs_referrer_keys
ORDER BY try_order;
func_cmd VARCHAR(4000);
BEGIN
func_cmd := 'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host IN VARCHAR,
767

PL/pgSQL - Langage de procdures SQL

v_domain IN VARCHAR, v_url IN VARCHAR) RETURN VARCHAR IS BEGIN';


FOR referrer_key IN referrer_keys LOOP
func_cmd := func_cmd ||
' IF v_' || referrer_key.kind
|| ' LIKE ''' || referrer_key.key_string
|| ''' THEN RETURN ''' || referrer_key.referrer_type
|| '''; END IF;';
END LOOP;
func_cmd := func_cmd || ' RETURN NULL; END;';
EXECUTE IMMEDIATE func_cmd;
END;
/
show errors;
Voici comment la fonction serait dans PostgreSQL :
CREATE OR REPLACE FUNCTION cs_update_referrer_type_proc() RETURNS void AS $func$
DECLARE
CURSOR referrer_keys IS
SELECT * FROM cs_referrer_keys
ORDER BY try_order;
func_body text;
func_cmd text;
BEGIN
func_body := 'BEGIN' ;
FOR referrer_key IN SELECT * FROM cs_referrer_keys ORDER BY try_order LOOP
func_body := func_body ||
' IF v_' || referrer_key.kind
|| ' LIKE ' || quote_literal(referrer_key.key_string)
|| ' THEN RETURN ' || quote_literal(referrer_key.referrer_type)
|| '; END IF;' ;
END LOOP;
func_body := func_body || ' RETURN NULL; END;';
func_cmd :=
'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host varchar,
v_domain varchar,
v_url varchar)
RETURNS varchar AS '
|| quote_literal(func_body)
|| ' LANGUAGE plpgsql;' ;
EXECUTE func_cmd;
END;
$func$ LANGUAGE plpgsql;
Notez comment le corps de la fonction est construit sparment et est pass au travers de quote_literal pour doubler tout
symbole guillemet qu'il peut contenir. Cette technique est ncessaire parce que nous ne pouvons pas utiliser coup sr les guillemets dollar pour dfinir la nouvelle fonction : nous ne sommes pas sr de savoir quelle chane sera interpole partir du champ
referrer_key.key_string (nous supposons ici que ce referrer_key.kind vaut coup sr host, domain ou url
mais referrer_key.key_string pourrait valoir autre chose, il pourrait contenir en particulier des signes dollar). Cette
fonction est en fait une amlioration de l'original Oracle parce qu'il ne gnrera pas de code cass quand referrer_key.key_string ou referrer_key.referrer_type contient des guillemets.
L'Exemple 39.9, Portage d'une procdure avec manipulation de chanes et paramtres OUT de PL/SQL vers PL/pgSQL montre
comment porter une fonction ayant des paramtres OUT et effectuant des manipulations de chanes. PostgreSQL n'a pas de fonction instr intgre mais vous pouvez en crer une en utilisant une combinaison d'autres fonctions. Dans la Section 39.12.3,
Annexe , il y a une implmentation PL/pgSQL d'instr que vous pouvez utiliser pour faciliter votre portage.
Exemple 39.9. Portage d'une procdure avec manipulation de chanes et paramtres OUT de PL/SQL vers PL/pgSQL

La procdure Oracle suivante est utilise pour analyser une URL et renvoyer plusieurs lments (hte, chemin et requte). Les
768

PL/pgSQL - Langage de procdures SQL

fonctions PL/pgSQL ne peuvent renvoyer qu'une seule valeur.


Voici la version Oracle :
CREATE OR REPLACE PROCEDURE cs_parse_url(
v_url IN VARCHAR,
v_host OUT VARCHAR, -- Celle-ci sera passe en retour
v_path OUT VARCHAR, -- Celle-l aussi
v_query OUT VARCHAR) -- Et celle-l
IS
a_pos1 INTEGER;
a_pos2 INTEGER;
BEGIN
v_host := NULL;
v_path := NULL;
v_query := NULL;
a_pos1 := instr(v_url, '//');
IF a_pos1 = 0 THEN
RETURN;
END IF;
a_pos2 := instr(v_url, '/', a_pos1 + 2);
IF a_pos2 = 0 THEN
v_host := substr(v_url, a_pos1 + 2);
v_path := '/';
RETURN;
END IF;
v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
a_pos1 := instr(v_url, '?', a_pos2 + 1);
IF a_pos1 = 0 THEN
v_path := substr(v_url, a_pos2);
RETURN;
END IF;
v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
v_query := substr(v_url, a_pos1 + 1);
END;
/
show errors;
Voici une traduction possible en PL/pgSQL :
CREATE OR REPLACE FUNCTION cs_parse_url(
v_url IN VARCHAR,
v_host OUT VARCHAR, -- This will be passed back
v_path OUT VARCHAR, -- This one too
v_query OUT VARCHAR) -- And this one
AS $$
DECLARE
a_pos1 INTEGER;
a_pos2 INTEGER;
BEGIN
v_host := NULL;
v_path := NULL;
v_query := NULL;
a_pos1 := instr(v_url, '//');
IF a_pos1 = 0 THEN
RETURN;
END IF;
a_pos2 := instr(v_url, '/', a_pos1 + 2);
IF a_pos2 = 0 THEN
v_host := substr(v_url, a_pos1 + 2);
v_path := '/';
RETURN;
END IF;
v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
a_pos1 := instr(v_url, '?', a_pos2 + 1);
769

PL/pgSQL - Langage de procdures SQL

IF a_pos1 = 0 THEN
v_path := substr(v_url, a_pos2);
RETURN;
END IF;
v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
v_query := substr(v_url, a_pos1 + 1);
END;
$$ LANGUAGE plpgsql;
Cette fonction pourrait tre utilise ainsi :
SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz');
L'Exemple 39.10, Portage d'une procdure de PL/SQL vers PL/pgSQL montre comment porter une procdure qui utilise de
nombreuses fonctionnalits spcifiques Oracle.
Exemple 39.10. Portage d'une procdure de PL/SQL vers PL/pgSQL

La version Oracle :
CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id IN INTEGER) IS
a_running_job_count INTEGER;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
LOCK TABLE cs_jobs IN EXCLUSIVE MODE;
SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;
IF a_running_job_count > 0 THEN
COMMIT; -- free lock
raise_application_error(-20000, 'Unable to create a new job: a job is currently
running.');
END IF;
DELETE FROM cs_active_job;
INSERT INTO cs_active_job(job_id) VALUES (v_job_id);
BEGIN
INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, sysdate);
EXCEPTION
WHEN dup_val_on_index THEN NULL; -- ne vous inquietez pas si cela existe dj
END;
COMMIT;
END;
/
show errors
Les procdures comme celles-ci peuvent tre aisment converties en fonctions PostgreSQL renvoyant un void. Cette procdure
en particulier est intressante parce qu'elle peut nous apprendre diverses choses :
Il n'y a pas d'instruction PRAGMA dans PostgreSQL.
Si vous faites un LOCK TABLE dans PL/pgSQL, le verrou ne sera pas libr jusqu' ce que la transaction appelante soit
termine.
Vous ne pouvez pas lancer un COMMIT dans une fonction PL/pgSQL. La fonction est lance l'intrieur d'une transaction
externe et, du coup, un COMMIT impliquerait simplement la fin de l'excution de la fonction. Nanmoins, dans ce cas particulier, ce n'est de toute faon pas ncessaire parce que le verrou obtenu par LOCK TABLE sera libr lors de la leve de
l'erreur.
Voici comment nous pourrions porter cette procdure vers PL/pgSQL :
CREATE OR REPLACE FUNCTION cs_create_job(v_job_id integer) RETURNS void AS $$
DECLARE
a_running_job_count integer;
BEGIN
LOCK TABLE cs_jobs IN EXCLUSIVE MODE;
770

PL/pgSQL - Langage de procdures SQL

SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;


IF a_running_job_count > 0 THEN
RAISE EXCEPTION 'Unable to create a new job: a job is currently running';
END IF;
DELETE FROM cs_active_job;
INSERT INTO cs_active_job(job_id) VALUES (v_job_id);
BEGIN
INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now());
EXCEPTION
WHEN unique_violation THEN
-- ne vous inquietez pas si cela existe dj
END;
END;
$$ LANGUAGE plpgsql;
La syntaxe de RAISE est considrablement diffrente de l'instruction Oracle similaire, bien que le cas basique du RAISE
nom_exception fonctionne de faon similaire.
Les noms d'exceptions supportes par PL/pgSQL sont diffrents de ceux d'Oracle. L'ensemble de noms d'exceptions intgr
est plus important (voir l'Annexe A, Codes d'erreurs de PostgreSQL). Il n'existe actuellement pas de faon de dclarer des
noms d'exceptions dfinis par l'utilisateur, bien que vous puissiez aussi ignorer les valeurs SQLSTATE choisies par
l'utilisateur.
La principale diffrence fonctionnelle entre cette procdure et l'quivalent Oracle est que le verrou exclusif sur la table cs_jobs
sera dtenu jusqu' la fin de la transaction appelante. De plus, si l'appelant annule plus tard (par exemple cause d'une erreur), les
effets de cette procdure seront annuls.

39.12.2. Autres choses surveiller


Cette section explique quelques autres choses surveiller quand on effectue un portage de fonctions PL/SQL Oracle vers PostgreSQL.

39.12.2.1. Annulation implicite aprs une exception


Dans PL/pgSQL, quand une exception est rcupre par une clause EXCEPTION, toutes les modifications de la base de donnes
depuis le bloc BEGIN sont automatiquement annules. C'est--dire que le comportement est identique celui obtenu partir
d'Oracle avec :
BEGIN
SAVEPOINT s1;
... code ici ...
EXCEPTION
WHEN ... THEN
ROLLBACK TO s1;
... code ici ...
WHEN ... THEN
ROLLBACK TO s1;
... code ici ...
END;
Si vous traduisez une procdure d'Oracle qui utilise SAVEPOINT et ROLLBACK TO dans ce style, votre tche est facile :
omettez SAVEPOINT et ROLLBACK TO. Si vous avez une procdure qui utilise SAVEPOINT et ROLLBACK TO d'une
faon diffrente, alors un peu de rflexion supplmentaire sera ncessaire.

39.12.2.2. EXECUTE
La version PL/pgSQL d'EXECUTE fonctionne de faon similaire la version PL/SQL mais vous devez vous rappeler d'utiliser
quote_literal et quote_ident comme dcrit dans la Section 39.5.4, Excuter des commandes dynamiques . Les
constructions de type EXECUTE 'SELECT * FROM $1'; ne fonctionneront pas de faon fiable moins d'utiliser ces fonctions.

39.12.2.3. Optimisation des fonctions PL/pgSQL


PostgreSQL vous donne deux modificateurs de cration de fonctions pour optimiser l'excution : la volatilit (la fonction
771

PL/pgSQL - Langage de procdures SQL

renvoie toujours le mme rsultat quand on lui donne les mmes arguments) et la rigueur (une fonction renvoie NULL si tous
ses arguments sont NULL). Consultez la page de rfrence de CREATE FUNCTION(7) pour les dtails.
Pour faire usage de ces attributs d'optimisation, votre instruction CREATE FUNCTION devrait ressembler ceci :
CREATE FUNCTION foo(...) RETURNS integer AS $$
...
$$ LANGUAGE plpgsql STRICT IMMUTABLE;

39.12.3. Annexe
Cette section contient le code d'un ensemble de fonctions instr compatible Oracle que vous pouvez utiliser pour simplifier vos
efforts de portage.
---------

fonctions instr qui reproduisent la contrepartie Oracle


Syntaxe: instr(string1, string2, [n], [m]) o [] signifie paramtre optionnel.
Cherche string1 en commenant par le n-ime caractre pour la m-ime occurrence
de string2. Si n est ngatif, cherche en sens inverse. Si m n'est pas fourni
suppose 1 (la recherche commence au premier caractre).

CREATE FUNCTION instr(varchar, varchar) RETURNS integer AS $$


DECLARE
pos integer;
BEGIN
pos:= instr($1, $2, 1);
RETURN pos;
END;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
CREATE FUNCTION instr(string varchar, string_to_search varchar, beg_index integer)
RETURNS integer AS $$
DECLARE
pos integer NOT NULL DEFAULT 0;
temp_str varchar;
beg integer;
length integer;
ss_length integer;
BEGIN
IF beg_index > 0 THEN
temp_str := substring(string FROM beg_index);
pos := position(string_to_search IN temp_str);
IF pos = 0 THEN
RETURN 0;
ELSE
RETURN pos + beg_index - 1;
END IF;
ELSE
ss_length := char_length(string_to_search);
length := char_length(string);
beg := length + beg_index - ss_length + 2;
WHILE beg > 0 LOOP
temp_str := substring(string FROM beg FOR ss_length);
pos := position(string_to_search IN temp_str);
IF pos > 0 THEN
RETURN beg;
END IF;
beg := beg - 1;
END LOOP;
RETURN 0;
END IF;
END;
772

PL/pgSQL - Langage de procdures SQL

$$ LANGUAGE plpgsql STRICT IMMUTABLE;


CREATE FUNCTION instr(string varchar, string_to_search varchar,
beg_index integer, occur_index integer)
RETURNS integer AS $$
DECLARE
pos integer NOT NULL DEFAULT 0;
occur_nombre integer NOT NULL DEFAULT 0;
temp_str varchar;
beg integer;
i integer;
length integer;
ss_length integer;
BEGIN
IF beg_index > 0 THEN
beg := beg_index;
temp_str := substring(string FROM beg_index);
FOR i IN 1..occur_index LOOP
pos := position(string_to_search IN temp_str);
IF i = 1 THEN
beg := beg + pos - 1;
ELSE
beg := beg + pos;
END IF;
temp_str := substring(string FROM beg + 1);
END LOOP;
IF pos = 0 THEN
RETURN 0;
ELSE
RETURN beg;
END IF;
ELSE
ss_length := char_length(string_to_search);
length := char_length(string);
beg := length + beg_index - ss_length + 2;
WHILE beg > 0 LOOP
temp_str := substring(string FROM beg FOR ss_length);
pos := position(string_to_search IN temp_str);
IF pos > 0 THEN
occur_nombre := occur_nombre + 1;
IF occur_nombre = occur_index THEN
RETURN beg;
END IF;
END IF;
beg := beg - 1;
END LOOP;
RETURN 0;
END IF;
END;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;

773

Chapitre 40. PL/Tcl - Langage de procdures Tcl


PL/Tcl est un langage de procdures chargeable pour le systme de bases de donnes PostgreSQL, activant l'utilisation du
langage Tcl pour l'criture de fonctions de procdures dclencheurs.

40.1. Aperu
PL/Tcl offre un grand nombre de fonctionnalits qu'un codeur de fonctions dispose avec le langage C, avec quelques restrictions
et coupl de puissantes bibliothques de traitement de chanes de caractres disponibles pour Tcl.
Une bonne restriction est que tout est excut dans le contexte de l'interprteur Tcl. En plus de l'ensemble sr de commandes limites de Tcl, seules quelques commandes sont disponibles pour accder la base via SPI et pour envoyer des messages via
elog(). PL/Tcl ne fournit aucun moyen pour accder aux internes du serveur de bases ou pour gagner un accs au niveau systme d'exploitation avec les droits du processus serveur PostgreSQL comme le fait une fonction C. Du coup, les utilisateurs
de la base, sans droits, peuvent utiliser ce langage en toute confiance ; il ne leur donne pas une autorit illimite.
L'autre restriction d'implmentation est que les fonctions Tcl ne peuvent pas tre utilises pour crer des fonctions
d'entres/sorties pour les nouveaux types de donnes.
Quelques fois, il est prfrable d'crire des fonctions Tcl non restreintes par le Tcl sr. Par exemple, vous pourriez vouloir une
fonction Tcl pour envoyer un courrier lectronique. Pour grer ces cas, il existe une variante de PL/Tcl appele PL/TclU (Tcl
non accrdit). C'est exactement le mme langage sauf qu'un interprteur Tcl complet est utilis. Si PL/TclU est utilis, il doit
tre install comme langage de procdures non accrdit de faon ce que seuls les superutilisateurs de la base de donnes
puissent crer des fonctions avec lui. Le codeur d'une fonction PL/TclU doit faire attention au fait que la fonction ne pourra pas
tre utilis pour faire autre chose que son but initial, car il sera possible de faire tout ce qu'un administrateur de la base de donnes peut faire.
Le code de l'objet partag pour les gestionnaires d'appel PL/Tcl et PL/TclU est automatiquement construit et install dans le rpertoire des bibliothques de PostgreSQL si le support de Tcl est spcifi dans l'tape de configuration de la procdure
d'installation. Pour installer PL/Tcl et/ou PL/TclU dans une base de donnes particulire, utilisez la commande CREATE EXTENSION ou le programme createlang, par exemple createlang pltcl nom_base ou createlang pltclu
nom_base.

40.2. Fonctions et arguments PL/Tcl


Pour crer une fonction dans le langage PL/Tcl, utilisez la syntaxe standard de CREATE FUNCTION(7) :
CREATE FUNCTION nom_fonction (types_arguments) RETURNS
type_en_retour AS $$
# corps de la fonction PL/Tcl
$$ LANGUAGE pltcl;
PL/TclU est identique sauf que le langage doit tre pltclu.
Le corps de la fonction est simplement un bout de script Tcl. Quand la fonction est appele, les valeurs des arguments sont passes en tant que variables $1 ... $n au script Tcl. Le rsultat est renvoy partir du code Tcl de la faon habituelle avec une instruction return.
Par exemple, une fonction renvoyant le plus grand de deux valeurs entires pourrait tre dfinie ainsi :
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
if {$1 > $2} {return $1}
return $2
$$ LANGUAGE pltcl STRICT;
Notez la clause STRICT qui nous permet d'viter de penser aux valeurs NULL en entres : si une valeur NULL est passe, la
fonction ne sera pas appele du tout mais renverra automatiquement un rsultat nul.
Dans une fonction non stricte, si la valeur relle d'un argument est NULL, la variable $n correspondante sera initialise avec
une chane vide. Pour dtecter si un argument particulier est NULL, utilisez la fonction argisnull. Par exemple, supposez
que nous voulons tcl_max avec un argument NULL et un non NULL pour renvoyer l'argument non NULL plutt que NULL :
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
if {[argisnull 1]} {
if {[argisnull 2]} { return_null }
return $2
}
if {[argisnull 2]} { return $1 }
774

PL/Tcl - Langage de procdures Tcl

if {$1 > $2} {return $1}


return $2
$$ LANGUAGE pltcl;
Comme indiqu ci-dessus, pour renvoyer une valeur NULL partir d'une fonction PL/Tcl, excutez return_null. Ceci peut
tre fait que la fonction soit stricte ou non.
Les arguments de type compos sont passs la fonction comme des tableaux Tcl. Les noms des lments du tableau sont les
noms d'attribut du type composite. Si un attribut dans la ligne passe a la valeur NULL, il n'apparatra pas dans le tableau. Voici
un exemple :
CREATE TABLE employe (
nom text,
salaire integer,
age integer
);
CREATE FUNCTION surpaye(employe) RETURNS boolean AS $$
if {200000.0 < $1(salaire)} {
return "t"
}
if {$1(age) < 30 && 100000.0 < $1(salaire)} {
return "t"
}
return "f"
$$ LANGUAGE pltcl;
Il n'y a actuellement aucun support pour le retour d'une valeur rsultat de type compos et pour le retour d'ensembles.
PL/Tcl n'a pas actuellement du support complet pour les types de domaine : il traite un domaine de la mme faon que le type scalaire sous-jacent. Cela signifie que les contraintes associes avec le domaine ne seront pas forces. Ce n'est pas un problme pour
les arguments de la fonction mais c'est hasardeux de dclarer une fonction PL/Tcl renvoyant un type domaine.

40.3. Valeurs des donnes avec PL/Tcl


Les valeurs des arguments fournies au code d'une fonction PL/Tcl sont simplement les arguments en entre convertis au format
texte (comme s'ils avaient t affichs par une instruction SELECT). De mme, la commande return acceptera toute chane acceptable dans le format d'entre du type de retour dclar pour la fonction. Donc, l'intrieur de la fonction PL/Tcl, toutes les valeurs de donnes sont simplement des chanes de texte.

40.4. Donnes globales avec PL/Tcl


Quelque fois, il est utile d'avoir des donnes globales qui sont conserves entre deux appels une fonction ou qui sont partages
entre plusieurs fonctions. Ceci peut tre facilement obtenu car toutes les fonctions PL/Tcl excutes dans une session partagent le
mme interprteur Tcl sr. Donc, toute variable globale Tcl est accessible aux appels de fonctions PL/Tcl et persisteront pour la
dure de la session SQL (notez que les fonctions PL/TclU partagent de la mme faon les donnes globales mais elles sont dans
un interprteur Tcl diffrent et ne peuvent pas communiquer avec les fonctions PL/Tcl). C'est facile faire en PL/Tcl mais il
existe quelques restrictions qui doivent tre comprises.
Pour des raisons de scurit, PL/Tcl excute les fonctions appeles par tout rle SQL dans un interprteur Tcl spar pour ce rle.
Ceci empche une interfrence accidentelle ou malicieuse d'un utilisateur avec le comportement des fonctions PL/Tcl d'un autre
utilisateur. Chaque interprteur aura ses propres valeurs pour toutes les variables globales Tcl. Du coup, deux fonctions PL/Tcl
partageront les mmes variables globales si et seulement si elles sont excutes par le mme rle SQL. Dans une application o
une seule session excute du code sous plusieurs rles SQL(via des fonctions SECURITY DEFINER, l'utilisation de SET
ROLE, etc), vous pouvez avoir besoin de mettre des tapes explicites pour vous assurer que les fonctions PL/Tcl peuvent partager
des donnes. Pour cela, assurez-vous que les fonctions qui doivent communiques ont pour propritaire le mme utilisateur et marquez-les avec l'option SECURITY DEFINER. Bien sr, vous devez faire attention ce que de telles fonctions ne puissent pas tre
utilises pour faire des choses non souhaites.
Toutes les fonctions PL/TclU utilises dans une session s'excutent avec le mme interprteur Tcl, qui est bien sr diffrent des interprteurs utilises pour les fonctions PL/Tcl. Donc les donnes globales sont automatiquement partages entre des fonctions PL/
TclU. Ceci n'est pas considr comme un risque de scurit parce que toutes les fonctions PL/TclU sexcutent dans le mme niveau de confiance, celui d'un super-utilisateur.
Pour aider la protection des fonctions PL/Tcl sur les interfrences non intentionnelles, un tableau global est rendu disponible
pour chaque fonction via la commande upvar. Le nom global de cette variable est le nom interne de la fonction alors que le nom
775

PL/Tcl - Langage de procdures Tcl

local est GD. Il est recommand d'utiliser GD pour les donnes prives persistantes d'une fonction. Utilisez les variables globales
Tcl uniquement pour les valeurs que vous avez l'intention de partager avec les autres fonctions. (Notez que les tableaux GD sont
seulement globaux l'intrieur d'un interprteur particulier, pour qu'ils ne franchissent pas les restrictions de scurit mentionnes
ci-dessus.)
Un exemple de l'utilisation de GD apparat dans l'exemple spi_execp ci-dessous.

40.5. Accs la base de donnes depuis PL/Tcl


Les commandes suivantes sont disponibles pour accder la base de donnes depuis le corps d'une fonction PL/Tcl :
spi_exec [-count n] [-array name] command [loop-body]
Excute une commande SQL donne en tant que chane. Une erreur dans la commande lve une erreur. Sinon, la valeur de retour de spi_exec est le nombre de lignes intresses dans le processus (slection, insertion, mise jour ou suppression) par
la commande ou zro si la commande est une instruction utilitaire. De plus, si la commande est une instruction SELECT, les
valeurs des donnes slectionnes sont places dans des variables Tcl dcrites ci-dessous.
La valeur optionnelle -count indique spi_exec le nombre maximum de lignes travailler dans la commande. L'effet de
ceci est comparable l'initialisation d'une requte en tant que curseur et de dire FETCH n.
Si la commande est une instruction SELECT, les valeurs des colonnes de rsultat sont places dans les variables Tcl nommes d'aprs les colonnes. Si l'option -array est donne, les valeurs de colonnes sont stockes la place dans un tableau associatif nomm, avec les noms des colonnes utiliss comme index du tableau.
Si la commande est une instruction SELECT et qu'aucun script loop-body n'est donn, alors seule la premire ligne de rsultats est stocke dans des variables Tcl ; les lignes suivantes sont ignores. Aucun stockage n'intervient si la requte ne renvoie pas de ligne (ce cas est dtectable avec le rsultat de la fonction spi_exec). Par exemple :
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
initialisera la variable Tcl $cnt avec le nombre de lignes dans le catalogue systme pg_proc.
Si l'argument loop-body optionnel est donn, il existe un morceau de script Tcl qui est excut une fois pour chaque ligne
du rsultat de la requte (loop-body est ignor si la commande donne n'est pas un SELECT). Les valeurs des colonnes de
la ligne actuelle sont stockes dans des variables Tcl avant chaque itration. Par exemple :
spi_exec -array C "SELECT * FROM pg_class" {
elog DEBUG "have table $C(relname)"
}
affichera un message de trace pour chaque ligne de pg_class. Cette fonctionnalit travaille de faon similaire aux autres
constructions de boucles de Tcl ; en particulier, continue et break fonctionnent de la mme faon l'intrieur de loopbody.
Si une colonne d'un rsultat de la requte est NULL, la variable cible est ds-initialise plutt qu'initialise.
spi_prepare query typelist
Prpare et sauvegarde un plan de requte pour une excution future. Le plan sauvegard sera conserv pour la dure de la session actuelle.
La requte peut utiliser des paramtres, c'est--dire des emplacements pour des valeurs fournir lorsque le plan sera rellement excut. Dans la chane de requte, faites rfrence aux paramtres avec les symboles $1 ... $n. Si la requte utilise les
paramtres, les noms des types de paramtre doivent tre donns dans une liste Tcl (crivez une liste vide pour typelist si
aucun paramtre n'est utilis).
La valeur de retour de spi_prepare est l'identifiant de la requte utiliser dans les appels suivants spi_execp. Voir
spi_execp pour un exemple.
spi_execp [-count n] [-array name] [-nulls string] queryid [value-list] [loop-body]
Excute une requte prpare prcdemment avec spi_prepare. queryid est l'identifiant renvoy par spi_prepare.
Si la requte fait rfrence des paramtres, une liste de valeurs (value-list) doit tre fournie. C'est une liste Tcl des valeurs relles des paramtres. La liste doit tre de la mme longueur que la liste de types de paramtres donne prcdemment
lors de l'appel spi_prepare. Oubliez-la si la requte n'a pas de paramtres.
La valeur optionnelle pour -nulls est une chane d'espaces et de caractres 'n' indiquant spi_execp les paramtres
nuls. Si indiqu, elle doit avoir exactement la mme longueur que value-list. Si elle est omise, toutes les valeurs de paramtres sont non NULL.
Sauf si la requte et ses paramtres sont spcifis, spi_execp fonctionne de la mme faon que spi_exec. Les options count, -array et loop-body sont identiques. Du coup, la valeur du rsultat l'est aussi.
776

PL/Tcl - Langage de procdures Tcl

Voici un exemple d'une fonction PL/Tcl utilisant un plan prpar :


CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$
if {![ info exists GD(plan) ]} {
# prpare le plan sauvegard au premier appel
set GD(plan) [ spi_prepare \
"SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \
[ list int4 int4 ] ]
}
spi_execp -count 1 $GD(plan) [ list $1 $2 ]
return $cnt
$$ LANGUAGE pltcl;
Nous avons besoin des antislashs l'intrieur de la chane de la requte passe spi_prepare pour s'assurer que les marqueurs $n sont passs au travers de spi_prepare sans transformation et ne sont pas remplacs avec la substitution de variables de Tcl.
spi_lastoid
Renvoie l'OID de la ligne insre par le dernier appel spi_exec ou spi_execp, si la commande tait un INSERT d'une
seule ligne et que la table modifie contenait des OID (sinon, vous obtenez zro).
quote string
Double toutes les occurrences de guillemet simple et d'antislash dans la chane donne. Ceci peut tre utilis pour mettre entre
guillemets des chanes de faon sr et pour qu'elles puissent tre insres dans des commandes SQL passes spi_exec ou
spi_prepare. Par exemple, pensez une chane de commande SQL comme :
"SELECT '$val' AS ret"
o la variable Tcl val contient actuellement le mot doesn't. Ceci finirait avec la chane de commande :
SELECT 'doesn't' AS ret
qui va causer une erreur d'analyse lors de spi_exec ou de spi_prepare. Pour fonctionner correctement, la commande
soumise devrait contenir :
SELECT 'doesn''t' AS ret
qui peut-tre cr avec PL/Tcl en utilisant :
"SELECT '[ quote $val ]' AS ret"
Un avantage de spi_execp est que vous n'avez pas mettre entre guillemets des valeurs de paramtres comme ceux-ci car
les paramtres ne sont jamais analyss comme faisant partie de la chane de la commande SQL.
elog level msg
met une trace ou un message d'erreur. Les niveaux possibles sont DEBUG, LOG, INFO, NOTICE, WARNING, ERROR et FATAL. ERROR lve une condition d'erreur ; si elle n'est pas rcupre par le code Tcl, l'erreur est propage la requte appelante, causant l'annulation de la transaction ou sous-transaction en cours. Ceci est en fait identique la commande error.
FATAL annule la transaction et fait que la session courante s'arrte (il n'existe probablement aucune raison d'utiliser ce niveau
d'erreur dans les fonctions PL/Tcl mais il est fourni pour que tous les messages soient tout de mme disponibles). Les autres
niveaux gnrent seulement des messages de niveaux de priorit diffrent. Le fait que les messages d'un niveau de priorit
particulier sont reports au client, crit dans les journaux du serveur ou les deux la fois, est contrl par les variables de
configuration log_min_messages et client_min_messages. Voir le Chapitre 18, Configuration du serveur pour plus
d'informations.

40.6. Procdures pour dclencheurs en PL/Tcl


Les procdures pour dclencheurs peuvent tre crites en PL/Tcl. PostgreSQL requiert qu'une procdure, devant tre appele en
tant que dclencheur, doit tre dclare comme une fonction sans arguments et retourner une valeur de type trigger.
L'information du gestionnaire de dclencheur est passe au corps de la procdure avec les variables suivantes :
$TG_name
Nom du dclencheur provenant de l'instruction CREATE TRIGGER.
$TG_relid
L'identifiant objet de la table qui est la cause du lancement du dclencheur.
$TG_table_name
777

PL/Tcl - Langage de procdures Tcl

Le nom de la table qui est la cause du lancement du dclencheur.


$TG_table_schema
Le schma de la table qui est la cause du lancement du dclencheur.
$TG_relatts
Une liste Tcl des noms des colonnes de la table, prfixe avec un lment de liste vide. Donc, rechercher un nom de colonne
dans la liste avec la commande lsearch de Tcl renvoie le numro de l'lment, en commenant 1 pour la premire colonne, de la mme faon que les colonnes sont numrotes personnellement avec PostgreSQL.
$TG_when
La chane BEFORE, AFTER ou INSTEAD OF suivant le type de l'vnement du dclencheur.
$TG_level
La chane ROW ou STATEMENT suivant le type de l'vnement du dclencheur.
$TG_op
La chane INSERT, UPDATE, DELETE ou TRUNCATE suivant le type de l'vnement du dclencheur.
$NEW
Un tableau associatif contenant les valeurs de la nouvelle ligne de la table pour les actions INSERT ou UPDATE ou vide
pour DELETE. Le tableau est index par nom de colonne. Les colonnes NULL n'apparaissent pas dans le tableau. Ce paramtre n'est pas initialis pour les triggers de niveau instruction.
$OLD
Un tableau associatif contenant les valeurs de l'ancienne ligne de la table pour les actions UPDATE or DELETE ou vide
pour INSERT. Le tableau est index par nom de colonne. Les colonnes NULL n'apparaissent pas dans le tableau. Ce paramtre n'est pas initialis pour les triggers de niveau instruction.
$args
Une liste Tcl des arguments de la procdure ainsi que l'instruction CREATE TRIGGER. Ces arguments sont aussi accessibles par $1 ... $n dans le corps de la procdure.
Le code de retour d'une procdure dclencheur peut tre faite avec une des chanes OK ou SKIP ou une liste renvoye par la commande Tcl array get. Si la valeur de retour est OK, l'opration (INSERT/UPDATE/DELETE) qui a lanc le dclencheur
continuera normalement. SKIP indique au gestionnaire de dclencheurs de supprimer silencieusement l'opration pour cette ligne.
Si une liste est renvoye, elle indique PL/Tcl de renvoyer la ligne modifie au gestionnaire de dclencheurs. Cela n'a un intrt
que pour les triggers niveau ligne pour BEFORE, INSERT ou UPDATE pour laquelle la ligne modifie sera insre au lieu de
celle donne dans $NEW ; our pour les triggers niveau ligne INSTEAD OF, INSERT ou UPDATE o la ligne renvoye est utilise pour supporter les commandes INSERT RETURNING et UPDATE RETURNING. La valeur de retour est ignore pour les
autres types de triggers.
Voici un petit exemple de procdure dclencheur qui force une valeur entire dans une table pour garder trace du nombre de mises
jour ralises sur la ligne. Pour les nouvelles lignes insres, la valeur est initialise 0 puis incrmente chaque opration de
mise jour.
CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS $$
switch $TG_op {
INSERT {
set NEW($1) 0
}
UPDATE {
set NEW($1) $OLD($1)
incr NEW($1)
}
default {
return OK
}
}
return [array get NEW]
$$ LANGUAGE pltcl;
CREATE TABLE mytab (num integer, description text, modcnt integer);
CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
FOR EACH ROW EXECUTE PROCEDURE trigfunc_modcount('modcnt');
Notez que la procdure dclencheur elle-mme ne connat pas le nom de la colonne ; c'est fourni avec les arguments du dclencheur. Ceci permet la procdure dclencheur d'tre r-utilise avec diffrentes tables.

778

PL/Tcl - Langage de procdures Tcl

40.7. Les modules et la commande unknown


PL/Tcl dispose du support de chargement automatique de code Tcl lorsqu'il est utilis. Il reconnat une table spciale, pltcl_modules, qui est prsume contenir les modules de code Tcl. Si cette table existe, le module unknown est rcupr de la
table et charg immdiatement dans l'interprteur Tcl avant la premire excution d'une fonction PL/Tcl dans une session. (Ceci
survient sparment pour chaque interprteur Tcl, si plus d'un est utilis dans une session ; voir Section 40.4, Donnes globales
avec PL/Tcl .)
Alors que le module unknown pourrait rellement contenir tout script d'initialisation dont vous avez besoin, il dfinit normalement une procdure Tcl unknown qui est appele lorsque Tcl ne reconnat pas le nom de la procdure appele. La version standard de PL/Tcl essaie de trouver un module dans pltcl_modules qui dfinira la procdure requis. Si une procdure est trouve, elle est charge dans l'interprteur, puis l'excution est permise avec l'appel original de la procdure. Une deuxime table
pltcl_modfuncs fournit un index des fonctions et des modules qui les dfinissent, de faon ce que la recherche soit rapide.
La distribution PostgreSQL inclut les scripts de support pour maintenir ces tables : pltcl_loadmod, pltcl_listmod, pltcl_delmod ainsi que le source pour le module standard unknown dans share/unknown.pltcl. Ce module doit tre chargeable dans chaque base de donnes initialement pour supporter le mcanisme de chargement automatique.
Les tables pltcl_modules et pltcl_modfuncs doivent tre lisibles par tous mais il est conseill de les laisser modifiables
uniquement par le propritaire, administrateur de la base de donnes. Pour des raisons de scurit, PL/Tcl ignorera pltcl_modules (et donc n'essaiera pas de charger le module unknown) sauf s'il appartient un superutilisateur. Cependant, les
droits de modification sur cette table peuvent tre donnes d'autres utilisateurs si vous avez suffisamment confiance en eux.

40.8. Noms de procdure Tcl


Avec PostgreSQL, le mme nom de fonction peut tre utilis par plusieurs fonctions tant que le nombre d'arguments ou leurs
types diffrent. Nanmoins, Tcl requiert que les noms de procdure soient distincts. PL/Tcl gre ceci en faisant en sorte que les
noms de procdures Tcl internes contiennent l'identifiant de l'objet de la fonction depuis la table systme pg_proc. Du coup, les
fonctions PostgreSQL avec un nom identique et des types d'arguments diffrents seront aussi des procdures Tcl diffrentes.
Ceci ne concerne normalement pas le dveloppeur PL/Tcl mais cela pourrait apparatre dans une session de dbogage.

779

Chapitre 41. PL/Perl - Langage de procdures Perl


PL/Perl est un langage de procdures chargeable qui vous permet d'crire des fonctions PostgreSQL dans le langage de programmation Perl.
Le principal avantage habituellement cit quant l'utilisation de Perl est que cela permet l'utilisation des nombreux oprateurs et
fonctions de gestion de chanes disponibles grce Perl dans des procdures stockes. L'analyse de chanes complexes se
trouve facilit par l'utilisation de Perl et des fonctions et structures de contrles fournies dans PL/pgSQL.
Pour installer PL/Perl dans une base de donnes spcifique, utilisez CREATE EXTENSION plperl ou utilisez la commande
createlang plperl nom_base partir de la ligne de commande du shell.

Astuce
Si un langage est install dans template1, toutes les bases de donnes cres ultrieurement disposeront automatiquement de ce langage.

Note
Les utilisateurs des paquetages sources doivent explicitement autoriser la construction de PL/Perl pendant le processus d'installation (se rfrer la Chapitre 15, Procdure d'installation de PostgreSQL du code source pour
plus d'informations). Les utilisateurs des paquetages binaires peuvent trouver PL/Perl dans un sous-paquetage spar.

41.1. Fonctions et arguments PL/Perl


Pour crer une fonction dans le langage PL/Perl, utilisez la syntaxe standard CREATE FUNCTION(7) :
CREATE FUNCTION nom_fonction (types-arguments) RETURNS
type-retour AS $$
# Corps de la fonction PL/Perl
$$ LANGUAGE plperl;
Le corps de la fonction est du code Perl normal. En fait, le code supplmentaire PL/Perl l'emballe dans une sous-routine Perl.
Une fonction PL/Perl est appele dans un contexte scalaire, il ne peut donc pas retourner une liste. Vous pouvez retourner des
valeurs non scalaire par rfrence comme indiqu ci-dessous.
PL/Perl peut aussi tre utilis au sein de blocs de procdures anonymes avec l'ordre DO(7) :
DO $$
# PL/Perl code
$$ LANGUAGE plperl;
Un bloc de procdure anonyme ne prend pas d'arguments et toute valeur retourn est ignore. Ceci mis part, il se comporte
comme une fonction classique.

Note
L'utilisation de sous-routines nommes est dangereux en Perl, spcialement si elles font rfrences des variables lexicales dans la partie englobante. Comme une fonction PL/Perl est englobe dans une sous-routine,
toute sous-routine nomme que vous y crez sera englobe. En gnral, il est bien plus sr de crer des sousroutines anonymes que vous appellerez via un coderef. Pour de plus amples dtails, voir les entres Variable
"%s" will not stay shared et Variable "%s" is not available dans le manuel perldiag, ou
recherchez perl nested named subroutine sur internet.
La syntaxe de la commande CREATE FUNCTION requiert que le corps de la fonction soit crit comme une constante de type
chane. Il est habituellement plus agrable d'utiliser les guillemets dollar (voir la Section 4.1.2.4, Constantes de chanes avec
guillemet dollar ) pour cette constante. Si vous choisissez d'utiliser la syntaxe d'chappement des chanes E'', vous devez
doubler les marques de guillemets simples (') et les antislashs (\) utiliss dans le corps de la fonction (voir la Section 4.1.2.1,
Constantes de chanes ).
Les arguments et les rsultats sont manipuls comme dans n'importe quel routine Perl : les arguments sont passs au tableau @_
et une valeur de retour est indique par return ou par la dernire expression value dans la fonction.
780

PL/Perl - Langage de procdures Perl

Par exemple, une fonction retournant le plus grand de deux entiers peut tre dfinie comme suit :
CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
if ($_[0] > $_[1]) { return $_[0]; }
return $_[1];
$$ LANGUAGE plperl;

Note
Les arguments seront convertis de l'encodage de la base de donnes en UTF-8 pour tre utilis par PL/perl, puis
converti de l'UTF-8 vers l'encodage de la base.
Si une valeur NULL en SQL est passe une fonction, cet argument apparatra comme undefined en Perl. La fonction dfinie
ci-dessus ne se comportera pas correctement avec des arguments NULL (en fait, tout se passera comme s'ils avaient t des zros).
Nous aurions pu ajouter STRICT la dfinition de la fonction pour forcer PostgreSQL faire quelque chose de plus raisonnable : si une valeur NULL est passe en argument, la fonction ne sera pas du tout appele mais retournera automatiquement un
rsultat NULL. D'une autre faon, nous aurions pu vrifier dans le corps de la fonction la prsence d'arguments NULL. Par
exemple, supposons que nous voulions que perl_max avec un argument NULL et un autre non NULL retourne une valeur non
NULL plutt qu'une valeur NULL, on aurait crit :
CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
my ($x, $y) = @_;
if (not defined $x) {
return undef if not defined $y;
return $y;
}
return $x if not defined $y;
return $x if $x > $y;
return $y;
$$ LANGUAGE plperl;
Comme le montre l'exemple ci-dessus, passer une valeur NULL en SQL une fonction en PL/Perl retourne une valeur non dfinie. Et ceci, que la fonction soit dclare stricte ou non.
Dans un argument de fonction, tout ce qui n'est pas une rfrence est une chane qui est dans la reprsentation texte externe standard de PostgreSQL pour ce type de donnes. Dans le cas de types numriques ou texte, Perl fera ce qu'il faut et le programmeur n'aura pas s'en soucier. Nanmoins, dans d'autres cas, l'argument aura besoin d'tre converti dans une forme qui est plus
utilisable que Perl. Par exemple, la fonction decode_bytea peut-tre utilise pour convertir un argument de type bytea en donnes binaires non chappes.
De faon similaire, les valeurs renvoyes PostgreSQL doivent tre dans le format textuel. Par exemple, la fonction encode_bytea peut tre utilise pour chapper des donnes binaires en retournant une valeur de type bytea.
Perl peut renvoyer des tableaux PostgreSQL comme rfrence des tableaux Perl. Voici un exemple :
CREATE OR REPLACE function renvoit_tableau()
RETURNS text[][] AS $$
return [['a"b','c,d'],['e\\f','g']];
$$ LANGUAGE plperl;
select renvoit_tableau();
Perl utilise les tableaux PostgreSQL comme des objets PostgreSQL::InServer::ARRAY. Cet objet sera trait comme une rfrence de tableau ou comme une chane, permettant une compatibilit ascendante avec le code Perl crit pour les versions de PostgreSQL antrieures la 9.1. Par exemple :
CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$
my $arg = shift;
my $result = "";
return undef if (!defined $arg);
# en tant que rfrence de tableau
for (@$arg) {
$result .= $_;
}
# en tant que chane
781

PL/Perl - Langage de procdures Perl

$result .= $arg;
return $result;
$$ LANGUAGE plperl;
SELECT concat_array_elements(ARRAY['PL','/','Perl']);

Note
Les tableaux multi-dimensionnels sont reprsents comme des rfrences des tableaux de refrence et de moindre
dimension, d'une faon connue de chaque dveloppeur Perl.
Les arguments de type composite sont passs la fonction en tant que rfrences d'un tableau de dcoupage, les cls du tableau de
dcoupage tant les noms des attributs du type compos. Voici un exemple :
CREATE TABLE employe (
nom text,
basesalaire integer,
bonus integer
);
CREATE FUNCTION empcomp(employe) RETURNS integer AS $$
my ($emp) = @_;
return $emp->{basesalaire} + $emp->{bonus};
$$ LANGUAGE plperl;
SELECT nom, empcomp(employe.*) FROM employe;
Une fonction PL/Perl peut renvoyer un rsultat de type composite en utilisant la mme approche : renvoyer une rfrence un hachage qui a les attributs requis. Par exemple
CREATE TYPE testligneperl AS (f1 integer, f2 text, f3 text);
CREATE OR REPLACE FUNCTION perl_ligne() RETURNS test_ligne_perl AS $$
return {f2 => 'hello', f1 => 1, f3 => 'world'};
$$ LANGUAGE plperl;
SELECT * FROM perl_row();
Toute colonne dans le type de donnes dclar du rsultat qui n'est pas prsente dans le hachage sera renvoye NULL.
Les fonctions PL/Perl peuvent aussi renvoyer des ensembles de types scalaires ou composites. Habituellement, vous voulez renvoyer une ligne la fois, la fois pour amliorer le temps de dmarrage et pour viter d'allonger la queue de l'ensemble des rsultats en mmoire. Vous pouvez faire ceci avec return_next comme indiqu ci-dessous. Notez qu'aprs le dernier return_next, vous devez placer soit return soit (encore mieux) return undef.
CREATE OR REPLACE FUNCTION perl_set_int(int)
RETURNS SETOF INTEGER AS $$
foreach (0..$_[0]) {
return_next($_);
}
return undef;
$$ LANGUAGE plperl;
SELECT * FROM perl_set_int(5);
CREATE OR REPLACE FUNCTION perl_set()
RETURNS SETOF test_ligne_perl AS $$
return_next({ f1 => 1, f2 => 'Hello', f3 => 'World' });
return_next({ f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' });
return_next({ f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' });
return undef;
$$ LANGUAGE plperl;
Pour les petits ensembles de rsultats, vous pouvez renvoyer une rfrence un tableau contenant soit des scalaires, soit des rfrences des tableaux soit des rfrences des hachages de types simples, de types tableaux ou de types composites. Voici
quelques exemples simples pour renvoyer l'ensemble complet du rsultant en tant que rfrence de tableau :
782

PL/Perl - Langage de procdures Perl

CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$


return [0..$_[0]];
$$ LANGUAGE plperl;
SELECT * FROM perl_set_int(5);
CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testligneperl AS $$
return [
{ f1 => 1, f2 => 'Bonjour', f3 => 'Monde' },
{ f1 => 2, f2 => 'Bonjour', f3 => 'PostgreSQL' },
{ f1 => 3, f2 => 'Bonjour', f3 => 'PL/Perl' }
];
$$ LANGUAGE plperl;
SELECT * FROM perl_set();
Si vous souhaitez utiliser le pragma strict dans votre code, vous avez plusieurs options. Pour une utilisation temporaire globale
vous pouvez positionner (SET) plperl.use_strict true . Ce paramtre affectera les compilations suivantes de fonctions PL/Perl, mais pas les fonctions dj compiles dans la session en cours. Pour une utilisation globale permanente, vous pouvez positionner plperl.use_strict true dans le fichier postgresql.conf.
Pour une utilisation permanente dans des fonctions spcifiques, vous pouvez simplement placer:
use strict;
en haut du corps de la fonction.
Le pragma feature est aussi disponible avec use si votre version de Perl est 5.10.0 ou suprieur.

41.2. Valeurs en PL/Perl


Les valeurs des arguments fournis au code d'une fonction PL/Perl sont simplement les arguments d'entre convertis en tant que
texte (comme s'ils avaient t affichs par une commande SELECT). Inversement, les commandes return and return_next
accepterons toute chane qui a un format d'entre acceptable pour le type de retour dclar de la fonction.

41.3. Fonction incluses


41.3.1. Accs la base de donnes depuis PL/Perl
L'accs la base de donnes l'intrieur de vos fonctions crites en Perl peut se faire partir des fonctions suivantes :
spi_exec_query(query [, max-rows])
spi_exec_query excute une commande SQL et renvoie l'ensemble complet de la ligne comme une rfrence un table
de rfrences haches. Vous ne devez utiliser cette commande que lorsque vous savez que l'ensemble de rsultat sera relativement petit. Voici un exemple d'une requte (commande SELECT) avec le nombre optionnel maximum de lignes :
$rv = spi_exec_query('SELECT * FROM ma_table', 5);
Ceci entrevoit cinq lignes au maximum de la table ma_table. Si ma_table a une colonne ma_colonne, vous obtenez la
valeur de la ligne $i du rsultat de cette faon :
$foo = $rv->{rows}[$i]->{ma_colonne};
Le nombre total des lignes renvoyes d'une requte SELECT peut tre accd de cette faon :
$nrows = $rv->{processed}
Voici un exemple en utilisant un type de commande diffrent :
$query = "INSERT INTO ma_table VALUES (1, 'test')";
$rv = spi_exec_query($query);
Ensuite, vous pouvez accder au statut de la commande (c'est--dire, SPI_OK_INSERT) de cette faon :
$res = $rv->{status};
Pour obtenir le nombre de lignes affectes, excutez :
$nrows = $rv->{processed};

783

PL/Perl - Langage de procdures Perl

Voici un exemple complet :


CREATE TABLE test (
i int,
v varchar
);
INSERT
INSERT
INSERT
INSERT

INTO
INTO
INTO
INTO

test
test
test
test

(i,
(i,
(i,
(i,

v)
v)
v)
v)

VALUES
VALUES
VALUES
VALUES

(1,
(2,
(3,
(4,

'premire ligne');
'deuxime ligne');
'troisime ligne');
'immortel');

CREATE OR REPLACE FUNCTION test_munge() RETURNS SETOF test AS $$


my $rv = spi_exec_query('select i, v from test;');
my $status = $rv->{status};
my $nrows = $rv->{processed};
foreach my $rn (0 .. $nrows - 1) {
my $row = $rv->{rows}[$rn];
$row->{i} += 200 if defined($row->{i});
$row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v}));
return_next($row);
}
return undef;
$$ LANGUAGE plperl;
SELECT * FROM test_munge();
spi_query(command), spi_fetchrow(cursor), spi_cursor_close(cursor)
spi_query et spi_fetchrow fonctionnent ensemble comme une paire d'ensembles de lignes pouvant tre assez importants ou pour les cas o vous souhaitez renvoyer les lignes ds qu'elles arrivent. spi_fetchrow fonctionne seulement avec
spi_query. L'exemple suivant illustre comment vous les utilisez ensemble :
CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT);
CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$
use Digest::MD5 qw(md5_hex);
my $file = '/usr/share/dict/words';
my $t = localtime;
elog(NOTICE, "opening file $file at $t" );
open my $fh, '<', $file # ooh, it's a file access!
or elog(ERROR, "cannot open $file for reading: $!");
my @words = <$fh>;
close $fh;
$t = localtime;
elog(NOTICE, "closed file $file at $t");
chomp(@words);
my $row;
my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)");
while (defined ($row = spi_fetchrow($sth))) {
return_next({
the_num => $row->{a},
the_text => md5_hex($words[rand @words])
});
}
return;
$$ LANGUAGE plperlu;
SELECT * from lotsa_md5(500);
Habituellement, spi_fetchrow devra tre rpt jusqu' ce qu'il renvoie undef, indiquant qu'il n'y a plus de lignes lire.
Le curseur renvoy par spi_query est automatiquement libr quand spi_fetchrow renvoie undef. Si vous ne souhaitez pas lire toutes les lignes, appelez la place spi_cursor_close pour librer le curseur. Un chec ici rsultera en des
pertes mmoire.
spi_prepare(command,
argument
types),
spi_query_prepared(plan,
arguments),
spi_exec_prepared(plan [, attributes], arguments), spi_freeplan(plan)
spi_prepare, spi_query_prepared, spi_exec_prepared et spi_freeplan implmentent la mme fonctionnalit, mais pour des requtes prpares. spi_prepare accepte une chane pour la requte avec des arguments numrots
784

PL/Perl - Langage de procdures Perl

($1, $2, etc) et une liste de chanes indiquant le type des arguments :
$plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', 'INTEGER',
'TEXT');
Une fois qu'un plan est prpar suite un appel spi_prepare, le plan peut tre utilis la place de la requte, soit dans
spi_exec_prepared, o le rsultat est identique celui renvoy par spi_exec_query, soit dans
spi_query_prepared qui renvoi un curseur exactement comme le fait spi_query, qui peut ensuite tre pass
spi_fetchrow. Le deuxime paramtre, optionnel, de spi_exec_prepared est une rfrence hache des attributs ; le
seul attribut actuellement support est limit, qui configure le nombre maximum de lignes renvoyes par une requte.
L'avantage des requtes prpares est que cela rend possible l'utilisation d'un plan prpar par plusieurs excutions de la requte. Une fois que le plan n'est plus utile, il peut tre libr avec spi_freeplan :
CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$
$_SHARED{my_plan} = spi_prepare( 'SELECT (now() + $1)::date AS now',
'INTERVAL');
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION add_time( INTERVAL ) RETURNS TEXT AS $$
return spi_exec_prepared(
$_SHARED{my_plan},
$_[0]
)->{rows}->[0]->{now};
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION done() RETURNS VOID AS $$
spi_freeplan( $_SHARED{my_plan});
undef $_SHARED{my_plan};
$$ LANGUAGE plperl;
SELECT init();
SELECT add_time('1 day'), add_time('2 days'), add_time('3 days');
SELECT done();
add_time | add_time | add_time
------------+------------+-----------2005-12-10 | 2005-12-11 | 2005-12-12
Notez que l'indice du paramtre dans spi_prepare est dfini via $1, $2, $3, etc, donc vitez de dclarer des chanes de requtes qui pourraient aisment amener des bogues difficiles trouver et corriger.
Cet autre exemple illustre l'utilisation d'un paramtre optionnel avec spi_exec_prepared :
CREATE TABLE hosts AS SELECT id, ('192.168.1.'||id)::inet AS address FROM
generate_series(1,3) AS id;
CREATE OR REPLACE FUNCTION init_hosts_query() RETURNS VOID AS $$
$_SHARED{plan} = spi_prepare('SELECT * FROM hosts WHERE address << $1',
'inet');
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION query_hosts(inet) RETURNS SETOF hosts AS $$
return spi_exec_prepared(
$_SHARED{plan},
{limit => 2},
$_[0]
)->{rows};
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION release_hosts_query() RETURNS VOID AS $$
spi_freeplan($_SHARED{plan});
undef $_SHARED{plan};
$$ LANGUAGE plperl;
SELECT init_hosts_query();
785

PL/Perl - Langage de procdures Perl

SELECT query_hosts('192.168.1.0/30');
SELECT release_hosts_query();
query_hosts
----------------(1,192.168.1.1)
(2,192.168.1.2)
(2 rows)

41.3.2. Fonctions utiles en PL/Perl


elog(level, msg)
Produit un message de trace ou d'erreur. Les niveaux possibles sont DEBUG, LOG, INFO, NOTICE, WARNING et ERROR.
ERROR lve une condition d'erreur ; si elle n'est pas rcupre par le code Perl l'entourant, l'erreur se propage l'extrieur de
la requte appelante, causant l'annulation de la transaction ou sous-transaction en cours. Ceci est en fait identique la commande die de Perl. Les autres niveaux gnrent seulement des messages de niveaux de priorit diffrents. Le fait que les
messages d'un niveau de priorit particulier soient rapports au client, crit dans les journaux du serveur, voire les deux, est
contrl par les variables de configuration log_min_messages et client_min_messages. Voir le Chapitre 18, Configuration du
serveur pour plus d'informations.
quote_literal(string)
Retourne la chane donne convenablement plac entre simple guillemets pour tre utilise comme une chane littrale au sein
d'une chane reprsentant un ordre SQL. Les simples guillemets et antislashes de la chane sont correctement doubls Notez
que quote_literal retourne undef avec une entre undef ; si l'argument peut tre undef, quote_nullable est souvent
plus appropri.
quote_nullable(string)
Retourne la chane donne convenablement plac entre simple guillemets pour tre utilise comme une chane littrale au sein
d'une chane reprsentant un ordre SQL. Si l'argument d'entre est undef, retourne la chane "NULL" sans simple guillemet.
Les simples guillemets et antislashes de la chane sont correctement doubls
quote_ident(string)
Retourne la chane donne convenablement plac entre guillemets pour tre utilise comme un identifiant au sein d'une chane
reprsentant un ordre SQL. Les guillemets sont ajoutes seulement si cela est ncessaire (i.e. si la chane contient des caractres non-identifiant ou est en majuscule). Les guillemets de la chane seront convenablement doubls.
decode_bytea(string)
Retourne les donnes binaires non chapp reprsentes par le contenu de la chane donne, qui doit tre encod au format
bytea.
encode_bytea(string)
Retourne sous la forme d'un bytea le contenu binaire dans la chane pass en argument.
encode_array_literal(array), encode_array_literal(array, delimiter)
Retourne le contenu de tableau pass par rfrence sous forme d'une chane littrale. (voir Section 8.14.2, Saisie de valeurs
de type tableau ). Retourne la valeur de l'argument non altre si ce n'est pas une rfrence un tableau. Le dlimiteur utilis
entre les lments du tableau sous forme littrale sera par dfaut ", " si aucun dlimiteur n'est spcifi ou s'il est undef.
encode_typed_literal(value, typename)
Convertit une variable Perl en une valeur du type de donnes pass en second argument et renvoie une reprsentation de type
chane pour cette valeur. Gre correctement les tableaux imbriqus et les valeurs de types composites.
encode_array_constructor(array)
Retourne le contenu de tableau pass par rfrence sous forme d'une chane permettant de construire un tableau en SQL. (voir
Section 4.2.12, Constructeurs de tableaux ). Chaque lment est entour de simple guillemets par quote_nullable.
Retourne la valeur de l'argument, entour de simple guillemets par quote_nullable, si ce n'est pas une rfrence un tableau.
looks_like_number(string)
Retourne une valeur vraie si le contenu de la chane passe ressemble un nombre, selon l'interprtation de Perl, et faux dans
le cas contraire. Retourne undef si undef est pass en argument. Tout espace en dbut et fin de chane sont ignors. Inf et
Infinity sont vu comme des nombres.
is_array_ref(argument)
Renvoie une valeur true si l'argument donn peut tre trait comme une rfrence de tableau, c'est--dire si la rfrence de
786

PL/Perl - Langage de procdures Perl

l'argument est ARRAY ou PostgreSQL::InServer::ARRAY. Renvoie false sinon.

41.4. Valeurs globales dans PL/Perl


Vous pouvez utiliser le hachage global %_SHARED pour stocker les donnes, incluant les rfrences de code, entre les appels de
fonction pour la dure de vie de la session en cours.
Voici un exemple simple pour des donnes partages :
CREATE OR REPLACE FUNCTION set_var(name text, val text) RETURNS text AS $$
if ($_SHARED{$_[0]} = $_[1]) {
return 'ok';
} else {
return "Ne peux pas initialiser la variable partage $_[0] $_[1]";
}
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION get_var(name text) RETURNS text AS $$
return $_SHARED{$_[0]};
$$ LANGUAGE plperl;
SELECT set_var('sample', 'Bonjour, PL/Perl ! Comment va ?');
SELECT get_var('sample');
Voici un exemple lgrement plus compliqu utilisant une rfrence de code :
CREATE OR REPLACE FUNCTION ma_fonction() RETURNS void AS $$
$_SHARED{myquote} = sub {
my $arg = shift;
$arg =~ s/(['\\])/\\$1/g;
return "'$arg'";
};
$$ LANGUAGE plperl;
SELECT ma_fonction(); /* initialise la fonction */
/* Initialise une fonction qui utilise la fonction quote */
CREATE OR REPLACE FUNCTION utilise_quote(TEXT) RETURNS text AS $$
my $text_to_quote = shift;
my $qfunc = $_SHARED{myquote};
return &$qfunc($text_to_quote);
$$ LANGUAGE plperl;
(Vous pouviez avoir remplac le code ci-dessus avec la seule ligne return $_SHARED{myquote}->($_[0]); au prix
d'une mauvaise lisibilit.)
Pour des raisons de scurit, PL/Perl excute des fonctions appeles par un rle SQL dans un interprteur Perl spar pour ce rle.
Ceci empche l'interfrence accidentelle ou malicieuse d'un utilisateur avec le comportement des fonctions PL/Perl d'un autre utilisateur. Chaque interprtateur a sa propre valeur de la variable %_SHARED et des autres tats globaux. Du coup, deux fonctions
PL/Perl partageront la mme valeur de %_SHARED si et seulement si elles sont excutes par le mme rle SQL. Dans une application o une session seule excute du code sous plusieurs rles SQL (via des fonctions SECURITY DEFINER, l'utilisation de
SET ROLE, etc), vous pouvez avoir besoin de mettre en place des tapes explicites pour vous assurer que les fonctions PL/Perl
peuvent partager des donnes %_SHARED. Pour cela, assurez-vous que les fonctions qui doivent communiquer ont pour propritaire le mme utilisateur et marquez les comme SECURITY DEFINER. Bien sr, vous devez faire attention ce que ces fonctions ne puissent pas tre utilises pour faire des choses qu'elles ne sont pas senses faire.

41.5. Niveaux de confiance de PL/Perl


Normalement, PL/Perl est install en tant que langage de programmation de confiance , de nom plperl. Durant cette installation, certaines commandes Perl sont dsactives pour prserver la scurit. En gnral, les commandes qui interagissent avec
l'environnement sont restreintes. Cela inclut les commandes sur les descripteurs de fichiers, require et use (pour les modules
externes). Il n'est pas possible d'accder aux fonctions et variables internes du processus du serveur de base de donnes ou
d'obtenir un accs au niveau du systme d'exploitation avec les droits du processus serveur, tel qu'une fonction C peut le faire.
Ainsi, n'importe quel utilisateur sans droits sur la base de donnes est autoris utiliser ce langage.
Voici l'exemple d'une fonction qui ne fonctionnera pas car les commandes systme ne sont pas autorises pour des raisons de scurit :
787

PL/Perl - Langage de procdures Perl

CREATE FUNCTION badfunc() RETURNS integer AS $$


my $tmpfile = "/tmp/badfile";
open my $fh, '>', $tmpfile
or elog(ERROR, qq{could not open the file "$tmpfile": $!});
print $fh "Testing writing to a file\n";
close $fh or elog(ERROR, qq{could not close the file "$tmpfile": $!});
return 1;
$$ LANGUAGE plperl;
La cration de cette fonction chouera car le validateur dtectera l'utilisation par cette fonction d'une opration interdite.
Il est parfois souhaitable d'crire des fonctions Perl qui ne sont pas restreintes. Par exemple, on peut souhaiter vouloir envoyer des
courriers lectroniques. Pour supporter ce cas de figure, PL/Perl peut aussi tre install comme un langage douteux
(habituellement nomm PL/PerlU ). Dans ce cas, la totalit du langage Perl est accessible. Lors de l'installation du langage, le nom
du langage plperlu slectionnera la version douteuse de PL/Perl.
Les auteurs des fonctions PL/PerlU doivent faire attention au fait que celles-ci ne puissent tre utilises pour faire quelque chose
de non dsir car cela donnera la possibilit d'agir comme si l'on possdait les privilges d'administrateur de la base de donnes. Il
est noter que le systme de base de donnes ne permet qu'aux super-utilisateurs de crer des fonctions dans un langage douteux.
Si la fonction ci-dessus a t cre par un super-utilisateur en utilisant le langage plperlu, l'excution de celle-ci russira.
De la mme faon, les blocs de procdure anonymes cris en perl peuvent utiliser les oprations restreintes si le langage est spcifi comme plperlu plutt que plperl, mais l'appelant doit tre un super-utilisateur.

Note
While PL/Perl functions run in a separate Perl interpreter for each SQL role, all PL/PerlU functions executed in a
given session run in a single Perl interpreter (which is not any of the ones used for PL/Perl functions). This allows
PL/PerlU functions to share data freely, but no communication can occur between PL/Perl and PL/PerlU functions.

Note
Perl cannot support multiple interpreters within one process unless it was built with the appropriate flags, namely
either usemultiplicity or useithreads. (usemultiplicity is preferred unless you actually need to
use threads. For more details, see the perlembed man page.) If PL/Perl is used with a copy of Perl that was not built
this way, then it is only possible to have one Perl interpreter per session, and so any one session can only execute
either PL/PerlU functions, or PL/Perl functions that are all called by the same SQL role.

41.6. Dclencheurs PL/Perl


PL/Perl peut tre utilis pour crire des fonctions pour dclencheurs. Dans une fonction dclencheur, la rfrence hache $_TD
contient des informations sur l'vnement du dclencheur en cours. $_TD est une variable globale qui obtient une valeur locale spare chaque appel du dclencheur. Les champs de la rfrence de hachage $_TD sont :
$_TD->{new}{foo}
Valeur NEW de la colonne foo
$_TD->{old}{foo}
Valeur OLD de la colonne foo
$_TD->{name}
Nom du dclencheur appel
$_TD->{event}
vnement du dclencheur : INSERT, UPDATE, DELETE, TRUNCATE, INSTEAD OF ou UNKNOWN
$_TD->{when}
Quand le dclencheur a t appel : BEFORE (avant), AFTER (aprs) ou UNKNOWN (inconnu)
$_TD->{level}
Le niveau du dclencheur : ROW (ligne), STATEMENT (instruction) ou UNKNOWN (inconnu)
$_TD->{relid}
L'OID de la table sur lequel le dclencheur a t excut
$_TD->{table_name}
788

PL/Perl - Langage de procdures Perl

Nom de la table sur lequel le dclencheur a t excut


$_TD->{relname}
Nom de la table sur lequel le dclencheur a t excut. Elle est obsolte et pourrait tre supprime dans une prochaine version. Utilisez $_TD->{table_name} la place.
$_TD->{table_schema}
Nom du schma sur lequel le dclencheur a t excut.
$_TD->{argc}
Nombre d'arguments de la fonction dclencheur
@{$_TD->{args}}
Arguments de la fonction dclencheur. N'existe pas si $_TD->{argc} vaut 0.
Les dclencheurs niveau ligne peuvent renvoyer un des lments suivants :
return;
Excute l'opration
"SKIP"
N'excute pas l'opration
"MODIFY"
Indique que la ligne NEW a t modifie par la fonction dclencheur
Voici un exemple d'une fonction dclencheur illustrant certains points ci-dessus :
CREATE TABLE test (
i int,
v varchar
);
CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$
if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) {
return "SKIP";
# passe la commande INSERT/UPDATE
} elsif ($_TD->{new}{v} ne "immortal") {
$_TD->{new}{v} .= "(modified by trigger)";
return "MODIFY"; # modifie la ligne et excute la commande INSERT/UPDATE
} else {
return;
# excute la commande INSERT/UPDATE
}
$$ LANGUAGE plperl;
CREATE TRIGGER test_valid_id_trig
BEFORE INSERT OR UPDATE ON test
FOR EACH ROW EXECUTE PROCEDURE valid_id();

41.7. PL/Perl sous le capot


41.7.1. Configuration
Cette section liste les paramtres de configuration de PL/Perl. Pour paramtrer n'importe lequel d'entre eux avant que PL/Perl ne
soit charg, il est ncessaire d'avoir ajout plperl la liste custom_variable_classes dans postgresql.conf.
plperl.on_init (string)
Spcifie un code perl excuter lorsque l'interprteur Perl est initialis pour la premire fois et avant qu'il soit spcialis pour
tre utilis par plperl ou plperlu. Les fonction SPI ne sont pas disponible lorsque ce code est excut. Si le code lve
une erreur, il interrompra l'initialisation de l'interprteur et la propagera la requte originale, provoquant ainsi l'annulation de
la transaction ou sous-transaction courante.
Le code Perl est limit une seule ligne. Un code plus long peut tre plac dans un module et charg par on_init.
Exemples:
plperl.on_init = 'require "plperlinit.pl"'
plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;'

789

PL/Perl - Langage de procdures Perl

Tous les modules chargs par plperl.on_init, directement ou indirectement, seront disponibles depuis plperl. Cela
entrane un problme de scurit potentiel. Pour consulter la liste des modules chargs, vous pouvez utiliser :
DO 'elog(WARNING, join ", ", sort keys %INC)' language plperl;
L'initialisation aura lieu au sein du postmaster si la librairie plperl est incluse dans le paramtre shared_preload_libraries), auquel cas une plus grande attention doit tre porte au risque de dstabiliser ce dernier. The principal reason for making use of
this feature is that Perl modules loaded by plperl.on_init need be loaded only at postmaster start, and will be instantly
available without loading overhead in individual database sessions. However, keep in mind that the overhead is avoided only
for the first Perl interpreter used by a database session -- either PL/PerlU, or PL/Perl for the first SQL role that calls a PL/Perl
function. Any additional Perl interpreters created in a database session will have to execute plperl.on_init afresh. Also,
on Windows there will be no savings whatsoever from preloading, since the Perl interpreter created in the postmaster process
does not propagate to child processes.
Ce paramtre ne peut tre positionn que dans le fichier postgresql.conf ou depuis la ligne de commande de dmarrage
du serveur.
plperl.on_plperl_init (string), plperl.on_plperlu_init (string)
These parameters specify Perl code to be executed when a Perl interpreter is specialized for plperl or plperlu respectively. This will happen when a PL/Perl or PL/PerlU function is first executed in a database session, or when an additional interpreter has to be created because the other language is called or a PL/Perl function is called by a new SQL role. This follows
any initialization done by plperl.on_init. The SPI functions are not available when this code is executed. The Perl code
in plperl.on_plperl_init is executed after locking down the interpreter, and thus it can only perform trusted operations.
Si le code lve une erreur, il interrompra l'initialisation et la propagera la requte originale, provoquant ainsi l'annulation de
la transaction ou sous-transaction courante. Any actions already done within Perl won't be undone; however, that interpreter
won't be used again. If the language is used again the initialization will be attempted again within a fresh Perl interpreter.
Only superusers can change these settings. Although these settings can be changed within a session, such changes will not affect Perl interpreters that have already been used to execute functions.
plperl.use_strict (boolean)
Lorsqu'il est positionn true , les compilations des fonction PL/Perl suivantes auront le pragma strict activ. Ce paramtre n'affecte pas les fonctions dj compiles au sein de la session courante.

41.7.2. Limitations et fonctionnalits absentes


Les fonctionnalits suivantes ne sont actuellement pas implmentes dans PL/Perl, mais peuvent faire l'objet de contributions gnreuses de votre part.

Les fonctions PL/Perl ne peuvent pas s'appeler entre elles.

SPI n'est pas compltement implment.

Si vous rcuprez des ensembles de donnes trs importants en utilisant spi_exec_query, vous devez tre conscient qu'ils
iront tous en mmoire. Vous pouvez l'viter en utilisant spi_query/spi_fetchrow comme montr prcdemment.
Un problme similaire survient si une fonction renvoyant un ensemble passe un gros ensemble de lignes PostgreSQL via
return. Vous pouvez l'viter aussi en utilisant la place return_next pour chaque ligne renvoye, comme indiqu prcdemment.

Lorsque'une session se termine normalement, et pas cause d'une erreur fatale, tous les blocs END qui ont t dfinis sont excuts. Actuellement, aucune autre action ne sont ralises. Spcifiquement, les descripteurs de fichiers ne sont pas vids automatiquement et les objets ne sont pas dtruits automatiquement.

790

Chapitre 42. PL/Python - Langage de procdures


Python
Le langage de procdures PL/Python permet l'criture de fonctions PostgreSQL avec le langage Python (mais voir aussi Section 42.1, Python 2 et Python 3 ).
Pour installer PL/Python dans une base de donnes particulires, utilisez CREATE EXTENSION plpythonu. partir de la
ligne de commandes, utilisez createlang plpythonu nom_base.

Astuce
Si un langage est install dans template1, toutes les bases nouvellement cres se verront installes ce langage
automatiquement.
Depuis PostgreSQL 7.4, PL/Python est seulement disponible en tant que langage sans confiance (ceci signifiant qu'il
n'offre aucun moyen de restreindre ce que les utilisateurs en font). Il a donc t renomm en plpythonu. La variante de
confiance plpython pourrait tre de nouveau disponible dans le futur, si un nouveau mcanisme scuris d'excution est dvelopp dans Python. Le codeur d'une fonction dans PL/Python sans confiance doit faire attention ce que cette fonction ne puisse
pas tre utilise pour raliser quelque chose qui n'est pas prvue car il sera possible de faire tout ce que peut faire un utilisateur
connect en tant qu'administrateur de la base de donnes. Seuls les superutilisateurs peuvent crer des fonctions dans des langages sans confiance comme plpythonu.

Note
Les utilisateurs des paquets sources doivent activer spcifiquement la construction de PL/Python lors des tapes
d'installation (rfrez-vous aux instructions d'installation pour plus d'informations). Les utilisateurs de paquets binaires pourront trouver PL/Python dans un paquet spar.

42.1. Python 2 et Python 3


PL/Python accepte la fois les versions 2 et 3 de Python. (Les instructions d'installation de PostgreSQL peuvent contenir des informations plus prcises sur les versions mineures prcisment supportes de Python.) Comme les variantes Python 2 et Python
3 sont incompatibles pour certaines parties trs importantes, le schma de nommage et de transition suivant est utilis par PL/
Python pour viter de les mixer :

Le langage PostgreSQL nomm plpython2u implmente PL/Python sur la variante Python 2 du langage.

Le langage PostgreSQL nomm plpython3u implmente PL/Python sur la variante Python 3 du langage.

Le langage nomm plpythonu implmente PL/Python suivant la variante par dfaut du langage Python, qui est actuellement Python 2. (Cette valeur par dfaut est indpendante de ce que toute installations locales de Python pourrait considrer
comme la valeur par dfaut , par exemplece que pourrait tre /usr/bin/python.) La valeur par dfaut sera probablement change avec Python 3 dans une prochaine version de PostgreSQL, suivant les progrs de la migration Python 3 dans
la communaut Python.

Cela dpend de la configuration lors de la compilation ou des paquets installs si PL/Python pour Python 2 ou Python 3 ou les
deux sont disponibles.

Astuce
La variante construite dpend de la version de Python trouve pendant l'installation ou de la version slectionne
explicitement en configurant la variable d'environnement PYTHON ; voir Section 15.4, Procdure
d'installation . Pour que les deux variantes de PL/Python soient disponibles sur une installation, le rpertoire des
sources doit tre configur et construit deux fois.
Ceci a pour rsultat la stratgie suivante d'utilisation et de migration :

Les utilisateurs existants et ceux qui ne sont pas actuellement intresss par Python 3 utilisent le nom plpythonu et n'ont
rien changer pour l'instant. Il est recommand de s'assurer graduellement de migrer le code vers Python 2.6/2.7 pour
simplifier une migration ventuelle vers Python 3.
791

PL/Python - Langage de procdures Python

En pratique, beaucoup de fonctions PL/Python seront migres Python 3 avec peu, voire par du tout, de modifications.

Les utilisateurs sachant d'avance qu'ils ont du code reposant massivement sur Python 2 et ne planifient pas de changer peuvent
utiliser le nom plpython2u. Cela continuera de fonctionner, y compris dans un futur lointain, jusqu' ce que le support de
Python 2 soit compltement supprime de PostgreSQL.

Les utilisateurs qui veulent utiliser Python 3 peuvent utiliser le nom plpython3u, qui continuera fonctionner en permanence avec les standards actuels. Dans le futur, quand Python 3 deviendra la version par dfaut du langage, ils pourront supprimer le chiffre 3 , principalement pour des raisons esthtiques.

Les intrpides qui veulent construire un systme d'exploitation utilisant seulement Python-3, peuvent modifier le contenu de
pg_pltemplate pour rendre plpythonu quivalent plpython3u, en gardant en tte que cela rend leur installation incompatible avec la majorit de ce qui existe dans ce monde.

Voir aussi le document What's New In Python 3.0 pour plus d'informations sur le portage vers Python 3.
Il n'est pas permis d'utiliser PL/Python bas sur Python 2 et PL/Python bas sur Python 3 dans la mme session car les symbles
dans les modules dynamiques entreraient en conflit, ce qui pourrait rsulter en des arrts brutaux du processus serveur PostgreSQL. Une vrification est ajoute pour empcher ce mlange de versions majeures Python dans une mme sessio. Cette vrification
aura pour effet d'annuler la session si une diffrence est dtecte. Nanmoins, il est possible d'utiliser les deux variantes de PL/
Python dans une mme base de donnes condition que ce soit dans des sessions spares.

42.2. Fonctions PL/Python


Les fonctions PL/Python sont dclares via la syntaxe standard CREATE FUNCTION(7) :
CREATE FUNCTION nom_fonction (liste-arguments)
RETURNS return-type
AS $$
# corps de la fonction PL/Python
$$ LANGUAGE plpythonu;
Le corps d'une fonction est tout simplement un script Python. Quand la fonction est appele, ses arguments sont passs au script
Python comme des lments de la liste args ; les arguments nomms sont en plus passs comme des variables ordinaires.
L'utilisation des arguments nomms est beaucoup plus lisible. Le rsultat est renvoy par le code Python de la faon habituelle,
avec return ou yield (dans le cas d'une instruction avec un ensemble de rsultats). Si vous ne fournissez pas une valeur de retour, Python renvoie la valeur par dfaut None. PL/Python traduit la valeur None de Python comme une valeur NULL SQL.
Par exemple, une fonction renvoyant le plus grand de deux entiers peut tre dfinie ainsi :
CREATE FUNCTION pymax (a integer, b integer)
RETURNS integer
AS $$
if a > b:
return a
return b
$$ LANGUAGE plpythonu;
Le code Python donn comme corps de la dfinition de fonction est transform en fonction Python. Par exemple, le code ci-dessus
devient :
def __plpython_procedure_pymax_23456():
if a > b:
return a
return b
en supposant que 23456 est l'OID affect la fonction par PostgreSQL.
Les arguments sont dfinis comme des variables globales. Consquence subtile des rgles sur la porte de variables dans Python,
il n'est pas possible de raffecter une variable l'intrieur d'une fonction en conservant son nom, sauf si elle est pralablement dclare comme globale l'intrieur du bloc. Ainsi, l'exemple suivant ne fonctionnera pas :
CREATE FUNCTION pystrip(x text)
RETURNS text
AS $$
x = x.strip() # error
return x
792

PL/Python - Langage de procdures Python

$$ LANGUAGE plpythonu;
car affecter la variable x la transforme en variable locale pour ce bloc et que, par consquent, la variable x de l'expression de
droite fait rfrence une variable locale x non encore dfinie, et non pas au paramtre de la fonction PL/Python. L'utilisation du
mot-cl global permet de rsoudre le problme :
CREATE FUNCTION pystrip(x text)
RETURNS text
AS $$
global x
x = x.strip() # ok now
return x
$$ LANGUAGE plpythonu;
Cependant, il vaut mieux ne pas trop s'appuyer sur ce dtail d'implmentation de PL/Python. Il est prfrable de traiter les paramtres de fonction comme tant en lecture seule.

42.3. Valeur des donnes avec PL/Python


De manire gnrale, le but de PL/Python est de fournir une relation naturelle entre PostgreSQL et le monde Python. Ces
rgles relationelles sont dcrites ci-dessous.

42.3.1. Type de donnes


Les paramtres de fonctions sont convertis de leur type PostgreSQL vers un type correspondant en Python :

Le type boolean PostgreSQL est converti en bool Python.

Les smallint et int de PostgreSQL sont convertis en int Python. Le bigint PostgreSQL est converti en long pour Python 2 et en
int pour Python 3.

Les real, double et numeric de PostgreSQL sont convertis en float Python. Notez que pour numeric, cela entraine une perte
d'information et peut aboutir des rsulats incorrects. Cela devrait tre corrig dans une future version.

Le bytea PostgreSQL est converti en str pour Python 2 et en bytes pour Python 3. Avec Python 2, la chane devrait tre traite
comme une squence d'octets sans encodage.

Tous les autres types de donnes, y compris les chanes de caractres PostgreSQL, sont convertis en str Python. En Python 2,
ces chanes auront le mme encodage de caractres que le serveur. En Python 3, ce seront des chanes Unicode comme les
autres.

Pour les donnes non scalaires, voir ci-dessous.

Les valeurs renvoyes par les fonctions sont converties en types de retour PostgreSQL comme suit:

Quand le type de la valeur PostgreSQL renvoye est boolean, la valeur de retrour sera value en fonction des rgles Python.
Ainsi, les 0 et les chaines vides sont fausses, mais la valeur 'f' est vraie.

Quand le type de la valeur PostgreSQL renvoye est bytea, la valeur de retour sera convertie en chaine de caractres (Python
2) ou en octets (Python 3) en utilisant les mcanismes Python correspondants, le rsultat tant ensuite converti en bytea.

Pour tous les autres types de retrour PostgreSQL, la valeur renvoye par Python est convertie en chaine de caractres en utilisant la mthode Python str, et et le rsultat est transmis la fonction d'entre du type de donnes PostgreSQL.
Les chaines de caractres en Python 2 doivent tre transmises dans le mme encodage que celui du serveur PostgreSQL. Les
chaines invalides dans l'encodage du serveur entraineront la leve d'une erreur, mais toutes les erreurs d'encodage ne sont pas
detectes, ce qui peut aboutir une corruption des donnes lorsque ces rgles ne sont pas respcte. Les chaines Unicode sont
automatiquement converties dans le bon encodage, il est donc plus prudent de les utiliser. Dans Python 3, toutes les chaines
sont en Unicode.

Pour les donnes non scalaires, voire ci dessous.

Notez que les erreurs logiques entre le type de retour dclar dans PostgreSQL et le type de l'objet Python renvoy ne sont pas dtectes. La valeur sera convertie dans tous les cas.

42.3.2. Null, None


Si une valeur SQL NULL est passe une fonction, la valeur de l'argument apparatra comme None au niveau de Python. Par
793

PL/Python - Langage de procdures Python

exemple, la dfinition de la fonction pymax indique dans Section 42.2, Fonctions PL/Python renverra la mauvaise rponse
pour des entres NULL. Nous pouvons jouer STRICT la dfinition de la fonction pour faire en sorte que PostgreSQL fasse
quelque-chose de plus raisonnable : si une valeur NULL est passe, la fonction ne sera pas appele du tout mais renverra juste un
rsultat NULL automatiquement. Sinon, vous pouver vrifier les entres NULL dans le corps de la fonction :
CREATE FUNCTION pymax (a integer, b integer)
RETURNS integer
AS $$
if (a is None) or (b is None):
return None
if a > b:
return a
return b
$$ LANGUAGE plpythonu;
Comme montr ci-dessus, pour renvoyer une valeur SQL NULL partir d'une fonction PL/Python, renvoyez la valeur None. Ceci
peut se faire que la fonction soit stricte ou non.

42.3.3. Tableaux, Listes


Les valeurs de type tableaux SQL sont passes via PL/Python comme des listes Python. Pour renvoyer une valeur de type tableau
SQL par une fonction PL/Python, renvoyez une squence Python, par exemple une liste ou un tuple :
CREATE FUNCTION return_arr()
RETURNS int[]
AS $$
return (1, 2, 3, 4, 5)
$$ LANGUAGE plpythonu;
SELECT return_arr();
return_arr
------------{1,2,3,4,5}
(1 row)
Notez que, avec Python, les chanes sont des squences, ce qui peut avoir des effets indsirables qui peuvent tre familiers aux codeurs Python :
CREATE FUNCTION return_str_arr()
RETURNS varchar[]
AS $$
return "hello"
$$ LANGUAGE plpythonu;
SELECT return_str_arr();
return_str_arr
---------------{h,e,l,l,o}
(1 row)

42.3.4. Types composites


Les arguments de type composite sont passs la fonction via une correspondance Python. Les noms d'lment de la correspondance sont les noms d'attribut du type composite. Si un attribut a une valeur NULL dans la ligne traite; il a la valeur NULL dans
sa correspondance. Voici un exemple :
CREATE TABLE employe (
nom text,
salaire integer,
age integer
);
CREATE FUNCTION trop_paye (e employe)
RETURNS boolean
AS $$
if e["salaire"] > 200000:
return True
if (e["age"] < 30) and (e["salaire"] > 100000):
794

PL/Python - Langage de procdures Python

return True
return False
$$ LANGUAGE plpythonu;
Il existe plusieurs faon de renvoyer une ligne ou des types composites partir d'une fonction Python. Les exemples suivants supposent que nous avons :
CREATE TABLE valeur_nommee (
nom
text,
valeur integer
);
ou
CREATE TYPE valeur_nommee AS (
nom
text,
valeur integer
);
Une valeur composite peut tre renvoy comme :
Un type squence (ligne ou liste), mais pas un ensemble parce que ce n'est pas indexable
Les objets squences renvoys doivent avoir le mme nombre d'lments que le type composite a de champs. L'lment
d'index 0 est affect au premier champ du type composite, 1 au second et ainsi de suite. Par exemple :
CREATE FUNCTION cree_paire (nom text, valeur integer)
RETURNS valeur_nommee
AS $$
return [ nom, valeur ]
# ou autrement, en tant que ligne : return ( nom, valeur )
$$ LANGUAGE plpythonu;
Pour renvoyer NULL dans une colonne, insrez None la position correspondante.
Correspondance (dictionnaire)
La valeur de chaque colonne du type rsultat est rcupre partir de la correspondance avec le nom de colonne comme cl.
Exemple :
CREATE FUNCTION cree_paire (nom text, valeur integer)
RETURNS valeur_nommee
AS $$
return { "nom": nom, "valeur": valeur }
$$ LANGUAGE plpythonu;
Des paires cls/valeurs supplmentaires du dictionnaire sont ignores. Les cls manquantes sont traites comme des erreurs.
Pour renvoyer NULL comme une colonne, insrez None avec le nom de la colonne correspondante comme cl.
Objet (tout objet fournissant la mthode __getattr__)
Ceci fonctionne de la mme faon qu'une correspondance. Exemple :
CREATE FUNCTION cree_paire (nom text, valeur integer)
RETURNS valeur_nommee
AS $$
class valeur_nommee:
def __init__ (self, n, v):
self.nom = n
self.valeur = v
return valeur_nommee(nom, valeur)
# ou simplement
class nv: pass
nv.nom = nom
nv.valeur = valeur
return nv
$$ LANGUAGE plpythonu;
Les fonctions ayant des paramtres OUT sont aussi supportes. Par exemple :
CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer) AS $$
return (1, 2)
795

PL/Python - Langage de procdures Python

$$ LANGUAGE plpythonu;
SELECT * FROM multiout_simple();

42.3.5. Fonctions renvoyant des ensembles


Une fonction PL/Python peut aussi renvoyer des ensembles scalaires ou des types composites. Il existe plusieurs faon de faire ceci parce que l'objet renvoy est transform en interne en itrateur. Les exemples suivants supposent que nous avons le type composite :
CREATE TYPE greeting AS (
how text,
who text
);
Un rsultat ensemble peut tre renvoy partir de :
Un type squence (ligne, liste, ensemble)
CREATE FUNCTION greet (how text)
RETURNS SETOF greeting
AS $$
# renvoie la ligne contenant les listes en tant que types composites
# toutes les autres combinaisons fonctionnent aussi
return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] )
$$ LANGUAGE plpythonu;
L'itrateur (tout objet fournissant les mthodes __iter__ et next)
CREATE FUNCTION greet (how text)
RETURNS SETOF greeting
AS $$
class producer:
def __init__ (self, how, who):
self.how = how
self.who = who
self.ndx = -1
def __iter__ (self):
return self
def next (self):
self.ndx += 1
if self.ndx == len(self.who):
raise StopIteration
return ( self.how, self.who[self.ndx] )
return producer(how, [ "World", "PostgreSQL", "PL/Python" ])
$$ LANGUAGE plpythonu;
Le gnrateur (yield)
CREATE FUNCTION greet (how text)
RETURNS SETOF greeting
AS $$
for who in [ "World", "PostgreSQL", "PL/Python" ]:
yield ( how, who )
$$ LANGUAGE plpythonu;

Avertissement
cause du bogue #1483133 de Python, certaines versions de dbogage de Python 2.4 (configur et compil
avec l'option --with-pydebug) sont connues pour arrter brutalement le serveur PostgreSQL lors de
l'utilisation d'un itrateur pour renvoyer un rsultat ensemble. Les versions non corriges de Fedora 4
contiennent ce bogue. Cela n'arrive pas dans les versions de production de Python et sur les versions corriges
de Fedora 4.

796

PL/Python - Langage de procdures Python

Les fonctions renvoyant des ensembles et ayant des paramtres OUT (en utilisant RETURNS SETOF record) sont aussi supportes. Par exemple :
CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS
SETOF record AS $$
return [(1, 2)] * n
$$ LANGUAGE plpythonu;
SELECT * FROM multiout_simple_setof(3);

42.4. Sharing Data


Le dictionnaire global SD est disponible pour stocker des donnes entres les appels de fonctions. Cette variable est une donne statique prive. Le dictionnaire global GD est une donne publique disponible pour toutes les fonctions Python l'intrieur d'une session. utiliser avec prcaution.
Chaque fonction obtient son propre environnement d'excution dans l'interprteur Python, de faon ce que les donnes globales
et les arguments de fonction provenant de ma_fonction ne soient pas disponibles depuis ma_fonction2. L'exception
concerne les donnes du dictionnaire GD comme indiqu ci-dessus.

42.5. Blocs de code anonymes


PL/Python accepte aussi les blocs de code anonymes appels avec l'instruction DO(7) :
DO $$
# Code PL/Python
$$ LANGUAGE plpythonu;
Un bloc de code anonyme ne reoit aucun argument et, quelque soit la valeur renvoye, elle est ignore. Sinon, ce bloc se comporte exactement comme n'importe quelle fonction.

42.6. Fonctions de dclencheurs


Quand une fonction est utilise par un trigger, le dictionnaire TD contient les valeurs relatives au trigger :
TD["event"]
contient l'vnement sous la forme d'une chane : INSERT, UPDATE, DELETE, TRUNCATE.
TD["when"]
contient une chane valant soit BEFORE, soit AFTER soit INSTEAD OF.
TD["level"]
contient une chane valant soit ROW soit STATEMENT.
TD["new"], TD["old"]
pour un trigger au niveau ligne, ces champs contiennent les lignes du trigger, l'ancienne version et la nouvelle version ; les
deux champs ne sont pas forcment disponibles, ceci dpendant de l'vnement qui a dclench le trigger
TD["name"]
contient le nom du trigger.
TD["table_name"]
contient le nom de la table sur laquelle le trigger a t dclench
TD["table_schema"]
contient le schma de la table sur laquelle le trigger a t dclench
TD["relid"]
contient l'OID de la table sur laquelle le trigger a t dclench
TD["args"]
si la commande CREATE TRIGGER comprend des arguments, ils sont disponibles dans les variables allant de
TD["args"][0] TD["args"][n-1].
Si TD["when"] vaut BEFORE ou INSTEAD OF et si TD["level"] vaut ROW, vous pourriez renvoyer None ou "OK" partir de la fonction Python pour indiquer que la ligne n'est pas modifie, "SKIP" pour annuler l'vnement ou si TD["event"]
797

PL/Python - Langage de procdures Python

vaut INSERT ou UPDATE, vous pouvez renvoyer "MODIFY" pour indiquer que vous avez modifi la ligne. Sinon la valeur de
retour est ignore.

42.7. Accs la base de donnes


Le module du langage PL/Python importe automatiquement un module Python appel plpy. Les fonctions et constantes de ce
module vous sont accessibles dans le code Python via plpy.foo.

42.7.1. Fonctions d'accs la base de donnes


Le module plpy propose deux fonctions appeles execute et prepare. Appeler plpy.execute avec une requte sous
forme de chane de caractres et un argument optionnel de limite fait que la requte est excute et le rsultat renvoy dans un objet rsultat. Cet objet mule un objet liste ou dictionnaire. L'accs aux rsultats se fait par numro de ligne et nom de colonne.
Deux mthodes supplmentaires sont utilisables : nrows qui renvoit le nombre de lignes renvoyes par la requte, et status qui
correspond la valeur de retour de SPI_execute(). L'objet rsultat est modifiable.
Par exemple :
rv = plpy.execute("SELECT * FROM ma_table", 5)
renvoit jusqu' cinq lignes de ma_table. Si ma_table a une colonne ma_colonne, son contenu peut tre rcupr ainsi :
foo = rv[i]["ma_colonne"]
la seconde fonction, plpy.prepare, prpare le plan d'excution d'une requte. Il utilise comme arguments une chane de caractres pour la requte et une liste des types de paramtres si des rfrences de paramtres sont indiques dans la requte. Par
exemple :
plan = plpy.prepare("SELECT nom FROM mes_utilisateurs WHERE prenom = $1", [ "text" ])
text est le type de la variable que vous devrez passer pour $1. Aprs avoir prpar une requte, vous devez utiliser la fonction
plpy.execute pour l'excuter :
rv = plpy.execute(plan, [ "nom" ], 5)
Le troisime argument, optionnel, est la limite.
Les paramtres de requtes et les champs de rsultats sont convertis entre PostgreSQL et les types de donnes Python comme indiqu dans Section 42.3, Valeur des donnes avec PL/Python . L'exception est que les types composites ne sont pas actuellement
supports : ils sont rejets dans le cas des paramtres de requte et convertis en chanes de caractres quand ils apparaissent dans
le rsultat d'une requte. Pour contourner ce deuxime cas, la requte peut tre quelque fois crite de faon ce que le type composite apparaisse comme une ligne de rsultat plutt que comme le champ d'une ligne du rsultat. Autrement, la chane rsultante
peut tre analyse manuellement mais cette approche n'est pas recommende car une version future pourrait demander de refaire
l'analyse de la chane en retour.
Quand vous prparez un plan en utilisant le module PL/Python, il est automatiquement sauvegard. Lisez la documentation SPI
(Chapitre 43, Interface de programmation serveur) pour une description complte. Pour en avoir une utilisation relle via des appels de fonctions, vous avez besoin d'utiliser un dictionnaire de stockage persistent SD ou GD (voir Section 42.4, Sharing
Data ). Par exemple :
CREATE FUNCTION utilise_plan_sauvegarde() RETURNS trigger AS $$
if SD.has_key("plan"):
plan = SD["plan"]
else:
plan = plpy.prepare("SELECT 1")
SD["plan"] = plan
# reste de la fonction
$$ LANGUAGE plpythonu;

42.7.2. Rcuprer les erreurs


Les fonctions accdant la base de donnes peuvent rencontrer des erreurs, qui forceront leur annulation et lveront une exception. plpy.execute et plpy.prepare peuvent lancer une instance d'une sous-classe de plpy.SPIError, qui terminera
par dfaut la fonction. Cette erreur peut tre gre comme toutes les autres exceptions Python, en utilisant la construction try/
798

PL/Python - Langage de procdures Python

except. Par exemple :


CREATE FUNCTION essaie_ajout_joe() RETURNS text AS $$
try:
plpy.execute("INSERT INTO utilisateurs(nom) VALUES ('joe')")
except plpy.SPIError:
return "quelque chose de mal est arriv"
else:
return "Joe ajout"
$$ LANGUAGE plpythonu;
La classe relle de l'exception leve correspond la condition spcifique qui a caus l'erreur. Rfrez-vous Tableau A.1, Codes
d'erreur de PostgreSQL pour une liste des conditions possibles. Le module plpy.spiexceptions dfinit une classe
d'exception pour chaque condition PostgreSQL, drivant leur noms du nom de la condition. Par exemple, division_by_zero devient DivisionByZero, unique_violation devient UniqueViolation, fdw_error devient
FdwError, et ainsi de suite. Chacune de ces classes d'exception hrite de SPIError. Cette sparation rend plus simple la gestion des erreurs spcifiques. Par exemple :
CREATE FUNCTION insere_fraction(numerateur int, denominateur int) RETURNS text AS $$
from plpy import spiexceptions
try:
plan = plpy.prepare("INSERT INTO fractions (frac) VALUES ($1 / $2)", ["int",
"int"])
plpy.execute(plan, [numerateur, denominateur])
except spiexceptions.DivisionByZero:
return "denominateur doit tre diffrent de zro"
except spiexceptions.UniqueViolation:
return "a dj cette fraction"
except plpy.SPIError, e:
return "autre erreur, SQLSTATE %s" % e.sqlstate
else:
return "fraction insre"
$$ LANGUAGE plpythonu;
Notez que, comme toutes les exceptions du module plpy.spiexceptions hritent de SPIError, une clause except la grant rcuprera toutes les erreurs d'accs aux bases.
Comme alternative la gestion des diffrentes conditions d'erreur, vous pouvez rcuprer l'exception SPIError et dterminer la
condition d'erreur spcifique dans le bloc except en recherchant l'attribut sqlstate de l'objet exception. Cet attribut est une
chane contenant le code d'erreur SQLSTATE . Cette approche fournit approximativement la mme fonctionnalit.

42.8. Sous-transactions explicites


La rcupration d'erreurs causes par l'accs la base de donnes, comme dcrite dans Section 42.7.2, Rcuprer les erreurs ,
peut amener une situation indsirable o certaines oprations russissent avant qu'une d'entre elles choue et, aprs rcupration
de cette erreur, les donnes sont laisses dans un tat incohrent. PL/Python propose une solution ce problme sous la forme de
sous-transactions explicites.

42.8.1. Gestionnaires de contexte de sous-transaction


Prenez en considration une fonction qui implmente un transfert entre deux comptes :
CREATE FUNCTION transfert_fonds() RETURNS void AS $$
try:
plpy.execute("UPDATE comptes SET balance = balance
plpy.execute("UPDATE comptes SET balance = balance
except plpy.SPIError, e:
result = "erreur lors du transfert de fond : %s" %
else:
result = "fonds transfr correctement"
plan = plpy.prepare("INSERT INTO operations (resultat)
plpy.execute(plan, [result])
$$ LANGUAGE plpythonu;

- 100 WHERE nom = 'joe'")


+ 100 WHERE nom = 'mary'")
e.args
VALUES ($1)", ["text"])

Si la deuxime instruction UPDATE se termine avec la leve d'une exception, cette fonction renverra l'erreur mais le rsultat du
premier UPDATE sera valid malgr tout. Autrement dit, les fonds auront t dbits du compte de Joe mais ils n'auront pas t
799

PL/Python - Langage de procdures Python

crdits sur le compte de Mary.


Pour viter ce type de problmes, vous pouvez intgrer vos appels plpy.execute dans une sous-transaction explicite. Le module plpy fournit un objet d'aide la gestion des sous-transactions explicites qui sont cres avec la fonction plpy.subtransaction(). Les objets crs par cette fonction implmentent l' interface de gestion du contexte. Nous pouvons
rcrire notre fonction en utilisant les sous-transactions explicites :
CREATE FUNCTION transfert_fonds2() RETURNS void AS $$
try:
with plpy.subtransaction():
plpy.execute("UPDATE comptes SET balance = balance - 100 WHERE nom = 'joe'")
plpy.execute("UPDATE comptes SET balance = balance + 100 WHERE nom = 'mary'")
except plpy.SPIError, e:
result = "erreur lors du transfert de fond : %s" % e.args
else:
result = "fonds transfr correctement"
plan = plpy.prepare("INSERT INTO operations (resultat) VALUES ($1)", ["text"])
plpy.execute(plan, [result])
$$ LANGUAGE plpythonu;
Notez que l'utilisation de try/catch est toujours requis. Sinon, l'exception se propagerait en haut de la pile Python et causerait
l'annulation de la fonction entire avec une erreur PostgreSQL, pour que la table operations ne contienne aucune des lignes
insres. Le gestionnaire de contexte des sous-transactions ne rcupre pas les erreurs, il assure seulement que toutes les oprations de bases de donnes excutes dans son cadre seront valides ou annules de faon atomique. Une annulation d'un bloc de
sous-transaction survient la sortie de tout type d'exception, pas seulement celles causes par des erreurs venant de l'accs la
base de donnes. Une exception standard Python leve dans un bloc de sous-transaction explicite causerait aussi l'annulation de la
sous-transaction.

42.8.2. Anciennes versions de Python


Pour les gestionnaires de contexte, la syntaxe utilisant le mot cl with, est disponible par dfaut avec Python 2.6. Si vous utilisez
une version plus ancienne de Python, il est toujours possible d'utiliser les sous-transactions explicites, bien que cela ne sera pas
transparent. Vous pouvez appeler les fonctions __enter__ et __exit__ des gestionnaires de sous-transactions en utilisant les
alias enter et exit. La fonction exemple de transfert des fonds pourrait tre crite ainsi :
CREATE FUNCTION transfert_fonds_ancien() RETURNS
try:
subxact = plpy.subtransaction()
subxact.enter()
try:
plpy.execute("UPDATE comptes SET balance
plpy.execute("UPDATE comptes SET balance
except:
import sys
subxact.exit(*sys.exc_info())
raise
else:
subxact.exit(None, None, None)
except plpy.SPIError, e:
result = "erreur lors du transfert de fond :
else:
result = "fonds transfr correctement"

void AS $$

= balance - 100 WHERE nom = 'joe'")


= balance + 100 WHERE nom = 'mary'")

%s" % e.args

plan = plpy.prepare("INSERT INTO operations (resultat) VALUES ($1)", ["text"])


plpy.execute(plan, [result])
$$ LANGUAGE plpythonu;

Note
Bien que les gestionnaires de contexte sont implments dans Python 2.5, pour utiliser la syntaxe with dans cette
version vous aurez besoin d'utiliser une requte future. D aux dtails d'implmentation, vous ne pouvez pas utiliser les requtes futures dans des fonctions PL/Python.

42.9. Fonctions outils


800

PL/Python - Langage de procdures Python

Le module plpy fournit aussi les fonctions plpy.debug(msg), plpy.log(msg), plpy.info(msg),


plpy.notice(msg), plpy.warning(msg), plpy.error(msg) et plpy.fatal(msg). plpy.error et plpy.fatal("msg") lvent une exception Python qui, si non attrape, se propage la requte appelante causant l'annulation de
la transaction ou sous-transaction en cours. raise plpy.Error(msg) et raise plpy.Fatal(msg) sont quivalent
appeler, respectivement, plpy.error et plpy.fatal. Les autres fonctions gnrent uniquement des messages de niveaux de
priorit diffrents. Que les messages d'une priorit particulire soient reports au client, crit dans les journaux du serveur ou les
deux, cette configuration est contrle par les variables log_min_messages et client_min_messages. Voir le Chapitre 18, Configuration du serveur pour plus d'informations.
Voici un autre ensemble de fonctions outils : plpy.quote_literal(string), plpy.quote_nullable(string) et
plpy.quote_ident(string). Elles sont quivalentes aux fonctions internes de mise entre guillemets dcrites dans Section 9.4, Fonctions et oprateurs de chanes . Elles sont utiles lors de la construction de requtes. Un quivalent PL/Python
d'une requte SQL dynamique pour Exemple 39.1, Mettre entre guillemets des valeurs dans des requtes dynamiques serait :
plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % (
plpy.quote_ident(colname),
plpy.quote_nullable(newvalue),
plpy.quote_literal(keyvalue)))

42.10. Variables d'environnement


Certaines des variables d'environnement qui sont acceptes par l'interprteur Python peuvent aussi tre utilises pour modifier le
comportement de PL/Python. Elles doivent tre configures dans l'environnement du processus serveur PostgreSQL principal, par
exemple dans le script de dmarrage. Les variables d'environnement disponibles dpendent de la version de Python ; voir la documentation de Python pour les dtails. Au moment de l'criture de ce chapitre, les variables d'environnement suivantes avaient un
comportement sur PL/Python, condition d'utiliser une version adquate de Python :

PYTHONHOME

PYTHONPATH

PYTHONY2K

PYTHONOPTIMIZE

PYTHONDEBUG

PYTHONVERBOSE

PYTHONCASEOK

PYTHONDONTWRITEBYTECODE

PYTHONIOENCODING

PYTHONUSERBASE

(Cela semble tre un dtail d'implmentation de Python, en dehors du contrle de PL/Python, qui fait que certaines variables
d'environnement listes dans la page man de python sont seulement utilisables avec l'interprteur en ligne de commande et non
avec un interprteur Python embarqu.)

801

Chapitre 43. Interface de programmation serveur


L'interface de programmation serveur (SPI) donne aux auteurs de fonctions C la capacit de lancer des commandes SQL au sein
de leurs fonctions. SPI est une srie de fonctions d'interface simplifiant l'accs l'analyseur, au planificateur et au lanceur. SPI
fait aussi de la gestion de mmoire.

Note
Les langages procduraux disponibles donnent plusieurs moyens de lancer des commandes SQL partir de procdures. La plupart est base partir de SPI. Cette documentation prsente donc galement un intrt pour les
utilisateurs de ces langages.
Pour assurer la comprhension, nous utiliserons le terme de fonction quand nous parlerons de fonctions d'interface SPI et
procdure pour une fonction C dfinie par l'utilisateur et utilisant SPI.
Notez que si une commande appele via SPI choue, alors le contrle ne sera pas redonn votre procdure. Au contraire, la
transaction ou sous-transaction dans laquelle est excute votre procdure sera annule. (Ceci pourrait tre surprenant tant donn que les fonctions SPI ont pour la plupart des conventions documentes de renvoi d'erreur. Ces conventions s'appliquent seulement pour les erreurs dtectes l'intrieur des fonctions SPI.) Il est possible de rcuprer le contrle aprs une erreur en tablissant votre propre sous-transaction englobant les appels SPI qui pourraient chouer. Ceci n'est actuellement pas document
parce que les mcanismes requis sont toujours en flux.
Les fonctions SPI renvoient un rsultat positif en cas de succs (soit par une valeur de retour entire, soit dans la variable globale SPI_result comme dcrit ci-dessous). En cas d'erreur, un rsultat ngatif ou NULL sera retourn.
Les fichiers de code source qui utilisent SPI doivent inclure le fichier d'en-tte executor/spi.h.

43.1. Fonctions d'interface

802

Interface de programmation serveur

Nom
SPI_connect connecter une procdure au gestionnaire SPI

Synopsis
int SPI_connect(void)

Description
SPI_connect ouvre une connexion au gestionnaire SPI lors de l'appel d'une procdure. Vous devez appeler cette fonction si
vous voulez lancer des commandes au travers du SPI. Certaines fonctions SPI utilitaires peuvent tre appeles partir de procdures non connectes.
Si votre procdure est dj connecte, SPI_connect retournera le code d'erreur SPI_ERROR_CONNECT. Cela peut arriver si
une procdure qui a appel SPI_connect appelle directement une autre procdure qui appelle SPI_connect. Bien que des
appels rcursifs au gestionnaire SPI soient permis lorsqu'une commande SQL appele au travers du SPI invoque une autre fonction qui utilise SPI, les appels directement intgrs SPI_connect et SPI_finish sont interdits (mais voir SPI_push et
SPI_pop).

Valeur de retour
SPI_OK_CONNECT
en cas de succs
SPI_ERROR_CONNECT
en cas d'chec

803

Interface de programmation serveur

Nom
SPI_finish dconnecter une procdure du gestionnaire SPI

Synopsis
int SPI_finish(void)

Description
SPI_finish ferme une connexion existante au gestionnaire SPI. Vous devez appeler cette fonction aprs avoir termin les oprations SPI souhaites pendant l'invocation courante de votre procdure. Vous n'avez pas vous proccuper de ceci, sauf si vous
terminez la transaction via elog(ERROR). Dans ce cas, SPI terminera automatiquement.
Si SPI_finish est appele sans avoir une connexion valable, elle retournera SPI_ERROR_UNCONNECTED. Il n'y a pas de
problme fondamental avec cela ; le gestionnaire SPI n'a simplement rien faire.

Valeur de retour
SPI_OK_FINISH
si dconnecte correctement
SPI_ERROR_UNCONNECTED
si appel partir d'une procdure non connecte

804

Interface de programmation serveur

Nom
SPI_push pousse la pile SPI pour autoriser une utilisation rcursive de SPI

Synopsis
void SPI_push(void)

Description
SPI_push devrait tre appel avant d'excuter une autre procdure qui pourrait elle-mme souhaiter utiliser SPI. Aprs
SPI_push, SPI n'est plus dans un tat connect et les appels de fonction SPI seront rejets sauf si un nouveau
SPI_connect est excut. Ceci nous assure une sparation propre entre l'tat SPI de votre procdure et celui d'une autre procdure que vous appelez. Aprs le retour de cette dernire, appelez SPI_pop pour restaurer l'accs votre propre tat SPI.
Notez que SPI_execute et les fonctions relatives font automatiquement l'quivalent de SPI_push avant de repasser le
contrle au moteur d'excution SQL, donc il n'est pas ncessaire de vous inquiter de cela lors de l'utilisation de ces fonctions.
Vous aurez besoin d'appeler SPI_push et SPI_pop seulement quand vous appelez directement un code arbitraire qui pourrait
contenir des appels SPI_connect.

805

Interface de programmation serveur

Nom
SPI_pop rcupre la pile SPI pour revenir de l'utilisation rcursive de SPI

Synopsis
void SPI_pop(void)

Description
SPI_pop enlve l'environnement prcdent de la pile d'appel SPI. Voir SPI_push.

806

Interface de programmation serveur

Nom
SPI_execute excute une commande

Synopsis
int SPI_execute(const char * command, bool read_only, long count)

Description
SPI_exec lance la commande SQL spcifie pour count lignes. Si read_only est true, la commande doit tre en lecture
seule et la surcharge de l'excution est quelque peu rduite.
Cette fonction ne devrait tre appele qu' partir d'une procdure connecte.
Si count vaut zro, alors la commande est excute pour toutes les lignes auxquelles elle s'applique. Si count est suprieur 0,
alors pas plus de count lignes seront rcupres. L'excution s'arrtera quand le compte est atteint, un peu comme l'ajout d'une
clause LIMIT une requte. Par exemple :
SPI_execute("SELECT * FROM foo", true, 5);
rcuprera 5 lignes tout au plus partir de la table. Notez qu'une telle limite n'est efficace qu' partir du moment o la requte renvoie des lignes. Par exemple :
SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
insrera toutes les lignes de bar, en ignorant le paramtre count. Cependant, avec
SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5);
au plus cinq lignes seront insres car l'excution s'arrtera aprs la cinquime ligne renvoye par RETURNING.
Vous pourriez passer plusieurs commandes dans une chane, mais ces commandes ne peuvent pas dpendre d'objets crs plus tt
dans la chane car toute la chane est analyse et planifie avant le dbut de l'excution. SPI_execute renvoie le rsultat pour la
dernire commande excute. La limite count s'applique chaque commande sparment (mme si seul le dernier rsultat sera
renvoy). La limite n'est pas applique toute commande cache gnre par les rgles.
Quand read_only vaut false, SPI_execute incrmente le compteur de la commande et calcule une nouvelle image avant
d'excuter chaque commande dans la chane. L'image n'est pas rellement modifie si le niveau d'isolation de la transaction en
cours est SERIALIZABLE ou REPEATABLE READ mais, en mode READ COMMITTED, la mise jour de l'image permet
chaque commande de voir les rsultats des transactions nouvellement valides partir des autres sessions. Ceci est essentiel pour
un comportement cohrent quand les commandes modifient la base de donnes.
Quand read_only vaut true, SPI_execute ne met jour ni l'image ni le compteur de commandes, et il autorise seulement
les commandes SELECT dans la chane des commandes. Elles sont excutes en utilisant l'image prcdemment tablie par la requte englobante. Ce mode d'excution est un peu plus rapide que le mode lecture/criture cause de l'limination de la surcharge
par commande. Il autorise aussi directement la construction des fonctions stable comme les excutions successives utiliseront
toutes la mme image, il n'y aura aucune modification dans les rsultats.
Il n'est gnralement pas conseill de mixer les commandes en lecture seule et les commandes en lecture/criture l'intrieur d'une
seule fonction utilisant SPI ; ceci pourrait causer un comportement portant confusion car les requtes en mode lecture seule devraient ne pas voir les rsultats de toute mise jour de la base de donnes effectues par les requtes en lecture/criture.
Le nombre rel de lignes pour lesquelles la (dernire) commande a t lance est retourn dans la variable globale
SPI_processed. Si la valeur de retour de la fonction est SPI_OK_SELECT, SPI_OK_INSERT_RETURNING,
SPI_OK_DELETE_RETURNING ou SPI_OK_UPDATE_RETURNING, alors vous pouvez utiliser le pointeur global SPITupleTable *SPI_tuptable pour accder aux lignes de rsultat. Quelques commandes (comme EXPLAIN) renvoient aussi
des ensembles de lignes et SPI_tuptable contiendra aussi le rsultat dans ces cas.
La structure SPITupleTable est dfinie comme suit :
typedef struct
{
MemoryContext tuptabcxt;
uint32
alloced;
uint32
free;
TupleDesc
tupdesc;
HeapTuple *vals;
} SPITupleTable;

/*
/*
/*
/*
/*

contexte mmoire de la table de rsultat */


nombre de valeurs alloues */
nombre de valeurs libres */
descripteur de ranges */
ranges */
807

Interface de programmation serveur

vals est un tableau de pointeurs vers des lignes (le nombre d'entres valables est donn par SPI_processed). tupdesc est
un descripteur de ligne que vous pouvez passer aux fonctions SPI qui traitent des lignes. tuptabcxt, alloced et free sont
des champs internes non conus pour tre utiliss par des routines SPI appelantes.
SPI_finish libre tous les SPITupleTables alloues pendant la procdure courante. Vous pouvez librer une table de rsultats
donne plus tt, si vous en avez termin avec elle, en appelant SPI_freetuptable.

Arguments
const char * command
chane contenant la commande excuter
bool read_only
true en cas d'excution en lecture seule
long count
nombre maximum de lignes traiter ou 0 pour aucune limite

Valeur de retour
Si l'excution de la commande a russi, alors l'une des valeurs (positives) suivantes sera renvoye :
SPI_OK_SELECT
si un SELECT (mais pas SELECT INTO) a t lanc
SPI_OK_SELINTO
si un SELECT INTO a t lanc
SPI_OK_INSERT
si un INSERT a t lanc
SPI_OK_DELETE
si un DELETE a t lanc
SPI_OK_UPDATE
si un UPDATE a t lanc
SPI_OK_INSERT_RETURNING
si un INSERT RETURNING a t lanc
SPI_OK_DELETE_RETURNING
si un DELETE RETURNING a t lanc
SPI_OK_UPDATE_RETURNING
si un UPDATE RETURNING a t lanc
SPI_OK_UTILITY
si une commande utilitaire (c'est--dire CREATE TABLE) a t lance
SPI_OK_REWRITTEN
si la commande a t rcrite dans un autre style de commande (c'est--dire que UPDATE devient un INSERT) par une
rgle.
Sur une erreur, l'une des valeurs ngatives suivante est renvoye :
SPI_ERROR_ARGUMENT
si command est NULL ou count est infrieur 0
SPI_ERROR_COPY
si COPY TO stdout ou COPY FROM stdin ont t tents
SPI_ERROR_TRANSACTION
Si une commande de manipulation de transaction a t tente (BEGIN, COMMIT, ROLLBACK, SAVEPOINT, PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED ou toute variante de ces dernires)
SPI_ERROR_OPUNKNOWN
si le type de commande est inconnu (ce qui ne devrait pas arriver)

808

Interface de programmation serveur

SPI_ERROR_UNCONNECTED
si appel partir d'une procdure non connecte

Notes
Toutes les fonctions d'excution de requtes SPI changent la fois SPI_processed et SPI_tuptable (juste le pointeur, pas
le contenu de la structure). Sauvegardez ces deux variables globales dans des variables locales de procdures si vous voulez accder la table des rsultats de SPI_execute ou d'une fonction d'excution de requtes sur plusieurs appels.

809

Interface de programmation serveur

Nom
SPI_exec excute une commande en lecture/criture

Synopsis
int SPI_exec(const char * command, long count)

Description
SPI_exec est identique SPI_execute, mais le paramtre read_only de ce dernier est bloqu sur la valeur false.

Arguments
const char * command
chane contenant la commande excuter
long count
nombre maximum de lignes renvoyer ou 0 pour aucune limite

Valeur de retour
Voir SPI_execute.

810

Interface de programmation serveur

Nom
SPI_execute_with_args excute une commande avec des paramtres hors ligne

Synopsis
int SPI_execute_with_args(const char *command,
int nargs, Oid *argtypes,
Datum *values, const char *nulls,
bool read_only, long count)

Description
SPI_execute_with_args excute une commande qui pourrait inclure des rfrences des paramtres fournis en externe. Le
texte de commande fait rfrence un paramtre avec $n et l'appel spcifie les types et valeurs des donnes pour chaque symbole
de ce type. read_only et count ont la mme interprtation que dans SPI_execute.
Le principal avantage de cette routine compar SPI_execute est que les valeurs de donnes peuvent tre insres dans la
commande sans mise entre guillemets et chappements, et donc avec beaucoup moins de risques d'attaques du type injection SQL.
Des rsultats similaires peuvent tre raliss avec SPI_prepare suivi par SPI_execute_plan ; nanmoins, lors de
l'utilisation de cette fonction, le plan de requte est personnalis avec les valeurs de paramtres spcifiques fournies. Pour une excution simple, cette fonction doit tre prfre. Si la mme commande doit tre excute avec plusieurs paramtres diffrents,
chaque mthode peut tre la plus rapide, le cot de la planification pouvant contre-balancer les bnfices des plans personnaliss.

Arguments
const char * command
chane de commande
int nargs
nombre de paramtres en entre ($1, $2, etc.)
Oid * argtypes
un tableau contenant les OID des types de donnes des paramtres
Datum * values
un tableau des valeurs relles des paramtres
const char * nulls
un tableau dcrivant les paramtres NULL
Si nulls vaut NULL, alors SPI_execute_with_args suppose qu'aucun paramtre n'est NULL.
bool read_only
true pour les excutions en lecture seule
long count
nombre maximum de lignes renvoyer ou 0 pour aucune limite

Valeur de retour
La valeur de retour est identique celle de SPI_execute.
SPI_processed et SPI_tuptable sont configurs comme dans SPI_execute en cas de succs.

811

Interface de programmation serveur

Nom
SPI_prepare prpare un plan pour une commande sans l'excuter tout de suite

Synopsis
SPIPlanStr SPI_prepare(const char * command, int nargs, Oid * argtypes)

Description
SPI_prepare cre et retourne un plan d'excution pour la commande spcifie mais ne lance pas la commande. Cette fonction
ne peut tre appele que depuis une procdure connecte.
Lorsque la mme commande ou une commande semblable doit tre lance plusieurs reprises, il peut tre intressant de ne faire
la planification que d'une seule fois. SPI_prepare convertit une chane de commande en un plan d'excution qui peut tre lanc
plusieurs fois en utilisant SPI_executeplan.
Une commande prpare peut tre gnralise en utilisant les paramtres ($1, $2, etc.) en lieu et place de ce qui serait des
constantes dans une commande normale. Les valeurs actuelles des paramtres sont alors spcifies lorsque SPI_executeplan
est appele. Ceci permet la commande prpare d'tre utilise sur une plage plus grande de situations que cela ne serait possible
sans paramtres.
Le plan renvoy par SPI_prepare ne peut tre utilis que dans l'invocation courante de la procdure puisque SPI_finish libre la mmoire alloue pour le plan. Mais un plan peut tre sauvegard plus longtemps par l'utilisation de la fonction
SPI_saveplan.

Arguments
const char * command
chane contenant la commande planifier
int nargs
nombre de paramtres d'entre ($1, $2, etc.)
Oid * argtypes
pointeur vers un tableau contenant les OID des types de donnes des paramtres

Valeurs de retour
SPI_prepare retourne un pointeur non nul vers un plan d'excution. En cas d'erreur, NULL sera retourn et SPI_result sera positionne un des mmes codes d'erreur utiliss par SPI_execute sauf qu'il est positionn SPI_ERROR_ARGUMENT
si command est NULL ou si nargs est infrieur 0 ou si nargs est suprieur 0 et typesargs est NULL.

Notes
SPIPlanPtr est dclar comme un pointeur vers un type de structure opaque dans spi.h. Il est dconseill d'essayer d'accder
son contenu directement car cela rend votre code plus fragile aux futures versions de PostgreSQL.
Il y a un inconvnient utiliser les paramtres : puisque le planificateur ne connat pas les valeurs qui seront utilises pour les paramtres, il effectuera des choix pires que ceux qu'il prendrait pour une commande normale avec toutes les constantes visibles.

812

Interface de programmation serveur

Nom
SPI_prepare_cursor prpare un plan pour une commande, sans l'excuter pour l'instant

Synopsis
SPIPlanPtr SPI_prepare_cursor(const char * command, int nargs, Oid * argtypes, int
cursorOptions)

Description
SPI_prepare_cursor est identique SPI_prepare, sauf qu'il permet aussi la spcification du paramtre des options du
curseur du planificateur. Il s'agit d'un champ de bits dont les valeurs sont indiques dans nodes/parsenodes.h pour le
champ options de DeclareCursorStmt. SPI_prepare utilise zro pour les options du curseur.

Arguments
const char * command
chane commande
int nargs
nombre de paramtres en entre ($1, $2, etc.)
Oid * argtypes
pointeur vers un tableau contenant l'OID des types de donnes des paramtres
int cursorOptions
champ de bits prcisant les options du curseur ; zro est le comportement par dfaut

Valeur de retour
SPI_prepare_cursor a les mmes conventions pour la valeur de retour que SPI_prepare.

Notes
Les bits utiles pour cursorOptions incluent CURSOR_OPT_SCROLL, CURSOR_OPT_NO_SCROLL et CURSOR_OPT_FAST_PLAN. Notez en particulier que CURSOR_OPT_HOLD est ignor.

813

Interface de programmation serveur

Nom
SPI_prepare_params prpare un plan pour une commande, mais sans l'excuter

Synopsis
SPIPlanPtr SPI_prepare_params(const char * command,
ParserSetupHook parserSetup,
void * parserSetupArg,
int cursorOptions)

Description
SPI_prepare_params cre et renvoie un plan d'excution pour la commande indique mais n'excute pas la commande. Cette
fonction est quivalente SPI_prepare_cursor avec en plus le fait que l'appelant peut indiquer des fonctions pour contrler
l'analyse de rfrences de paramtres externes.

Arguments
const char * command
chane correspondant la commande
ParserSetupHook parserSetup
fonction de configuration de l'analyseur
void * parserSetupArg
argument pass parserSetup
int cursorOptions
masque de bits des options du curseur, sous la forme d'un entier ; zro indique le comportement par dfaut

Code de retour
SPI_prepare_params a les mmes conventions de retour que SPI_prepare.

814

Interface de programmation serveur

Nom
SPI_getargcount renvoie le nombre d'arguments ncessaires au plan prpar par SPI_prepare

Synopsis
int SPI_getargcount(SPIPlanPtr plan)

Description
SPI_getargcount renvoie le nombre d'arguments ncessaires pour excuter un plan prpar par SPI_prepare.

Arguments
SPIPlanPtr plan
plan d'excution (renvoy par SPI_prepare)

Code de retour
Le nombre d'arguments attendus par le plan. Si plan est NULL ou invalide, SPI_result est initialis
SPI_ERROR_ARGUMENT et -1 est renvoy.

815

Interface de programmation serveur

Nom
SPI_getargtypeid renvoie l'OID du type de donnes pour un argument du plan prpar par SPI_prepare

Synopsis
Oid SPI_getargtypeid(SPIPlanPtr plan, int argIndex)

Description
SPI_getargtypeid renvoie l'OID reprsentant le type pour le argIndex-ime argument d'un plan prpar par
SPI_prepare. Le premier argument se trouve l'index zro.

Arguments
SPIPlanPtr plan
plan d'excution (renvoy par SPI_prepare)
int argIndex
index de l'argument ( partir de zro)

Code de retour
L'OID du type de l'argument l'index donn. Si le plan est NULL ou invalide, ou argIndex infrieur 0 ou pas moins que le
nombre d'arguments dclar pour le plan, SPI_result est initialis SPI_ERROR_ARGUMENT et InvalidOid est renvoy.

816

Interface de programmation serveur

Nom
SPI_is_cursor_plan renvoie true si le plan prpar par SPI_prepare peut tre utilis avec SPI_cursor_open

Synopsis
bool SPI_is_cursor_plan(SPIPlanPtr plan)

Description
SPI_is_cursor_plan renvoie true si un plan prpar par SPI_prepare peut tre pass comme un argument
SPI_cursor_open ou false si ce n'est pas le cas. Les critres sont que le plan reprsente une seule commande et que cette
commande renvoit des lignes l'appelant ; par l'exemple, SELECT est autoris sauf s'il contient une clause INTO et UPDATE
est autoris seulement s'il contient un RETURNING

Arguments
SPIPlanPtr plan
plan d'excution (renvoy par SPI_prepare)

Return Value
true ou false pour indiquer si plan peut produire un curseur ou non, avec SPI_result initialis zro. S'il nest pas possible de
dterminer la rponse (par exemple, si le plan vaut NULL ou est invalide, ou s'il est appel en tant dconnect de SPI), alors
SPI_result est configur avec un code d'erreur convenable et false est renvoy.

817

Interface de programmation serveur

Nom
SPI_execute_plan excute un plan prpar par SPI_prepare

Synopsis
int SPI_execute_plan(SPIPlanPtr plan, Datum * values, const char * nulls, bool
read_only, long count)

Description
SPI_execute_plan excute un plan prpar par SPI_prepare. read_only et count ont la mme interprtation que
dans SPI_execute.

Arguments
SPIPlanPtr plan
plan d'excution (retourn par SPI_prepare)
Datum *values
Un tableau des vraies valeurs des paramtres. Doit avoir la mme longueur que le nombre d'arguments du plan.
const char * nulls
Un tableau dcrivant les paramtres nuls. Doit avoir la mme longueur que le nombre d'arguments du plan. n indique une valeur NULL (l'entre correspondante dans values sera ignore) ; un espace indique une valeur non NULL (l'entre correspondante dans values est valide).
Si nulls est NULL, alors SPI_executeplan part du principe qu'aucun paramtre n'est nul.
bool read_only
true pour une excution en lecture seule
long count
nombre maximum de lignes renvoyer ou 0 pour aucune ligne renvoyer

Valeur de retour
La valeur de retour est la mme que pour SPI_execute avec les rsultats d'erreurs (ngatif) possibles :
SPI_ERROR_ARGUMENT
si plan est NULL ou invalide ou count est infrieur 0
SPI_ERROR_PARAM
si values est NULL et plan est prpar avec des paramtres
SPI_processed et SPI_tuptable sont positionns comme dans SPI_execute en cas de russite.

818

Interface de programmation serveur

Nom
SPI_execute_plan_with_paramlist excute un plan prpar par SPI_prepare

Synopsis
int SPI_execute_plan_with_paramlist(SPIPlanPtr plan,
ParamListInfo params,
bool read_only,
long count)

Description
SPI_execute_plan_with_paramlist excute un plan prpar par SPI_prepare. Cette fonction est l'quivalent de
SPI_execute_plan, sauf que les informations sur les valeurs des paramtres passer la requte sont prsentes diffremment. La reprsentation ParamListInfo peut tre utilse pour passer des valeurs qui sont dj disponibles dans ce format. Elle
supporte aussi l'utilisation d'ensemble de paramtres dynamiques indiqus via des fonctions dans ParamListInfo.

Arguments
SPIPlanPtr plan
plan d'excution (renvoy par SPI_prepare)
ParamListInfo params
structure de donnes contenant les types et valeurs de paramtres ; NULL si aucune structure
bool read_only
true pour une excution en lecture seule
long count
nombre maximum de lignes renvoyer ou 0 pour aucune ligne renvoyer

Code de retour
La valeur de retour est identique celle de SPI_execute_plan.
SPI_processed et SPI_tuptable sont initialiss de la mme faon que pour SPI_execute_plan en cas de russite.

819

Interface de programmation serveur

Nom
SPI_execp excute un plan en mode lecture/criture

Synopsis
int SPI_execp(SPIPlanPtr plan, Datum * values, const char * nulls, long count)

Description
SPI_execp est identique SPI_execute_plan mais le paramtre read_only de ce dernier vaut toujours false.

Arguments
SPIPlanPtr plan
plan d'excution (renvoy par SPI_prepare)
Datum * values
Un tableau des vraies valeurs de paramtre. Doit avoir la mme longueur que le nombre d'arguments du plan.
const char * nulls
Un tableau dcrivant les paramtres NULL. Doit avoir la mme longueur que le nombre d'arguments du plan. n indique une
valeur NULL (l'entre dans values sera ignore) ; un espace indique une valeur non NULL (l'entre dans values est valide).
Si nulls est NULL, alors SPI_execp suppose qu'aucun paramtre n'est NULL.
long count
nombre maximum de lignes renvoyer ou 0 pour aucune ligne renvoyer

Valeur de retour
Voir SPI_execute_plan.
SPI_processed et SPI_tuptable sont initialises comme dans SPI_execute en cas de succs.

820

Interface de programmation serveur

Nom
SPI_cursor_open met en place un curseur en utilisant un plan cr avec SPI_prepare

Synopsis
Portal SPI_cursor_open(const char * name, SPIPlanPtr plan,
Datum * values, const char * nulls,
bool read_only)

Description
SPI_cursor_open met en place un curseur (en interne, un portail) qui lancera un plan prpar par SPI_prepare. Les paramtres ont la mme signification que les paramtres correspondant SPI_execute_plan.
Utiliser un curseur au lieu de lancer le plan directement a deux avantages. Premirement, les lignes de rsultats peuvent tre rcupres un certain nombre la fois, vitant la saturation de mmoire pour les requtes qui retournent trop de lignes. Deuximement,
un portail peut survivre la procdure courante (elle peut, en fait, vivre jusqu' la fin de la transaction courante). Renvoyer le nom
du portail l'appelant de la procdure donne un moyen de retourner une srie de ligne en tant que rsultat.
Les donnes passes seront copies dans le portail du curseur, donc il peut tre libr alors que le curseur existe toujours.

Arguments
const char * name
nom pour le portail ou NULL pour laisser le systme choisir un nom
SPIPlanPtr plan
plan d'excution (retourn par SPI_prepare)
Datum * values
Un tableau des valeurs de paramtres actuelles. Doit avoir la mme longueur que le nombre d'arguments du plan.
const char *nulls
Un tableau dcrivant quels paramtres sont NULL. Doit avoir la mme longueur que le nombre d'arguments du plan. n indique une valeur NULL (l'entre correspondante dans values sera ignore) ; un espace indique une valeur non NULL
(l'entre correspondante dans values est valide).
Si nulls est NULL, alors SPI_cursor_open part du principe qu'aucun paramtre n'est nul.
bool read_only
true pour les excutions en lecture seule

Valeur de retour
Pointeur vers le portail contenant le curseur. Notez qu'il n'y a pas de convention pour le renvoi d'une erreur ; toute erreur sera rapporte via elog.

821

Interface de programmation serveur

Nom
SPI_cursor_open_with_args ouvre un curseur en utilisant une requte et des paramtres

Synopsis
Portal SPI_cursor_open_with_args(const char *name,
const char *command,
int nargs, Oid *argtypes,
Datum *values, const char *nulls,
bool read_only, int cursorOptions)

Description
SPI_cursor_open_with_args initialise un curseur (en interne, un portail) qui excutera la requte spcifi. La plupart des
paramtres ont la mme signification que les paramtres correspondant de SPI_prepare_cursor et SPI_cursor_open.
Pour une excution seule, cette fonction sera prfre SPI_prepare_cursor suivie de SPI_cursor_open. Si la mme
commande doit tre excute avec plusieurs paramtres diffrents, il n'y a pas de diffrences sur les deux mthode, la replanification a un cot mais bnficie de plans personnaliss.
Les donnes passes seront copies dans le portail du curseur, donc elles seront libres alors que le curseur existe toujours.

Arguments
const char * name
nom du portail, ou NULL pour que le systme slectionne un nom de lui-mme
const char * command
chane de commande
int nargs
nombre de paramtres en entre ($1, $2, etc.)
Oid * argtypes
un tableau contenant les OID des types de donnes des paramtres
Datum * values
un tableau des valeurs actuelles des paramtres
const char * nulls
un tableau dcrivant les paramtres NULL
Si nulls vaut NULL, alors SPI_cursor_open_with_args suppose qu'aucun paramtre n'est NULL.
bool read_only
true pour une excution en lecture seule
int cursorOptions
masque de bits des options du curseur : zro cause le comportement par dfaut

Valeur de retour
Pointeur du portail contenant le curseur. Notez qu'il n'y a pas de convention pour le renvoi des erreurs ; toute erreur sera rapporte
par elog.

822

Interface de programmation serveur

Nom
SPI_cursor_open_with_paramlist ouvre un curseur en utilisant les paramtres

Synopsis
Portal SPI_cursor_open_with_paramlist(const char *name,
SPIPlanPtr plan,
ParamListInfo params,
bool read_only)

Description
SPI_cursor_open_with_paramlist prpare un curseur (en interne un portail), qui excutera un plan prpar par
SPI_prepare. Cette fonction est quivalente SPI_cursor_open sauf que les informations sur les valeurs des paramtres
passes la requte sont prsentes diffremment. La reprsentation de ParamListInfo peut tre utile pour fournir des valeurs
dj disponibles dans ce format. Elle supporte aussi l'utilisation d'ensemble de paramtres dynamiques via des fonctions spcifies
dans ParamListInfo.
Les donnes passes en paramtre seront copies dans le portail du curseur et peuvent donc tre libres alors que le curseur existe
toujours.

Arguments
const char * name
nom d'un portail ou NULL pour que le systme en choisisse un lui-mme
SPIPlanPtr plan
plan d'excution (renvoy par SPI_prepare)
ParamListInfo params
structure de donnes contenant les types et valeurs de paramtres ; NULL sinon
bool read_only
true pour une excution en lecture seule

Valeur de retour
Pointeur vers le portail contenant le curseur. Notez qu'il n'existe pas de convention pour le retour d'erreur ; toute erreur sera renvoye via elog.

823

Interface de programmation serveur

Nom
SPI_cursor_find recherche un curseur existant par nom

Synopsis
Portal SPI_cursor_find(const char * name)

Description
SPI_cursor_find recherche un portail par nom. Ceci est principalement utile pour rsoudre un nom de curseur renvoy en
tant que texte par une autre fonction.

Arguments
const char * name
nom du portail

Valeur de retour
Pointeur vers le portail portant le nom spcifi ou NULL si aucun n'a t trouv

824

Interface de programmation serveur

Nom
SPI_cursor_fetch extrait des lignes partir d'un curseur

Synopsis
void SPI_cursor_fetch(Portal portal, bool forward, long count)

Description
SPI_cursor_fetch extrait des lignes partir d'un curseur. Ceci est quivalent un sous-ensemble de la commande SQL
FETCH (voir SPI_scroll_cursor_fetch pour plus de dtails).

Arguments
Portal portal
portail contenant le curseur
bool forward
vrai pour une extraction en avant, faux pour une extraction en arrire
long count
nombre maximum de lignes rcuprer

Valeur de retour
SPI_processed et SPI_tuptable sont positionns comme dans SPI_execute en cas de russite.

Notes
Rcuprer en sens inverse pourrait chouer si le plan du curseur n'tait pas cr avec l'option CURSOR_OPT_SCROLL.

825

Interface de programmation serveur

Nom
SPI_cursor_move dplace un curseur

Synopsis
void SPI_cursor_move(Portal portal, bool forward, long count)

Description
SPI_cursor_move saute un certain nombre de lignes dans un curseur. Ceci est quivalent un sous-ensemble de la commande
SQL MOVE (voir SPI_scroll_cursor_move pour plus de dtails).

Arguments
Portal portal
portail contenant le curseur
bool forward
vrai pour un saut en avant, faux pour un saut en arrire
long count
nombre maximum de lignes dplacer

Notes
Se dplacer en sens inverse pourrait chouer si le plan du curseur n'a pas t cr avec l'option CURSOR_OPT_SCROLL option.

826

Interface de programmation serveur

Nom
SPI_scroll_cursor_fetch rcupre quelques lignes partir d'un curseur

Synopsis
void SPI_scroll_cursor_fetch(Portal portal, FetchDirection direction, long count)

Description
SPI_scroll_cursor_fetch rcupre quelques lignes partir d'un curseur. C'est quivalent la commande SQL FETCH.

Arguments
Portal portal
portail contenant le curseur
FetchDirection direction
un parmi FETCH_FORWARD, FETCH_BACKWARD, FETCH_ABSOLUTE ou FETCH_RELATIVE
long count
nombre de lignes rcuprer pour FETCH_FORWARD ou FETCH_BACKWARD ; nombre de lignes absolu rcuprer
pour FETCH_ABSOLUTE ; ou nombre de lignes relatif rcuprer pour FETCH_RELATIVE

Valeur de retour
SPI_processed et SPI_tuptable sont configurs comme SPI_execute en cas de succs.

Notes
Voir la commande SQL FETCH(7) pour des dtails sur l'interprtation des paramtres direction et count.
Les valeurs de direction autres que FETCH_FORWARD peuvent chouer si le plan du curseur n'a pas t cr avec l'option CURSOR_OPT_SCROLL.

827

Interface de programmation serveur

Nom
SPI_scroll_cursor_move dplacer un curseur

Synopsis
void SPI_scroll_cursor_move(Portal portal, FetchDirection direction, long count)

Description
SPI_scroll_cursor_move ignore un certain nombre de lignes dans un curseur. C'est l'quivalent de la commande SQL
MOVE.

Arguments
Portal portal
portail contenant le curseur
FetchDirection direction
un parmi FETCH_FORWARD, FETCH_BACKWARD, FETCH_ABSOLUTE et FETCH_RELATIVE
long count
nombre de lignes dplacer pour FETCH_FORWARD ou FETCH_BACKWARD ; nombre de lignes absolu dplacer pour
FETCH_ABSOLUTE ; ou nombre de lignes relatif dplacer pour FETCH_RELATIVE

Valeur de retour
SPI_processed est configur comme SPI_execute en cas de succs. SPI_tuptable est configur NULL car aucune
ligne n'est renvoye par cette fonction.

Notes
Voir la commande SQL FETCH(7) pour des dtails sur l'interprtation des paramtres direction et count.
Les valeurs de direction autres que FETCH_FORWARD peuvent chouer si le plan du curseur n'a pas t cr avec l'option CURSOR_OPT_SCROLL.

828

Interface de programmation serveur

Nom
SPI_cursor_close ferme un curseur

Synopsis
void SPI_cursor_close(Portal portal)

Description
SPI_cursor_close ferme un curseur cr prcdemment et libre la mmoire du portail.
Tous les curseurs ouverts sont ferms automatiquement la fin de la transaction. SPI_cursor_close n'a besoin d'tre invoqu
que s'il est dsirable de librer les ressources plus tt.

Arguments
Portal portal
portail contenant le curseur

829

Interface de programmation serveur

Nom
SPI_saveplan sauvegarde un plan

Synopsis
SPIPlanPtr SPI_saveplan(SPIPlanPtr plan)

Description
SPI_saveplan sauvegarde un plan valid (prpar par SPI_prepare) dans une zone de mmoire qui ne sera pas libre par
SPI_finish et par le gestionnaire de transactions et retourne le pointeur vers le plan sauvegard. Ceci vous donne la possibilit
de rutiliser les plans prpars lors des invocations suivantes de votre procdure dans la session courante.

Arguments
SPIPlanPtr plan
le plan sauvegarder

Valeur de retour
Pointeur vers le plan sauvegard ; NULL en cas d'chec. En cas d'erreur, SPI_result est positionne comme suit :
SPI_ERROR_ARGUMENT
si plan est NULL ou invalide
SPI_ERROR_UNCONNECTED
si appel d'une procdure non connecte

Notes
Le plan pass n'est pas libr, donc vous pouvez souhaiter excuter SPI_freeplan sur ce dernier pour viter des pertes mmoire jusqu' SPI_finish.
Si l'un des objets (une table, une fonction, etc.) rfrencs par le plan prpar est supprim ou redfini, alors les excutions futures
de SPI_execute_plan pourrait chouer ou renvoyer des rsultats diffrents de ce que le plan indique initialement.

43.2. Fonctions de support d'interface


Les fonctions dcrites ici donnent une interface pour extraire les informations des sries de rsultats renvoys par SPI_execute
et les autres fonctions SPI.
Toutes les fonctions dcrites dans cette section peuvent tre utilises par toutes les procdures, connectes et non connectes.

830

Interface de programmation serveur

Nom
SPI_fname dtermine le nom de colonne pour le numro de colonne spcifi

Synopsis
char * SPI_fname(TupleDesc rowdesc, int colnumber)

Description
SPI_fname retourne une copie du nom de colonne d'une colonne spcifie (vous pouvez utiliser pfree pour librer la copie du
nom lorsque vous n'en avez plus besoin).

Arguments
TupleDesc rowdesc
description de range d'entre
int colnumber
nombre de colonne (le compte commence 1)

Valeur de retour
Le nom de colonne ; NULL si colnumber est hors de porte. SPI_result est positionne SPI_ERROR_NOATTRIBUTE
en cas d'chec.

831

Interface de programmation serveur

Nom
SPI_fnumber dtermine le numro de colonne pour le nom de colonne spcifie

Synopsis
int SPI_fnumber(TupleDesc rowdesc, const char * colname)

Description
SPI_fnumber renvoie le numro de colonne pour la colonne portant le nom spcifi.
Si colname rfre une colonne systme (c'est--dire oid), alors le numro de colonne ngatif appropri sera renvoy.
L'appelant devra faire attention tester la valeur de retour pour galit exacte SPI_ERROR_NOATTRIBUTE pour dtecter une
erreur ; tester le rsultat pour une valeur infrieure ou gale 0 n'est pas correcte sauf si les colonnes systmes doivent tre rejetes.

Arguments
TupleDesc rowdesc
description de la range d'entre
const char * colname
nom de colonne

Valeur de retour
Numro de colonne (le compte commence 1) ou SPI_ERROR_NOATTRIBUTE si la colonne nomme n'est trouve.

832

Interface de programmation serveur

Nom
SPI_getvalue renvoie la valeur de chane de la colonne spcifie

Synopsis
char * SPI_getvalue(HeapTuple row, TupleDesc rowdesc, int colnumber)

Description
SPI_getvalue retourne la reprsentation chane de la valeur de la colonne spcifie.
Le rsultat est retourn en mmoire alloue en utilisant palloc (vous pouvez utiliser pfree pour librer la mmoire lorsque
vous n'en avez plus besoin).

Arguments
HeapTuple row
ligne d'entre examiner
TupleDesc rowdesc
description de la ligne en entre
int colnumber
numro de colonne (le compte commence 1)

Valeur de retour
Valeur de colonne ou NULL si la colonne est NULL, si colnumber est hors de porte (SPI_result est positionne
SPI_ERROR_NOATTRIBUTE) ou si aucune fonction de sortie n'est disponible (SPI_result est positionne
SPI_ERROR_NOOUTFUNC).

833

Interface de programmation serveur

Nom
SPI_getbinval retourne la valeur binaire de la colonne spcifie

Synopsis
Datum SPI_getbinval(HeapTuple row, TupleDesc rowdesc, int colnumber, bool * isNULL)

Description
SPI_getbinval retourne la valeur de la colonne spcifie dans le format interne (en tant que type Datum).
Cette fonction n'alloue pas de nouvel espace pour le datum. Dans le cas d'un type de donnes pass par rfrence, la valeur de retour sera un pointeur dans la ligne passe.

Arguments
HeapTuple row
ligne d'entre examiner
TupleDesc rowdesc
description de la ligne d'entre
int colnumber
numro de colonne (le compte commence 1)
bool * isNULL
indique une valeur NULL dans la colonne

Valeur de retour
La valeur binaire de la colonne est retourne. La variable vers laquelle pointe isNULL est positionne vrai si la colonne est
NULL et sinon faux.
SPI_result est positionne SPI_ERROR_NOATTRIBUTE en cas d'erreur.

834

Interface de programmation serveur

Nom
SPI_gettype retourne le nom du type de donne de la colonne spcifie

Synopsis
char * SPI_gettype(TupleDesc rowdesc, int colnumber)

Description
SPI_gettype retourne une copie du nom du type de donne de la colonne spcifie (vous pouvez utiliser pfree pour librer la
copie du nom lorsque vous n'en avez plus besoin).

Arguments
TupleDesc rowdesc
description de ligne d'entre
int colnumber
numro de colonne (le compte commence 1)

Valeur de retour
Le nom de type de donne de la colonne spcifie ou NULL en cas d'erreur. SPI_result est positionne
SPI_ERROR_NOATTRIBUTE en cas d'erreur.

835

Interface de programmation serveur

Nom
SPI_gettypeid retourne l'OID de type de donne de la colonne spcifie

Synopsis
Oid SPI_gettypeid(TupleDesc rowdesc, int colnumber)

Description
SPI_gettypeid retourne l'OID du type de donne de la colonne spcifie.

Arguments
TupleDesc rowdesc
description de ligne d'entre
int colnumber
numro de colonne (le compte commence 1)

Valeur de retour
L'OID du type de donne de la colonne spcifie ou InvalidOid en cas d'erreur. En cas d'erreur, SPI_result est positionne
SPI_ERROR_NOATTRIBUTE.

836

Interface de programmation serveur

Nom
SPI_getrelname retourne le nom de la relation spcifie

Synopsis
char * SPI_getrelname(Relation rel)

Description
SPI_getrelname retourne une copie du nom de la relation spcifie (vous pouvez utiliser pfree pour librer la copie du nom
lorsque vous n'en avez plus besoin).

Arguments
Relation rel
relation d'entre

Valeur de retour
Le nom de la relation spcifie.

837

Interface de programmation serveur

Nom
SPI_getnspname renvoie l'espace de noms de la relation spcifie

Synopsis
char * SPI_getnspname(Relation rel)

Description
SPI_getnspname renvoie une copie du nom de l'espace de nom auquel appartient la Relation spcifie. Ceci est quivalent au
schma de la relation. Vous devriez librer (pfree) la valeur de retour de cette fonction lorsque vous en avez fini avec elle.

Arguments
Relation rel
relation en entre

Valeur de retour
Le nom de l'espace de noms de la relation spcifie.

43.3. Gestion de la mmoire


PostgreSQL alloue de la mmoire dans des contextes mmoire qui donnent une mthode pratique pour grer les allocations
fates dans plusieurs endroits qui ont besoin de vivre pour des dures diffrentes. Dtruire un contexte libre toute la mmoire qui
y tait alloue. Donc, il n'est pas ncessaire de garder la trace des objets individuels pour viter les fuites de mmoire ; la place,
seul un petit nombre de contextes doivent tre grs. palloc et les fonctions lies allouent de la mmoire du contexte
courant .
SPI_connect cre un nouveau contexte mmoire et le rend courant. SPI_finish restaure le contexte mmoire prcdant et
dtruit le contexte cr par SPI_connect. Ces actions garantissent que les allocations temporaires de mmoire fates dans votre
procdure soient rclames lors de la sortie de la procdure, vitant les fuites de mmoire.
En revanche, si votre procdure a besoin de renvoyer un objet dans de la mmoire alloue (tel que la valeur d'un type de donn
pass par rfrence), vous ne pouvez pas allouer cette mmoire en utilisant palloc, au moins pas tant que vous tes connect
SPI. Si vous essayez, l'objet sera dsallou par SPI_finish et votre procdure ne fonctionnera pas de manire fiable. Pour rsoudre ce problme, utilisez SPI_palloc pour allouer de la mmoire pour votre objet de retour. SPI_palloc alloue de la mmoire dans le contexte de mmoire courant , c'est--dire le contexte de mmoire qui tait courant lorsque SPI_connect a t
appele, ce qui est prcisment le bon contexte pour une valeur renvoye partir de votre procdure.
Si SPI_palloc est appel pendant que la procdure n'est pas connecte SPI, alors il agit de la mme manire qu'un palloc
normal. Avant qu'une procdure ne se connecte au gestionnaire SPI, toutes les allocations fates par la procdure via palloc ou
par une fonction utilitaire SPI sont fates dans le contexte de mmoire courant.
Quand SPI_connect est appele, le contexte priv de la procdure, qui est cre par SPI_connect, est nomm le contexte
courant. Toute allocation fate par palloc, repalloc ou une fonction utilitaire SPI ( part pour SPI_copytuple,
SPI_returntuple, SPI_modifytuple, et SPI_palloc) sont fates dans ce contexte. Quand une procdure se dconnecte du gestionnaire SPI (via SPI_finish), le contexte courant est restaur au contexte de mmoire courant et toutes les allocations fates dans le contexte de mmoire de la procdure sont libres et ne peuvent plus tre utilises.
Toutes les fonctions couvertes dans cette section peuvent tre utilises par des procdures connectes comme non connectes.
Dans une procdure non connecte, elles agissent de la mme faon que les fonctions serveur sous-jacentes (palloc, etc.).

838

Interface de programmation serveur

Nom
SPI_palloc alloue de la mmoire dans le contexte de mmoire courant

Synopsis
void * SPI_palloc(Size size)

Description
SPI_palloc alloue de la mmoire dans le contexte de mmoire courant.

Arguments
Size size
taille en octets du stockage allouer

Valeur de retour
Pointeur vers le nouvel espace de stockage de la taille spcifie

839

Interface de programmation serveur

Nom
SPI_repalloc r-alloue de la mmoire dans le contexte de mmoire courant

Synopsis
void * SPI_repalloc(void * pointer, Size size)

Description
SPI_repalloc change la taille d'un segment de mmoire allou auparavant en utilisant SPI_palloc.
Cette fonction n'est plus diffrente du repalloc standard. Elle n'est garde que pour la compatibilit du code existant.

Arguments
void * pointer
pointeur vers l'espace de stockage modifier
Size size
taille en octets du stockage allouer

Valeur de retour
Pointeur vers le nouvel espace de stockage de taille spcifie avec le contenu copi de l'espace existant

840

Interface de programmation serveur

Nom
SPI_pfree libre de la mmoire dans le contexte de mmoire courant

Synopsis
void SPI_pfree(void * pointer)

Description
SPI_pfree libre de la mmoire alloue auparavant par SPI_palloc ou SPI_repalloc.
Cette fonction n'est plus diffrente du pfree standard. Elle n'est conserve que pour la compatibilit du code existant.

Arguments
void * pointer
pointeur vers l'espace de stockage librer

841

Interface de programmation serveur

Nom
SPI_copytuple effectue une copie d'une ligne dans le contexte de mmoire courant

Synopsis
HeapTuple SPI_copytuple(HeapTuple row)

Description
SPI_copytuple cre une copie d'une ligne dans le contexte de mmoire courant. Ceci est normalement utilis pour renvoyer
une ligne modifie partir d'un dclencheur. Dans une fonction dclare pour renvoyer un type composite, utilisez
SPI_returntuple la place.

Arguments
HeapTuple row
ligne copier

Valeur de retour
la ligne copie ; NULL seulement si row est NULL

842

Interface de programmation serveur

Nom
SPI_returntuple prpare le renvoi d'une ligne en tant que Datum

Synopsis
HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc rowdesc)

Description
SPI_returntuple cre une copie d'une ligne dans le contexte de l'excuteur suprieur, la renvoyant sous la forme d'une ligne
de type Datum. Le pointeur renvoy a seulement besoin d'tre converti en Datum via PointerGetDatum avant d'tre renvoy.
Notez que ceci devrait tre utilis pour les fonctions qui dclarent renvoyer des types composites. Ce n'est pas utilis pour les dclencheurs ; utilisez pour renvoyer une ligne modifie dans un dclencheur.

Arguments
HeapTuple row
ligne copier
TupleDesc rowdesc
descripteur pour la ligne (passez le mme descripteur chaque fois pour un cache plus efficace)

Valeur de retour
HeapTupleHeader pointant vers la ligne copie ; NULL seulement si row ou rowdesc est NULL

843

Interface de programmation serveur

Nom
SPI_modifytuple cre une ligne en remplaant les champs slectionns d'une ligne donne

Synopsis
HeapTuple SPI_modifytuple(Relation rel, HeapTuple row, ncols, colnumber, Datum *
values, const char * nulls)

Description
SPI_modifytuple cre une nouvelle ligne en retirant les nouvelles valeurs pour les colonnes slectionnes et en copiant les
colonnes de la ligne d'origine d'autres positions. La ligne d'entre n'est pas modifie.

Arguments
Relation rel
Utilis seulement en tant que source du descripteur de ligne pour la ligne (passez une relation plutt qu'un descripteur de ligne
est une erreur).
HeapTuple row
range modifier
int ncols
nombre de numros de colonnes dans le tableau colnumber
int * colnumber
tableau des numros de colonnes modifier (le numro des colonnes commence 1)
Datum * values
nouvelles valeurs pour les colonnes spcifies
const char * nulls
quelles nouvelles valeurs sont NULL, si elles existent (voir SPI_executeplan pour le format)

Valeur de retour
nouvelle ligne avec modifications, alloue dans le contexte de mmoire courant ; NULL seulement si row est NULL
En cas d'erreur, SPI_result est positionne comme suit :
SPI_ERROR_ARGUMENT
si rel est NULL ou si row est NULL ou si ncols est infrieur ou gal 0 ou si nocolonne est NULL ou si values est
NULL.
SPI_ERROR_NOATTRIBUTE
si nocolonne contient un numro de colonne invalide (infrieur ou gal 0 ou suprieur au numro de colonne dans row)

844

Interface de programmation serveur

Nom
SPI_freetuple libre une ligne alloue dans le contexte de mmoire courant

Synopsis
void SPI_freetuple(HeapTuple row)

Description
SPI_freetuple libre une range alloue auparavant dans le contexte de mmoire courant.
Cette fonction n'est plus diffrente du standard heap_freetuple. Elle est garde juste pour la compatibilit du code existant.

Arguments
HeapTuple row
range librer

845

Interface de programmation serveur

Nom
SPI_freetuptable libre une srie de lignes cre par SPI_execute ou une fonction semblable

Synopsis
void SPI_freetuptable(SPITupleTable * tuptable)

Description
SPI_freetuptable libre une srie de lignes cre auparavant par une fonction d'excution de commandes SPI, tel que
SPI_execute. Par consquent, cette fonction est souvent appele avec la variable globale SPI_tupletable comme argument.
Cette fonction est utile si une procdure SPI a besoin d'excuter de multiples commandes et ne veut pas garder les rsultats de
commandes prcdentes en mmoire jusqu' sa fin. Notez que toute srie de lignes non libres est libre quand mme lors de
SPI_finish.

Arguments
SPITupleTable * tuptable
pointeur vers la srie de lignes librer

846

Interface de programmation serveur

Nom
SPI_freeplan libre un plan sauvegard auparavant

Synopsis
int SPI_freeplan(SPIPlanPtr plan)

Description
SPI_freeplan libre un plan de commandes d'excution retourn auparavant par SPI_prepare ou sauvegard par
SPI_saveplan.

Arguments
SPIPlanPtr plan
pointeur vers le plan librer

Valeur de retour
SPI_ERROR_ARGUMENT si plan est NULL ou invalide.

43.4. Visibilit des modifications de donnes


Les rgles suivantes gouvernent la visibilit des modifications de donnes dans les fonctions qui utilisent SPI (ou tout autre fonction C) :

Pendant l'excution de la commande SQL, toute modification de donnes faite par la commande est invisible la commande.
Par exemple, dans la commande :
INSERT INTO a SELECT * FROM a;
les lignes insres sont invisibles la partie SELECT.

Les modifications effectues par une commande C sont visibles par toutes les commandes qui sont lances aprs C, peu importe qu'elles soient lances l'intrieur de C (pendant l'excution de C) ou aprs que C soit termine.

Les commandes excutes via SPI l'intrieur d'une fonction appele par une commande SQL (soit une fonction ordinaire soit
un dclencheur) suivent une des rgles ci-dessus suivant le commutateur lecture/criture pass SPI. Les commandes excutes en mode lecture seule suivent la premire rgle : elles ne peuvent pas voir les modifications de la commande appelante.
Les commandes excutes en mode lecture/criture suivent la deuxime rgle : elles peuvent voir toutes les modifications ralises jusqu' maintenant.

Tous les langages standards de procdures initialisent le mode lecture/criture suivant l'attribut de volatilit de la fonction. Les
commandes des fonctions STABLE et IMMUTABLE sont ralises en mode lecture seule alors que les fonctions VOLATILE
sont ralises en mode lecture/criture. Alors que les auteurs de fonctions C sont capables de violer cette convention, il est peu
probable que cela soit une bonne ide de le faire.

La section suivante contient un exemple qui illustre l'application de ces rgles.

43.5. Exemples
Cette section contient un exemple trs simple d'utilisation de SPI. La procdure execq prend une commande SQL comme premier argument et un compteur de lignes comme second, excute la commande en utilisant SPI_exec et renvoie le nombre de
lignes qui ont t traites par la commande. Vous trouverez des exemples plus complexes pour SPI dans l'arborescence source
dans src/test/regress/regress.c et dans le module spi.
#include "postgres.h"
#include "executor/spi.h"
#include "utils/builtins.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
847

Interface de programmation serveur

#endif
int execq(text *sql, int cnt);
int
execq(text *sql, int cnt)
{
char *command;
int ret;
int proc;
/* Convertir l'objet texte donn en chane C */
command = text_to_cstring(sql);
SPI_connect();
ret = SPI_exec(command, cnt);
proc = SPI_processed;
/*
* Si des lignes ont t rcupres,
* alors les afficher via elog(INFO).
*/
if (ret > 0 && SPI_tuptable != NULL)
{
TupleDesc tupdesc = SPI_tuptable->tupdesc;
SPITupleTable *tuptable = SPI_tuptable;
char buf[8192];
int i, j;
for (j = 0; j < proc; j++)
{
HeapTuple tuple = tuptable->vals[j];
for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)
snprintf(buf + strlen (buf), sizeof(buf) - strlen(buf), " %s%s",
SPI_getvalue(tuple, tupdesc, i),
(i == tupdesc->natts) ? " " : " |");
elog(INFO, "EXECQ: %s", buf);
}
}
SPI_finish();
pfree(command);
return (proc);
}
(Cette fonction utilisera la convention d'appel version 0 pour rendre l'exemple plus simple comprendre. Dans des applications
relles, vous devriez utiliser la nouvelle interface version 1.)
Voici comment dclarer la fonction aprs l'avoir compile en une bibliothque partage (les dtails sont dans Section 35.9.6,
Compiler et lier des fonctions charges dynamiquement ) :
CREATE FUNCTION execq(text, integer) RETURNS integer
AS 'filename'
LANGUAGE C;
Voici une session d'exemple :
=> SELECT execq('CREATE TABLE a (x integer)', 0);
execq
------0
(1 row)
=> INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)', 0));
INSERT 0 1
=> SELECT execq('SELECT * FROM a', 0);
INFO: EXECQ: 0
-- insr par execq
848

Interface de programmation serveur

INFO:

EXECQ:

-- retourn par execq et insr par l'INSERT prcdant

execq
------2
(1 row)
=> SELECT execq('INSERT INTO a SELECT x + 2 FROM a', 1);
execq
------1
(1 row)
=> SELECT execq('SELECT * FROM a', 10);
INFO: EXECQ: 0
INFO: EXECQ: 1
INFO: EXECQ: 2
-- 0 + 2, une seule ligne insre - comme spcifi
execq
------3
(1 row)

-- 10 est la valeur max seulement, 3 est le nombre rel de ranges

=> DELETE FROM a;


DELETE 3
=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
INSERT 0 1
=> SELECT * FROM a;
x
--1
-- aucune range dans a (0) + 1
(1 row)
=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
INFO: EXECQ: 1
INSERT 0 1
=> SELECT * FROM a;
x
--1
2
-- il y a une range dans a + 1
(2 rows)
-- Ceci montre la rgle de visibilit de modifications de donnes :
=> INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
INFO: EXECQ: 1
INFO: EXECQ: 2
INFO: EXECQ: 1
INFO: EXECQ: 2
INFO: EXECQ: 2
INSERT 0 2
=> SELECT * FROM a;
x
--1
2
2
-- 2 ranges * 1 (x dans la premire range)
6
-- 3 ranges (2 + 1 juste insre) * 2 (x dans la deuxime range)
(4 rows)
^^^^^^^
ranges visible execq() dans des invocations diffrentes

849

Partie VI. Rfrence


Les points abords dans ce rfrentiel ont pour objectif de fournir, de manire concise, un rsum prcis, complet, formel et faisant autorit sur leurs sujets respectifs. Des informations complmentaires sur l'utilisation de PostgreSQL sont prsentes, dans
d'autres parties de cet ouvrage, sous la forme de descriptions, de tutoriels ou d'exemples. On pourra se reporter la liste de rfrences croises disponible sur chaque page de rfrence.
Les entres du rfrentiel sont galement disponibles sous la forme de pages man traditionnelles.

Commandes SQL
Cette partie regroupe les informations de rfrence concernant les commandes SQL reconnues par PostgreSQL. Gnralement, on dsigne par SQL le langage ; toute information sur la structure et la compatibilit standard de chaque commande
peut tre trouve sur les pages rfrences.

851

Nom
ABORT Interrompre la transaction en cours

Synopsis
ABORT [ WORK | TRANSACTION ]

Description
ABORT annule la transaction en cours et toutes les mises jour effectues pendant cette transaction. Cette commande a un
comportement identique la commande SQL ROLLBACK(7). Elle n'est prsente que pour des raisons historiques.

Paramtres
WORK, TRANSACTION
Mots-cl optionnels. Ils n'ont aucun effet.

Notes
COMMIT(7) est utilis pour terminer avec succs une transaction.
Lancer ABORT l'extrieur de toute transaction ne cause aucun dgt, mais provoque un message d'avertissement.

Exemples
Annuler toutes les modifications :
ABORT;

Compatibilit
Cette commande est une extension PostgreSQL prsente pour des raisons historiques. ROLLBACK est la commande quivalente du standard SQL.

Voir aussi
BEGIN(7), COMMIT(7), ROLLBACK(7)

852

Nom
ALTER AGGREGATE Modifier la dfinition d'une fonction d'agrgat

Synopsis
ALTER AGGREGATE nom ( type [ , ... ] ) RENAME TO nouveau_nom
ALTER AGGREGATE nom ( type [ , ... ] ) OWNER TO nouveau_proprietaire
ALTER AGGREGATE nom ( type [ , ... ] ) SET SCHEMA nouveau_schema

Description
ALTER AGGREGATE change la dfinition d'une fonction d'agrgat.
Seul le propritaire de la fonction d'agrgat peut utiliser ALTER AGGREGATE. Pour modifier le schma d'une fonction
d'agrgat, il est ncessaire de possder le droit CREATE sur le nouveau schma. Pour modifier le propritaire de la fonction, il
faut tre un membre direct ou indirect du nouveau rle propritaire, rle qui doit en outre possder le droit CREATE sur le schma de la fonction d'agrgat. Ces restrictions assurent que la modification du propritaire ne permet pas d'aller au-del de ce que
permet la suppression et la recration d'une fonction d'agrgat. Toutefois, un superutilisateur peut modifier la possession de
n'importe quelle fonction d'agrgat.

Paramtres
nom
Le nom (ventuellement qualifi du nom du schma) de la fonction d'agrgat.
type
Un type de donnes en entre sur lequel la fonction d'agrgat opre. Pour rfrencer une fonction d'agrgat sans argument,
crivez * la place de la liste des types de donnes en entre.
nouveau_nom
Le nouveau nom de la fonction d'agrgat.
nouveau_propritaire
Le nouveau propritaire de la fonction d'agrgat.
nouveau_schema
Le nouveau schma de la fonction d'agrgat.

Exemples
Renommer la fonction d'agrgat mamoyenne de type integer en ma_moyenne :
ALTER AGGREGATE mamoyenne(integer) RENAME TO ma_moyenne;
Changer le propritaire de la fonction d'agrgat mamoyenne de type integer en joe :
ALTER AGGREGATE mamoyenne(integer) OWNER TO joe;
Dplacer la fonction d'agrgat mamoyenne du type integer dans le schma monschema :
ALTER AGGREGATE mamoyenne(integer) SET SCHEMA monschema;

Compatibilit
Il n'y a pas de commande ALTER AGGREGATE dans le standard SQL.

Voir aussi
CREATE AGGREGATE(7), DROP AGGREGATE(7)

853

Nom
ALTER COLLATION modifie la dfinition d'une collation

Synopsis
ALTER COLLATION nom RENAME TO nouveau_nom
ALTER COLLATION nom OWNER TO nouveau_propritaire
ALTER COLLATION nom SET SCHEMA nouveau_schma

Description
ALTER COLLATION modifie la dfinition d'une collation.
Pour pouvoir utiliser la commande ALTER COLLATION, vous devez tre propritaire de la collation. Pour en modifier le
propritaire, vous devez galement tre un membre direct ou indirect du nouveau rle propritaire, et ce rle doit dtenir le privilge CREATE sur le schma de la collation. (Ces restrictions ont pour effet que vous ne pouvez effectuer aucune modification
de propritaire qui serait impossible en supprimant et en recrant la collation. Cependant, un super-utilisateur peut modifier le
propritaire de n'importe quelle collation, quoi qu'il arrive.)

Paramtres
nom
Le nom (ventuellement prcd par le schma) d'une collation existante.
nouveau_nom
Le nouveau nom de la collation.
nouveau_propritaire
Le nouveau propritaire de la collation.
nouveau_schma
Le nouveau schma de la collation.

Exemples
Pour renommer la collation de_DE en german:
ALTER COLLATION "de_DE" RENAME TO german;
Pour donner la proprit de la collation en_US en joe:
ALTER COLLATION "en_US" OWNER TO joe;

Compatibilit
Il n'y a pas de commande ALTER COLLATION dans le standard SQL.

Voir galement
CREATE COLLATION(7), DROP COLLATION(7)

854

Nom
ALTER CONVERSION Modifier la dfinition d'une conversion

Synopsis
ALTER CONVERSION nom RENAME TO nouveau_nom
ALTER CONVERSION nom OWNER TO nouveau_propritaire
ALTER CONVERSION nom SET SCHEMA nouveau_schma

Description
ALTER CONVERSION modifie la dfinition d'une conversion.
Seul le propritaire de la conversion peut utiliser ALTER CONVERSION. Pour changer le propritaire, il faut aussi tre un
membre direct ou indirect du nouveau rle propritaire et ce rle doit avoir le droit CREATE sur le schma de la conversion. Ces
restrictions assurent que le changement de propritaire ne va pas au-del de ce qui peut tre obtenu en supprimant et en re-crant
la conversion. Toutefois, un superutilisateur peut changer le propritaire de n'importe quelle conversion.

Paramtres
nom
Le nom de la conversion.
nouveau_nom
Le nouveau nom de la conversion.
nouveau_propritaire
Le nouveau propritaire de la conversion.
nouveau_schma
Le nouveau schma de la conversion.

Exemples
Renommer la conversion iso_8859_1_to_utf8 en latin1_to_unicode :
ALTER CONVERSION iso_8859_1_to_utf8 RENAME TO latin1_to_unicode;
Changer le propritaire de la conversion iso_8859_1_to_utf8 en joe :
ALTER CONVERSION iso_8859_1_to_utf8 OWNER TO joe;

Compatibilit
Il n'y a pas d'instruction ALTER CONVERSION dans le standard SQL.

Voir aussi
CREATE CONVERSION(7), DROP CONVERSION(7)

855

Nom
ALTER DATABASE Modifier une base de donnes

Synopsis
ALTER DATABASE nom [ [ WITH ] option [ ... ] ]
o option peut tre :
CONNECTION LIMIT limite_connexion
ALTER DATABASE nom RENAME TO nouveau_nom
ALTER DATABASE nom OWNER TO nouveau_propritaire
ALTER DATABASE nom SET TABLESPACE nouveau_tablespace
ALTER
ALTER
ALTER
ALTER

DATABASE
DATABASE
DATABASE
DATABASE

nom
nom
nom
nom

SET paramtre { TO | = } { valeur | DEFAULT }


SET paramtre FROM CURRENT
RESET paramtre
RESET ALL

Description
ALTER DATABASE modifie les attributs d'une base de donnes.
La premire forme modifie certains paramtres d'une base de donnes (voir ci-dessous pour les dtails). Seul le propritaire de
la base de donnes ou un superutilisateur peut modifier ces paramtres.
La deuxime forme permet de renommer la base. Seul le propritaire ou un superutilisateur peut renommer une base. Un propritaire qui n'est pas superutilisateur doit en outre possder le droit CREATEDB. La base en cours d'utilisation ne peut pas tre
renomme (on se connectera une base diffrente pour raliser cette opration).
La troisime forme change le propritaire de la base de donnes. Pour changer le propritaire, il faut tre propritaire de la base
de donnes et membre direct ou indirect du nouveau rle propritaire. Le droit CREATEDB est galement requis (les superutilisateurs ont automatiquement tous ces droits).
La quatrime forme change le tablespace par dfaut de la base de donnes. Seuls le propritaire de la base de donnes et un superutilisateur peuvent le faire ; vous devez aussi avoir le droit CREATE pour le nouveau tablespace. Cette commande dplace
physiquement toutes tables et index actuellement dans l'ancien tablespace par dfaut de la base de donnes vers le nouveau tablespace. Notez que les tables et index placs dans d'autres tablespaces ne sont pas affects.
Les formes restantes modifient la valeur par dfaut d'un paramtre de configuration pour une base PostgreSQL. Par la suite,
chaque fois qu'une nouvelle session est lance, la valeur spcifique devient la valeur par dfaut de la session. Les valeurs par dfaut de la base deviennent les valeurs par dfaut de la session. En fait, elles surchargent tout paramtre prsent dans postgresql.conf ou indiqu sur la ligne de commande de postgres. Seul le propritaire de la base de donnes ou un superutilisateur peut modifier les valeurs par dfaut de la session pour une base. Certaines variables ne peuvent pas tre configures de cette
faon pour une base de donnes ou peuvent seulement tre configures par un superutilisateur.

Paramtres
nom
Le nom de la base dont les attributs sont modifier.
limite_connexion
Le nombre de connexions concurrentes sur la base de donnes. -1 signifie aucune limite.
nouveau_nom
Le nouveau nom de la base.
nouveau_propritaire
Le nouveau propritaire de la base.
nouveau_tablespace
Le nouveau tablespace par dfaut de la base de donnes.
paramtre, valeur
856

ALTER DATABASE

Configure cette valeur comme valeur par dfaut de la base pour le paramtre de configuration prcise. Si valeur indique
DEFAULT ou, de faon quivalente, si RESET est utilis, le paramtrage en cours pour cette base est supprime, donc la valeur systme est utilise pour les nouvelles sessions. Utiliser RESET ALL permet de supprimer tous les paramtres spcifiques de cette base. SET FROM CURRENT sauvegarde la valeur actuelle du paramtre en tant que valeur spcifique de la
base.
Voir SET(7) et Chapitre 18, Configuration du serveur pour plus d'informations sur les noms de paramtres et valeurs autorises.

Notes
Il est possible de lier une valeur de session par dfaut un rle plutt qu' une base. Voir ALTER ROLE(7) ce propos. En cas de
conflit, les configurations spcifiques au rle l'emportent sur celles spcifiques la base.

Exemples
Dsactiver les parcours d'index par dfaut de la base test :
ALTER DATABASE test SET enable_indexscan TO off;

Compatibilit
La commande ALTER DATABASE est une extension PostgreSQL.

Voir aussi
CREATE DATABASE(7), DROP DATABASE(7), SET(7), CREATE TABLESPACE(7)

857

Nom
ALTER DEFAULT PRIVILEGES dfinit les droits d'accs par dfaut

Synopsis
ALTER DEFAULT PRIVILEGES
[ FOR { ROLE | USER } cible_rle [, ...] ]
[ IN SCHEMA nom_schma [, ...] ]
grant_ou_revoke_rduit
where grant_ou_revoke_rduit is one of:
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
[, ...] | ALL [ PRIVILEGES ] }
ON TABLES
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { USAGE | SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON SEQUENCES
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTIONS
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
[, ...] | ALL [ PRIVILEGES ] }
ON TABLES
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ { USAGE | SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON SEQUENCES
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTIONS
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]

Description
ALTER DEFAULT PRIVILEGES vous permet de configurer les droits qui seront appliqus aux objets qui seront crs dans
le futur. (Cela ne modifie pas les droits affects des objets dj existants.) Actuellement, seuls les droits pour les tables (ceci
incluant les vues et les tables distantes), les squences et les fonctions peuvent tre modifis.
Vous pouvez modifier les droits par dfaut seulement pour les objets qui seront crs par vous ou par des rles dont vous tes
membres. Les droits peuvent tre configurs de manire globale (c'est--dire pour tous les objets de la base de donnes) ou pour
les objets des schmas indiqus. Les droits par dfaut spcifiques par schma sont ajouts aux droits par dfaut globaux pour le
type d'objet particulier.
Comme indiqu dans GRANT(7), les droits par dfaut de tout type d'objet donnent tous les droits au propritaire de l'objet et
peut aussi donner certains droits PUBLIC. Nanmoins, ce comportement peut tre chang par une modification des droits par
dfaut globaux avec ALTER DEFAULT PRIVILEGES.

Paramtres
cible_rle
858

ALTER DEFAULT PRIVILEGES

Le nom d'un rle existant dont le rle actuel est membre. Si FOR ROLE est omis, le rle courant est utilis.
nom_schma
Le nom d'un schma existant. S'il est indiqu, les droits par dfaut sont modifis pour les objets crs aprs coup dans ce
schma. Si IN SCHEMA est omis, les droits globaux par dfaut sont modifis.
nom_rle
Le nom d'un rle existant pour donner ou reprendre les droits. Ce paramtre, et tous les autres paramtres dans
grant_ou_revoke_rduit, agissent de la faon dcrite dans GRANT(7) ou REVOKE(7), sauf qu'un permet de configurer les droits pour une classe complte d'objets plutt que pour des objets nomms spcifiques.

Notes
Utilisez la commande \ddp de psql(1) pour otbenir des informations sur les droits par dfaut. La signification des valeurs de droit
est identique celles utilises par \dp et est expliqu dans GRANT(7).
Si vous souhaitez supprimer un rle dont les droits par dfaut ont t modifis, il est ncessaire d'inverser les modifications dans
ses droits par dfaut ou d'utiliser DROP OWNED BY pour supprimer l'entre des droits par dfaut pour le rle.

Examples
Donner le droit SELECT tout le monde pour toutes les tables (et vues) que vous pourriez crer plus tard dans le schma
mon_schema, et permettre au rle webuser d'utiliser en plus INSERT :
ALTER DEFAULT PRIVILEGES IN SCHEMA mon_schema GRANT SELECT ON TABLES TO PUBLIC;
ALTER DEFAULT PRIVILEGES IN SCHEMA mon_schema GRANT INSERT ON TABLES TO webuser;
Annuler ce qui a t fait ci-dessus, pour que les tables cres par la suite n'aient pas plus de droits qu'en standard :
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE SELECT ON TABLES FROM PUBLIC;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE INSERT ON TABLES FROM webuser;
Supprimer le droit publique EXECUTE qui est normalement donn aux fonctions, pour toutes les fonctions cres aprs coup par
le rle admin :
ALTER DEFAULT PRIVILEGES FOR ROLE admin REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;

Compatibilit
Il n'existe pas d'instruction ALTER DEFAULT PRIVILEGES dans le standard SQL.

Voir aussi
GRANT(7), REVOKE(7)

859

Nom
ALTER DOMAIN Modifier la dfinition d'un domaine

Synopsis
ALTER DOMAIN nom
{ SET DEFAULT expression | DROP DEFAULT }
ALTER DOMAIN nom
{ SET | DROP } NOT NULL
ALTER DOMAIN nom
ADD contrainte_de_domaine
ALTER DOMAIN nom
DROP CONSTRAINT nom_de_contrainte [ RESTRICT | CASCADE ]
ALTER DOMAIN nom
OWNER TO nouveau_propritaire
ALTER DOMAIN nom
SET SCHEMA nouveau_schema

Description
ALTER DOMAIN modifie la dfinition d'un domaine. Il existe plusieurs sous-formes :
SET/DROP DEFAULT
Ces formes positionnent ou suppriment la valeur par dfaut d'un domaine. Les valeurs par dfaut ne s'appliquent qu'aux
commandes INSERT ultrieures ; les colonnes d'une table qui utilise dj le domaine ne sont pas affectes.
SET/DROP NOT NULL
Ces formes agissent sur l'acceptation ou le rejet des valeurs NULL par un domaine. SET NOT NULL ne peut tre utilis
que si les colonnes qui utilisent le domaine contiennent des valeurs non nulles.
ADD contrainte de domaine
Cette forme ajoute une nouvelle contrainte un domaine avec la mme syntaxe que CREATE DOMAIN(7). Ceci ne fonctionne que lorsque toutes les colonnes qui utilisent le domaine satisfont la nouvelle contrainte.
DROP CONSTRAINT
Cette forme supprime les contraintes sur un domaine.
OWNER
Cette forme change le propritaire du domaine.
SET SCHEMA
Cette forme change le schma du domaine. Toute contrainte associe au domaine est dplace dans le nouveau schma.
Seul le propritaire de la fonction d'agrgat peut utiliser ALTER AGGREGATE.
Seul le propritaire du domaine peut utiliser ALTER DOMAIN. Pour modifier le schma d'un domaine, le droit CREATE sur le
nouveau schma est galement requis. Pour modifier le propritaire, il faut tre un membre direct ou indirect du nouveau rle
propritaire et ce rle doit avoir le droit CREATE sur le schma du domaine. Ces restrictions assurent que la modification du
propritaire n'agissent pas au-del de ce qui est ralisable en supprimant et en re-crant le domaine. Toutefois, un superutilisateur peut modifier le propritaire de n'importe quel domaine.

Paramtres
nom
Le nom du domaine modifier.
contrainte_de_domaine
Nouvelle contrainte de domaine pour le domaine.
nom_de_contrainte
Le nom d'une contrainte supprimer.
CASCADE
Les objets qui dpendent de la contrainte sont automatiquement supprims.
860

ALTER DOMAIN

RESTRICT
La contrainte n'est pas supprime si des objets en dpendent. C'est le comportement par dfaut.
nouveau_propritaire
Le nom de l'utilisateur nouveau propritaire du domaine.
nouveau_schema
Le nouveau schma du domaine.

Notes
Actuellement, ALTER DOMAIN ADD CONSTRAINT et ALTER DOMAIN SET NOT NULL choueront si le domaine
nomm ou tout domaine driv est utilis pour une colonne de type composite dans toute table de la base de donnes. Il se pourrait
que cela soit amlior pour vrifier la nouvelle contrainte sur ce type de colonnes intgres.

Exemples
Ajouter une contrainte NOT NULL un domaine :
ALTER DOMAIN codezip SET NOT NULL;
Supprimer une contrainte NOT NULL d'un domaine :
ALTER DOMAIN codezip DROP NOT NULL;
Ajouter une contrainte de contrle un domaine :
ALTER DOMAIN codezip ADD CONSTRAINT verif_zip CHECK (char_length(VALUE) = 5);
Supprimer une contrainte de contrle d'un domaine :
ALTER DOMAIN codezip DROP CONSTRAINT verif_zip;
Dplacer le domaine dans un schma diffrent :
ALTER DOMAIN zipcode SET SCHEMA customers;

Compatibilit
ALTER DOMAIN se conforme au standard SQL, l'exception des variantes OWNER et SET SCHEMA, qui sont des extensions
PostgreSQL.

Voir aussi
CREATE DOMAIN(7), DROP DOMAIN(7)

861

Nom
ALTER EXTENSION modifie la dfinition d'une extension

Synopsis
ALTER
ALTER
ALTER
ALTER

EXTENSION
EXTENSION
EXTENSION
EXTENSION

nom_extension
nom_extension
nom_extension
nom_extension

UPDATE [ TO nouvelle_version ]
SET SCHEMA nouveau_schma
ADD objet_membre
DROP objet_membre

o objet_membre peut tre :


AGGREGATE nom_agg (type_agg [, ...] ) |
CAST (type_source AS type_cible) |
COLLATION nom_objet |
CONVERSION nom_objet |
DOMAIN nom_objet |
FOREIGN DATA WRAPPER nom_objet |
FOREIGN TABLE nom_objet |
FUNCTION nom_fonction ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] ) |
OPERATOR nom_oprateur (type_gauche, type_droit) |
OPERATOR CLASS nom_objet USING mthode_indexage |
OPERATOR FAMILY nom_objet USING mthode_indexage |
[ PROCEDURAL ] LANGUAGE nom_objet |
SCHEMA nom_objet |
SEQUENCE nom_objet |
SERVER nom_objet |
TABLE nom_objet |
TEXT SEARCH CONFIGURATION nom_objet |
TEXT SEARCH DICTIONARY nom_objet |
TEXT SEARCH PARSER nom_objet |
TEXT SEARCH TEMPLATE nom_objet |
TYPE nom_objet |
VIEW nom_objet

Description
ALTER EXTENSION modifie la dfinition d'une extension. Il existe plusieurs variantes :
UPDATE
Met jour l'extension avec une nouvelle version. L'extension doit fournir le script de mise jour adquat (voire un ensemble de scripts) qui peut modifier la version en cours vers la version demande.
SET SCHEMA
Dplace les objets de l'extension vers un autre schma. L'extension doit permettre que ses objets soient dplacs pour que
cette commande fonctionne.
ADD objet_membre
Ajoute un objet existant l'extension. Cette commande est utilise principalement dans les scripts de mise jour
d'extensions. L'objet concern sera alors considr comme appartenant l'extension. Cela signifie principalement que
l'objet ne pourra tre supprim qu'en supprimant l'extension.
DROP objet_membre
Supprime un objet de l'extension. Cette commande est utilise principalement dans les scripts de mise jour d'extensions.
L'objet n'est pas supprim : il n'appartient simplement plus l'extension.
Voir aussi Section 35.15, Empaqueter des objets dans une extension pour des informations complmentaires sur les extensions.
Seul le propritaire de l'extension peut utiliser la commande ALTER EXTENSION pour supprimer l'extension. Les options
ADD ou DROP ncessitent en complment d'tre le propritaire de l'objet concern par l'ajout ou la suppression.

Paramtres
862

ALTER EXTENSION

nom_extension
Le nom de l'extension concerne.
nouvelle_version
La nouvelle version de l'extension installer. Il peut autant s'agir d'un identifiant que d'une chane de caractre. Si cette version n'est pas spcifie, la commande ALTER EXTENSION UPDATE va utiliser tous les lments de la version par dfaut
mentionns dans le fichier de contrle de l'extension.
nouveau_schma
Le nouveau schma vers lequel dplacer l'extension.
nom_objet, nom_agg, nom_fonction, nom_oprateur
Le nom d'un objet qui sera ajout ou retir de l'extension. Les noms de tables, aggrgats, domaines, tables distantes, fonctions,
oprateurs, classes d'oprateurs, familles d'oprateurs, squences, objets de recherche de texte, types et vues peuvent tre qualifis du nom du schma.
type_agg
Un type de donne paramtres de la fonction d'aggrgat concern. La syntaxe * peut tre utilise pour les fonctions d'aggrgat
sans paramtres.
type_source
Le nom d'un type de donnes source d'un transtypage.
type_cible
Le nom du type de donne cible d'un transtypage.
mode_arg
Le mode du paramtre d'une mthode : IN, OUT, INOUT ou VARIADIC. La valeur par dfaut est IN. Notez que la commande ALTER EXTENSION ne tient en ralit pas compte des paramtres dont le mode est OUT, car les paramtres en entre sont suffisants pour dterminer la signature de la fonction. Il est ainsi possible de ne spcifier que les paramtres de mode
IN, INOUT et VARIADIC.
nom_arg
Le nom du paramtre de la mthode concerne. Notez que la commande ALTER EXTENSION ne tient pas compte en ralit des noms de paramtre, car les types de donnes sont suffisants pour dterminer la signature de la mthode.
type_arg
Le(s) type(s) de donne des paramtres de la mthode concerne (ventuellement qualifi du nom du schma).
type_gauche, type_droit
Le type de donnes des arguments (ventuellement qualifi du nom du schma). crire NONE pour l'argument manquant d'un
oprateur prfix ou postfix.
PROCEDURAL
Le mot cl PROCEDURAL n'est pas ncessaire. Il peut tre omis.

Exemples
Pour mettre jour l'extension hstore la version 2.0 :
ALTER EXTENSION hstore UPDATE TO '2.0';
Pour modifier le schma de l'extension hstore vers utils :
ALTER EXTENSION hstore SET SCHEMA utils;
Pour ajouter une procdure stocke existante l'extension hstore :
ALTER EXTENSION hstore ADD FUNCTION populate_record(anyelement, hstore);

Compatibilit
ALTER EXTENSION est une extension de PostgreSQL.

863

ALTER EXTENSION

Voir aussi
CREATE EXTENSION(7), DROP EXTENSION(7)

864

Nom
ALTER FOREIGN DATA WRAPPER modifier la dfinition d'un wrapper de donnes distantes

Synopsis
ALTER
[
[
[
ALTER

FOREIGN DATA WRAPPER nom


HANDLER fonction_handler | NO HANDLER ]
VALIDATOR fonction_validation | NO VALIDATOR ]
OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ]) ]
FOREIGN DATA WRAPPER nom OWNER TO nouveau_propritaire

Description
ALTER FOREIGN DATA WRAPPER modifie la dfinition d'un wrapper de donnes distantes. La premire forme de la
commande modifie les fonctions de support ou les options gnriques du wrapper de donnes distantes (au moins une clause est
ncessaire). La seconde forme modifie le propritaire du wrapper de donnes distantes.
Seuls les superutilisateurs peuvent modifier les wrappers de donnes distantes. De plus, seuls les superutilisateurs peuvent tre
propritaire de wrappers de donnes distantes.

Paramtres
nom
Le nom d'un wrapper de donnes distantes existant.
HANDLER fonction_handler
Spcifie une nouvelle fonction de gestion pour le wrapper de donnes distantes.
NO HANDLER
Cette clause est utilise pour spcifier que le wrapper de donnes distantes ne doit plus avoir de fonction de gestion.
Notez que les tables distantes qui utilisent un wrapper de donnes distantes, sans fonction de gestion, ne peuvent pas tre
utilises.
VALIDATOR fonction_validation
Indique une fonction de validation pour le wrapper de donnes distantes.
Notez qu'il est possible que les options des wrappers de donnes distantes, des serveurs et des correspondances utilisateur
deviennent invalides une fois le validateur chang. C'est l'utilisateur de s'assurer que ces options sont correctes avant
d'utiliser le wrapper de donnes distantes.
NO VALIDATOR
Cette option est utilise pour spcifier que le wrapper de donnes distantes n'aura plus de fonction de validation.
OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ] )
Modifie les options du wrapper de donnes distantes. ADD, SET et DROP spcifient l'action raliser. ADD est pris par dfaut si aucune opration n'est explicitement spcifie. Les noms des options doivent tre uniques ; les noms et valeurs sont
valids en utilisant la fonction de validation du wrapper de donnes distantes.

Exemples
Modifier wrapper de donnes distantes dbi, ajouter l'option foo, supprimer bar :
ALTER FOREIGN DATA WRAPPER dbi OPTIONS (ADD foo '1', DROP 'bar');
Modifier la fonction de validation du wrapper de donnes distantes dbi en bob.myvalidator :
ALTER FOREIGN DATA WRAPPER dbi VALIDATOR bob.myvalidator;

Compatibilit
ALTER FOREIGN DATA WRAPPER se conforme ISO/IEC 9075-9 (SQL/MED). Nanmoins, les clauses HANDLER, VA865

ALTER FOREIGN DATA WRAPPER

LIDATOR et OWNER TO sont des extensions.

Voir aussi
CREATE FOREIGN DATA WRAPPER(7), DROP FOREIGN DATA WRAPPER(7)

866

Nom
ALTER FOREIGN TABLE modifie la dfinition de la table distante

Synopsis
ALTER FOREIGN TABLE nom
action [, ... ]
ALTER FOREIGN TABLE nom
RENAME [ COLUMN ] colonne TO nouvelle_colonne
ALTER FOREIGN TABLE nom
RENAME TO nouveau_nom
ALTER FOREIGN TABLE nom
SET SCHEMA nouveau_schma
o action peut tre :
ADD [ COLUMN ] colonne type
ADD [ COLUMN ] colonne type [ NULL | NOT NULL ]
DROP [ COLUMN ] [ IF EXISTS ] colonne [ RESTRICT | CASCADE ]
ALTER [ COLUMN ] colonne [ SET DATA ] TYPE type
ALTER [ COLUMN ] colonne { SET | DROP } NOT NULL
OWNER TO nouveau_propritaire
OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ])

Description
ALTER FOREIGN TABLE modifie la dfinition d'une table distante existante. Il existe plusieurs variantes :
ADD COLUMN
Ajoute une nouvelle colonne la table distante en utilisant une syntaxe identique celle de CREATE FOREIGN
TABLE(7).
DROP COLUMN [ IF EXISTS ]
Supprime une colonne de la table. L'option CASCADE doit tre utilise lorsque des objets en dehors de la table dpendant
de cette colonne, comme par exemple des rfrences de cls trangres ou des vues. Si IF EXISTS est indiqu et que la
colonne n'existe pas, aucune erreur n'est renvoye. Dans ce cas, un message d'avertissement est envoy la place.
SET DATA TYPE
Change le type d'une colonne de la table.
SET/DROP NOT NULL
Autorise / refuse l'ajout de valeurs NULL dans la colonne. SET NOT NULL ne peut tre utilis que si la colonne ne
contient pas de valeurs NULL.
OWNER
Change le propritaire d'une table distante. Le nouveau propritaire est celui pass en paramtre.
RENAME
Change le nom d'une table distante ou le nom d'une colonne individuelle de la table distante. Cela n'a aucun effet sur la donne stocke.
SET SCHEMA
Dplace la table distante dans un autre schma.
OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] )
Modifie les options de la table distante. L'action effectuer est spcifie par ADD (ajout), SET (dfinition) ou DROP
(suppression). Si aucune action n'est mentionne, ADD est utilise. Les noms des options autorises et leurs valeurs sont
spcifiques chaque wrapper de donnes distantes et sont valides en utilisant la fonction de validation du wrapper de donnes distantes. Le nom de chaque option doit tre unique.
l'exception de RENAME et SET SCHEMA, toutes les actions peuvent tre combines en une liste de modifications appliques
paralllement. Par exemple, il est possible d'ajouter plusieurs colonnes et/ou de modifier plusieurs colonnes en une seule commande.
Il faut tre propritaire de la table pour utiliser ALTER FOREIGN TABLE. Pour modifier le schma d'une table, le droit
867

ALTER FOREIGN TABLE

CREATE sur le nouveau schma est requis. Pour modifier le propritaire de la table, il est ncessaire d'tre un membre direct ou
indirect du nouveau rle et ce dernier doit avoir le droit CREATE sur le schma de la table (ces restrictions assurent que la modification du propritaire ne diffre en rien de ce qu'il est possible de faire par la suppression et la re-cration de la table. Nanmoins,
dans tous les cas, un superutilisateur peut modifier le propritaire de n'importe quelle table).

Paramtres
nom
Le nom (ventuellement qualifi du nom du schma) de la table modifier.
colonne
Le nom d'une colonne, existante ou nouvelle.
nouvelle_colonne
Le nouveau nom d'une colonne existante.
nouveau_nom
Le nouveau nom de la table.
type
Le type de donnes de la nouvelle colonne, ou le nouveau type de donnes d'une colonne existante.
CASCADE
Les objets qui dpendent de la colonne ou de la contrainte supprime sont automatiquement supprims (par exemple, les vues
rfrenant la colonne).
RESTRICT
La colonne ou la contrainte n'est pas supprime si des objets en dpendent. C'est le comportement par dfaut.
nouveau_propritaire
Le nom d'utilisateur du nouveau propritaire de la table distante.
nouveau_schma
Le nom du schma vers lequel la table distante sera dplace.

Notes
Le mot cl COLUMN n'est pas ncessaire. Il peut tre omis.
La cohrence avec le serveur distant n'est pas vrifie lorsqu'une colonne est ajoute ou supprime avec la commande ADD COLUMN ou DROP COLUMN, lorsqu'une contrainte CHECK ou NOT NULL est ajoute, ou encore lorsqu'un type de colonne est modifi avec l'action SET DATA TYPE. Il est ainsi de la responsabilit de l'utilisateur de s'assurer que la dfinition de la table distante
est compatible avec celle du serveur distant.
Voir la commande CREATE FOREIGN TABLE(7) pour une description plus complte des paramtres valides.

Exemples
Pour interdire les valeurs NULL sur une colonne :
ALTER FOREIGN TABLE distributeurs ALTER COLUMN rue SET NOT NULL;
Pour modifier les options d'une table distante :
ALTER FOREIGN TABLE mon_schema.distributeurs OPTIONS (ADD opt1 'valeur', SET opt2,
'valeur2', DROP opt3 'valeur3');

Compatibilit
Les actions ADD, DROP, et SET DATA TYPE sont conformes au standard SQL. Les autres actions sont des extensions PostgreSQL du standard SQL. De plus, la possibilit de combiner de multiples modifications en une seule commande ALTER FOREIGN TABLE est une extension PostgreSQL.
La commande ALTER FOREIGN TABLE DROP COLUMN peut tre utilise pour supprimer jusqu' la dernire colonne
d'une table distante, permettant ainsi d'obtenir une table sans colonne. Il s'agit d'une extension du standard SQL, qui ne permet pas
de grer des tables sans colonnes.
868

Nom
ALTER FUNCTION Modifier la dfinition d'une fonction

Synopsis
ALTER FUNCTION nom ( [ [ modearg
action [ ... ] [ RESTRICT ]
ALTER FUNCTION nom ( [ [ modearg
RENAME TO nouveau_nom
ALTER FUNCTION nom ( [ [ modearg
OWNER TO new_owner
ALTER FUNCTION nom ( [ [ modearg
SET SCHEMA nouveau_schema

] [ nomarg ] typearg [, ...] ] )


] [ nomarg ] typearg [, ...] ] )
] [ nomarg ] typearg [, ...] ] )
] [ nomarg ] typearg [, ...] ] )

o action peut tre :


CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
IMMUTABLE | STABLE | VOLATILE
[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
COST cout_execution
ROWS nb_lignes_resultat
SET parametre { TO | = } { valeur | DEFAULT }
SET parametre FROM CURRENT
RESET parametre
RESET ALL

Description
ALTER FUNCTION modifie la dfinition d'une fonction.
Seul le propritaire de la fonction peut utiliser ALTER FUNCTION. Le privilge CREATE sur le nouveau schma est requis
pour pouvoir changer le schma de la fonction. Pour modifier le propritaire, il est ncessaire d'tre membre direct ou indirect
du nouveau rle propritaire. Ce dernier doit possder le droit CREATE sur le schma de la fonction. Ces restrictions assurent
que la modification du propritaire n'a pas d'effets autres que ceux obtenus par la suppression et la re-cration de la fonction ;
toutefois, un superutilisateur peut modifier le propritaire de n'importe quelle fonction.

Paramtres
nom
Le nom de la fonction.
modearg
Le mode d'un argument : IN, OUT, INOUT ou VARIADIC. En cas d'omission, la valeur par dfaut est IN. ALTER FUNCTION ne tient pas compte des arguments OUT, car seuls les arguments en entre sont ncessaire pour dterminer l'identit
de la fonction. Les arguments IN, INOUT et VARIADIC sont donc suffisants.
nomarg
Le nom d'un argument. ALTER FUNCTION ne tient pas compte des noms des arguments, car seuls les types de donnes
des arguments sont ncessaires pour dterminer l'identit d'une fonction.
typearg
Le(s) type(s) de donnes des arguments de la fonction (ventuellement qualifi(s) du nom du schma).
nouveau_nom
Le nouveau nom de la fonction.
nouveau_proprietaire
Le nouveau propritaire de la fonction. Si cette fonction est marque SECURITY DEFINER, elle s'excute par la suite
sous cette identit.
nouveau_schema
Le nouveau schma de la fonction.
CALLED ON NULL INPUT, RETURNS NULL ON NULL INPUT, STRICT
CALLED ON NULL INPUT modifie la fonction pour qu'elle puisse tre appele avec des arguments NULL. RETURNS
NULL ON NULL INPUT et STRICT modifie la fonction pour qu'elle ne soit pas appele si un des arguments est NULL ;
869

ALTER FUNCTION

un rsultat NULL est alors automatiquement dtermin. Voir CREATE FUNCTION(7) pour plus d'informations.
IMMUTABLE, STABLE, VOLATILE
Modifie la volatilit de la fonction. Voir CREATE FUNCTION(7) pour plus d'informations.
[ EXTERNAL ] SECURITY INVOKER, [ EXTERNAL ] SECURITY DEFINER
Prcise si la fonction doit tre appele avec les droits de l'utilisateur qui l'a cre. Le mot cl EXTERNAL, ignor, existe pour
des raisons de compatibilit SQL. Voir CREATE FUNCTION(7) pour plus d'informations.
COST cout_execution
Modifie l'estimation du cot d'excution de la fonction. Voir CREATE FUNCTION(7) pour plus d'informations.
ROWS nb_lignes_resultat
Modifie l'estimation du nombre de lignes renvoyes par une fonction SRF. Voir CREATE FUNCTION(7) pour plus
d'informations.
parametre, valeur
Ajoute ou modifie l'initialisation d'un paramtre de configuration lorsque la fonction est appele. Si valeur est DEFAULT
ou, de faon quivalente, si RESET est utilis, le paramtre local de la fonction est supprime pour que la fonction s'excute
avec la valeur par dfaut du paramtre. Utiliser RESET ALL supprime tous les valeurs spcifiques des paramtres pour cette
fonction. SET FROM CURRENT sauvegarde la valeur courante comme valeur du paramtre appliquer lors de l'excution de
la fonction.
Voir SET(7) et Chapitre 18, Configuration du serveur pour plus d'informations sur les noms des paramtres et les valeurs autoriss.
RESTRICT
Ignor, prsent pour des raisons de conformit avec le standard SQL.

Exemples
Renommer la fonction sqrt pour le type integer en square_root :
ALTER FUNCTION sqrt(integer) RENAME TO square_root;
Changer le propritaire de la fonction sqrt pour le type integer en joe :
ALTER FUNCTION sqrt(integer) OWNER TO joe;
Modifier le schma de la fonction sqrt du type integer par maths :
ALTER FUNCTION sqrt(integer) SET SCHEMA maths;
Pour ajuster automatiquement le chemin de recherche des schmas pour une fonction :
ALTER FUNCTION verifie_motdepasse(text) SET search_path = admin, pg_temp;
Pour dsactiver le paramtre search_path d'une fonction :
ALTER FUNCTION verifie_motdepasse(text) RESET search_path;
La fonction s'excutera maintenant avec la valeur de la session pour cette variable.

Compatibilit
La compatibilit de cette instruction avec l'instruction ALTER FUNCTION du standard SQL est partielle. Le standard autorise la
modification d'un plus grand nombre de proprits d'une fonction mais ne laisse pas la possibilit de renommer une fonction, de
placer le commutateur SECURITY DEFINER sur la fonction, d'y attacher des valeurs de paramtres ou d'en modifier le propritaire, le schma ou la volatilit. Le standard requiert le mot cl RESTRICT ; il est optionnel avec PostgreSQL.

Voir aussi
CREATE FUNCTION(7), DROP FUNCTION(7)

870

Nom
ALTER GROUP Modifier le nom d'un rle ou la liste de ses membres

Synopsis
ALTER GROUP nom_groupe ADD USER nom utilisateur [, ... ]
ALTER GROUP nom_groupe DROP USER nom_utilisateur [, ... ]
ALTER GROUP nom_groupe RENAME TO nouveau_nom

Description
ALTER GROUP modifie les attributs d'un groupe d'utilisateurs Cette commande est obsolte, mais toujours accepte pour des
raisons de compatibilit ascendante. Les groupes (et les utilisateurs) ont t remplacs par le concept plus gnral de rles.
Les deux premires formes ajoutent des utilisateurs un groupe ou en suppriment. Tout rle peut tre ici utilisateur ou
groupe . Ces variantes sont rellement quivalentes la promotion ou la rvocation de l'appartenance au rle nomm
groupe ; il est donc prfrable d'utiliser GRANT(7) et REVOKE(7) pour le faire.
La troisime forme change le nom du groupe. Elle est strictement quivalente au renommage du rle par ALTER ROLE(7).

Paramtres
nom_groupe
Le nom du groupe (rle) modifier.
nom_utilisateur
Les utilisateurs (rles) ajouter au groupe ou en enlever. Les utilisateurs doivent pralablement exister ; ALTER
GROUP ne cre pas et ne dtruit pas d'utilisateur.
nouveau_nom
Le nouveau nom du groupe.

Exemples
Ajouter des utilisateurs un groupe :
ALTER GROUP staff ADD USER karl, john;
Supprimer des utilisateurs d'un groupe :
ALTER GROUP workers DROP USER beth;

Compatibilit
Il n'existe pas de relation ALTER GROUP en SQL standard.

Voir aussi
GRANT(7), REVOKE(7), ALTER ROLE(7)

871

Nom
ALTER INDEX Modifier la dfinition d'un index

Synopsis
ALTER
ALTER
ALTER
ALTER

INDEX
INDEX
INDEX
INDEX

nom
nom
nom
nom

RENAME TO nouveau_nom
SET TABLESPACE nom_espacelogique
SET ( parametre_stockage = valeur [, ... ] )
RESET ( parametre_stockage [, ... ] )

Description
ALTER INDEX modifie la dfinition d'un index. Il existe plusieurs formes de l'instruction :
RENAME
La forme RENAME modifie le nom de l'index. Cela n'a aucun effet sur les donnes stockes.
SET TABLESPACE
Cette forme remplace le tablespace de l'index par le tablespace spcifi et dplace le(s) fichier(s) de donnes associ(s)
l'index dans le nouveau tablespace. Voir aussi CREATE TABLESPACE(7).
SET ( paramtre_stockage = valeur [, ... ] )
Cette forme modifie un ou plusieurs paramtres spcifiques la mthode d'indexage de cet index. Voir CREATE INDEX(7) pour les dtails sur les paramtres disponibles. Notez que le contenu de l'index ne sera pas immdiatement modifi
par cette commande ; suivant le paramtre, vous pouvez avoir besoin de reconstruire l'index avec REINDEX(7) pour obtenir l'effet dsir.
RESET ( paramtre_stockage [, ... ] )
Cette forme rinitialise un ou plusieurs paramtres de stockage spcifiques la mthode d'indexage leurs valeurs par dfaut. Comme avec SET, un REINDEX peut tre ncessaire pour mettre jour l'index compltement.

Paramtres
nom
Le nom de l'index modifier (ventuellement qualifi du nom du schma).
nouveau_nom
Le nouveau nom de l'index.
nom_espacelogique
Le nom du tablespace dans lequel dplacer l'index.
paramtre_stockage
Le nom du paramtre de stockage spcifique la mthode d'indexage.
valeur
La nouvelle valeur du paramtre de stockage spcifique la mthode d'indexage. Cette valeur peut tre un nombre ou une
chane suivant le paramtre.

Notes
Ces oprations sont aussi possibles en utilisant ALTER TABLE(7). ALTER INDEX n'est en fait qu'un alias pour les formes
d'ALTER TABLE qui s'appliquent aux index.
Auparavant, il existait une variante ALTER INDEX OWNER mais elle est maintenant ignore (avec un message
d'avertissement). Un index ne peut pas avoir un propritaire diffrent de celui de la table. Modifier le propritaire de la table modifie automatiquement celui de l'index.
Il est interdit de modifier toute partie d'un index du catalogue systme.

Exemples
Renommer un index existant :
872

ALTER INDEX

ALTER INDEX distributeurs RENAME TO fournisseurs;


Dplacer un index dans un autre tablespace :
ALTER INDEX distributeurs SET TABLESPACE espacelogiquerapide;
Pour modifier le facteur de remplissage d'un index (en supposant que la mthode d'indexage le supporte) :
ALTER INDEX distributeurs SET (fillfactor = 75);
REINDEX INDEX distributeurs;

Compatibilit
ALTER INDEX est une extension PostgreSQL.

Voir aussi
CREATE INDEX(7), REINDEX(7)

873

Nom
ALTER LANGUAGE Modifier la dfinition d'un langage procdural

Synopsis
ALTER LANGUAGE nom RENAME TO nouveau_nom
ALTER LANGUAGE nom OWNER TO nouveau_proprietaire

Description
ALTER LANGUAGE modifie la dfinition d'un langage. Les seules fonctionnalits disponibles sont le renommage du langage
et son changement de propritaire. Vous devez tre soit un super-utilisateur soit le propritaire du langage pour utiliser ALTER
LANGUAGE.

Paramtres
nom
Le nom du langage.
nouveau_nom
Le nouveau nom du langage.
new_owner
Le nouveau propritaire du langage

Compatibilit
Il n'existe pas de relation ALTER LANGUAGE dans le standard SQL.

Voir aussi
CREATE LANGUAGE(7), DROP LANGUAGE(7)

874

Nom
ALTER LARGE OBJECT Modifier la dfinition d'un Large Object

Synopsis
ALTER LARGE OBJECT oid_large_object OWNER TO nouveau_propritaire

Description
ALTER LARGE OBJECT modifie la dfinition d'un Large Object . La seule fonctionnalit disponible est l'affectation d'un
nouveau propritaire. Vous devez tre un superutilisateur ou le propritaire du Large Object pour utiliser ALTER LARGE
OBJECT.

Paramtres
oid_large_object
OID d'un Large Object modifier
nouveau_propritaire
Le nouveau propritaire du Large Object

Compatibilit
Il n'existe pas d'instruction ALTER LARGE OBJECT dans le standard SQL.

Voir aussi
Chapitre 32, Objets larges

875

Nom
ALTER OPERATOR Modifier la dfinition d'un oprateur

Synopsis
ALTER OPERATOR nom ( { type_gauche | NONE } , { type_droit | NONE } ) OWNER TO
nouveau_propritaire
ALTER OPERATOR nom ( { type_gauche | NONE } , { type_droit | NONE } ) SET SCHEMA
nouveau_schma

Description
ALTER OPERATOR modifie la dfinition d'un oprateur. La seule fonctionnalit disponible est le changement de propritaire
d'un oprateur.
Seul le propritaire de l'oprateur peut utiliser ALTER OPERATOR. Pour modifier le propritaire, il est ncessaire d'tre un
membre direct ou indirect du nouveau rle propritaire, et ce rle doit avoir le droit CREATE sur le schma de l'oprateur. Ces
restrictions assurent que la modification du propritaire produise le mme rsultat que la suppression et la re-cration de
l'oprateur ; nanmoins, un superutilisateur peut modifier le propritaire de n'importe quel oprateur.

Paramtres
nom
Le nom de l'oprateur (ventuellement qualifi du nom du schma).
type_gauche
Le type de donnes de l'oprande gauche de l'oprateur ; NONE si l'oprateur n'a pas d'oprande gauche.
type_droit
Le type de donnes de l'oprande droit de l'oprateur ; NONE si l'oprateur n'a pas d'oprande droit.
nouveau_propritaire
Le nouveau propritaire de l'oprateur.
nouveau_schma
Le nouveau schma de l'oprateur.

Exemples
Modifier le propritaire d'un oprateur personnalis a @@ b pour le type text :
ALTER OPERATOR @@ (text, text) OWNER TO joe;

Compatibilit
Il n'existe pas d'instructions ALTER OPERATOR dans le standard SQL.

Voir aussi
CREATE OPERATOR(7), DROP OPERATOR(7)

876

Nom
ALTER OPERATOR CLASS Modifier la dfinition d'une classe d'oprateur

Synopsis
ALTER OPERATOR CLASS nom USING mthode_indexage RENAME TO nouveau_nom
ALTER OPERATOR CLASS nom USING mthode_indexage OWNER TO nouveau_propritaire
ALTER OPERATOR CLASS nom USING mthode_indexage SET SCHEMA nouveau_schma

Description
ALTER OPERATOR CLASS modifie la dfinition d'une classe d'oprateur.
Seul le propritaire de la classe d'oprateur peut utiliser ALTER OPERATOR CLASS. Pour modifier le propritaire, il est
obligatoire d'tre un membre direct ou indirect du nouveau rle propritaire. Ce rle doit possder le privilge CREATE sur le
schma de la classe d'oprateur. Ces restrictions assurent que la modification du propritaire produise le mme effet que celui
obtenu par la suppression et la re-cration de la classe d'oprateur ; nanmoins, un superutilisateur peut modifier le propritaire
de n'importe quelle classe d'oprateur.

Paramtres
nom
Le nom d'une classe d'oprateur.
mthode_indexage
Le nom de la mthode d'indexage laquelle associer la classe d'oprateur.
nouveau_nom
Le nouveau nom de la classe d'oprateur.
nouveau_propritaire
Le nouveau propritaire de la classe d'oprateur.
nouveau_schma
Le nouveau schma de la classe d'oprateur.

Compatibilit
Il n'existe pas d'instruction ALTER OPERATOR CLASS dans le standard SQL.

Voir aussi
CREATE OPERATOR CLASS(7), DROP OPERATOR CLASS(7), ALTER OPERATOR FAMILY(7)

877

Nom
ALTER OPERATOR FAMILY Modifier la dfinition d'une famille d'oprateur

Synopsis
ALTER OPERATOR FAMILY nom USING methode_indexage ADD
{ OPERATOR numero_strategie nom_operateur ( type_op, type_op ) [ FOR SEARCH | FOR
ORDER BY nom_famille_tri ]
| FUNCTION numero_support [ ( type_op [ , type_op ] ) ] nom_fonction (
type_argument [, ...] )
} [, ... ]
ALTER OPERATOR FAMILY nom USING methode_indexage DROP
{ OPERATOR numero_strategie ( type_op [ , type_op ] )
| FUNCTION numero_support ( type_op [ , type_op ] )
} [, ... ]
ALTER OPERATOR FAMILY nom USING mthode_indexage RENAME TO nouveau_nom
ALTER OPERATOR FAMILY nom USING mthode_indexage OWNER TO nouveau_proprietaire
ALTER OPERATOR FAMILY name USING mthode_indexage SET SCHEMA nouveau_schma

Description
ALTER OPERATOR FAMILY modifie la dfinition d'une famille d'oprateur. Vous pouvez ajouter des oprateurs et des
fonctions du support la famille, les supprimer ou modifier le nom et le propritaire de la famille.
Quand les oprateurs et fonctions de support sont ajouts une famille avec la commande ALTER OPERATOR FAMILY, ils
ne font partie d'aucune classe d'oprateur spcifique l'intrieur de la famille. Ils sont lches dans la famille. Ceci indique
que ces oprateurs et fonctions sont compatibles avec la smantique de la famille but qu'ils ne sont pas requis pour un fonctionnement correct d'un index spcifique. (Les oprateurs et fonctions qui sont ainsi ncessaires doivent tre dclars comme faisant
partie d'une classe d'oprateur ; voir CREATE OPERATOR CLASS(7).) PostgreSQL la suppression des membres lches
d'une famille tout moment, mais les membres d'une classe d'oprateur ne peuvent pas tre supprims sans supprimer toute la
classe et les index qui en dpendent. Typiquement, les oprateurs et fonctions sur un seul type de donnes font partie des classes
d'oprateurs car ils ont besoin de supporter un index sur ce type de donnes spcifique alors que les oprateurs et familles intertypes sont fait de membres lches de la famille.
Vous devez tre superutilisateur pour utiliser ALTER OPERATOR FAMILY. (Cette restriction est faite parce qu'une dfinition errone d'une famille d'oprateur pourrait gner voire mme arrter brutalement le serveur.)
ALTER OPERATOR FAMILY ne vrifie pas encore si la dfinition de l'oprateur de famille inclut tous les oprateurs et
fonctions requis par la mthode d'indexage, ni si les oprateurs et les fonctions forment un ensemble cohrent et suffisant. C'est
de la responsabilit de l'utilisateur de dfinir une famille d'oprateur valide.
Voir Section 35.14, Interfacer des extensions d'index pour plus d'informations.

Paramtres
nom
Le nom d'une famille d'oprateur (pouvant tre qualifi du schma).
methode_indexage
Le nom de la mthode d'indexage.
numero_strategie
Le numro de stratgie de la mthode d'indexage pour un oprateur associ avec la famille.
nom_operateur
Le nom d'un oprateur (pouvant tre qualifi du schma) associ avec la famille d'oprateur.
type_op
Dans une clause OPERATOR, les types de donnes en oprande de l'oprateur, ou NONE pour signifier un oprateur unaire.
Contrairement la syntaxe comparable de CREATE OPERATOR CLASS, les types de donnes en oprande doivent toujours tre prciss.
Dans une clause ADD FUNCTION, les types de donnes des oprandes que la fonction est sense supporter, si diffrent des
types de donnes en entre de la fonction. Pour les index B-tree et hash, il n'est pas strictement ncessaire de spcifier
878

ALTER OPERATOR FAMILY

op_type car les types de donnes en entre de la fonction sont toujours les bons utiliser. Pour les index GIN et GiST, il est
ncessaire de spcifier le type de donnes en entre qui sera utilis par la fonction.
Dans une clause DROP FUNCTION, les types de donnes en oprande que la fonction est sense supporte doivent tre prciss.
nom_famille_tri
Le nom d'une famille d'oprateur btree (pouvant tre qualifi du schma) dcrivant l'ordre de tri associ l'oprateur de tri.
Si ni FOR SEARCH ni FOR ORDER BY ne sont indiqus, FOR SEARCH est la valeur par dfaut.
numero_support
Le numro de la procdure de support de la mthode d'indexage associ avec la famille d'oprateur.
nom_fonction
Le nom (pouvant tre qualifi du schma) d'une fonction qui est une procdure de support de la mthode d'indexage pour la
famille d'oprateur.
argument_types
Les types de donnes pour les arguments de la fonction.
nouveau_nom
Le nouveau nom de la famille d'oprateur
nouveau_proprietaire
Le nouveau propritaire de la famille d'oprateur
nouveau_schma
Le nouveau schma de la famille d'oprateur.
Les clauses OPERATOR et FUNCTION peuvent apparatre dans n'importe quel ordre.

Notes
Notez que la syntaxe DROP spcifie uniquement le slot dans la famille d'oprateur, par stratgie ou numro de support et types
de donnes en entre. Le nom de l'oprateur ou de la fonction occupant le slot n'est pas mentionn. De plus, pour DROP FUNCTION, les types spcifier sont les types de donnes en entre que la fonction doit supporter ; pour les index GIN et GiST, ceci
pourrait ne rien avoir faire avec les types d'argument en entre de la fonction.
Comme le processus des index ne vrifie pas les droits sur les fonctions avant de les utiliser, inclure une fonction ou un oprateur
dans une famille d'oprateur est quivalent donner le droit d'excution public. Ceci n'est gnralement pas un problme pour
les tris de fonction qui sont utiles une famille d'oprateur.
Les oprateurs ne doivent pas tre dfinis par des fonctions SQL. Une fonction SQL risque d'tre remplace dans la requte appelante, ce qui empchera l'optimiseur de savoir si la requte peut utiliser un index.
Avant PostgreSQL 8.4, la clause OPERATOR pouvait inclure une option RECHECK. Ce n'est plus support parce que le fait
qu'un oprateur d'index soit perte est maintenant dtermin l'excution. Cela permet une gestion plus efficace des cas o un
oprateur pourrait ou non tre perte.

Exemples
La commande exemple suivant ajoute des oprateurs inter-type de donnes et ajoute les fonctions de support pour une famille
d'oprateur qui contient dj les classes d'oprateur B_tree pour les types de donnes int4 et int2.
ALTER OPERATOR FAMILY integer_ops USING btree ADD
-- int4 vs
OPERATOR 1
OPERATOR 2
OPERATOR 3
OPERATOR 4
OPERATOR 5
FUNCTION 1

int2
< (int4, int2) ,
<= (int4, int2) ,
= (int4, int2) ,
>= (int4, int2) ,
> (int4, int2) ,
btint42cmp(int4, int2) ,

-- int2 vs
OPERATOR 1
OPERATOR 2
OPERATOR 3

int4
< (int2, int4) ,
<= (int2, int4) ,
= (int2, int4) ,
879

ALTER OPERATOR FAMILY

OPERATOR 4 >= (int2, int4) ,


OPERATOR 5 > (int2, int4) ,
FUNCTION 1 btint24cmp(int2, int4) ;
Pour supprimer de nouveau ces entres :
ALTER OPERATOR FAMILY integer_ops USING btree DROP
-- int4 vs
OPERATOR 1
OPERATOR 2
OPERATOR 3
OPERATOR 4
OPERATOR 5
FUNCTION 1

int2
(int4,
(int4,
(int4,
(int4,
(int4,
(int4,

int2)
int2)
int2)
int2)
int2)
int2)

,
,
,
,
,
,

-- int2 vs
OPERATOR 1
OPERATOR 2
OPERATOR 3
OPERATOR 4
OPERATOR 5
FUNCTION 1

int4
(int2,
(int2,
(int2,
(int2,
(int2,
(int2,

int4)
int4)
int4)
int4)
int4)
int4)

,
,
,
,
,
;

Compatibilit
Il n'existe pas d'instruction ALTER OPERATOR FAMILY dans le standard SQL.

Voir aussi
CREATE OPERATOR FAMILY(7), DROP OPERATOR FAMILY(7), CREATE OPERATOR CLASS(7), ALTER OPERATOR
CLASS(7), DROP OPERATOR CLASS(7)

880

Nom
ALTER ROLE Modifier un rle de base de donnes

Synopsis
ALTER ROLE nom [ [ WITH ] option [ ... ] ]
o option peut tre :
|
|
|
|
|
|
|
|
|

SUPERUSER | NOSUPERUSER
CREATEDB | NOCREATEDB
CREATEROLE | NOCREATEROLE
CREATEUSER | NOCREATEUSER
INHERIT | NOINHERIT
LOGIN | NOLOGIN
REPLICATION | NOREPLICATION
CONNECTION LIMIT limiteconnexion
[ ENCRYPTED | UNENCRYPTED ] PASSWORD 'motdepasse'
VALID UNTIL 'dateheure'

ALTER ROLE nom RENAME TO nouveau_nom


ALTER ROLE nom [
valeur | DEFAULT
ALTER ROLE nom [
ALTER ROLE nom [
ALTER ROLE nom [

IN
}
IN
IN
IN

DATABASE nom_base ] SET parametre_configuration { TO | = } {


DATABASE nom_base ] SET parametre_configuration FROM CURRENT
DATABASE nom_base ] RESET parametre_configuration
DATABASE nom_base ] RESET ALL

Description
ALTER ROLE modifie les attributs d'un rle PostgreSQL.
La premire variante liste dans le synopsis, permet de modifier la plupart des attributs de rle spcifiables dans la commande
CREATE ROLE(7) ( lire pour plus de dtails). (Tous les attributs possibles sont couverts, l'exception de la gestion des appartenances ; GRANT(7) et REVOKE(7) sont utiliss pour cela.) Les attributs qui ne sont pas mentionns dans la commande
conservent leur paramtrage prcdent. Tous ces attributs peuvent tre modifis pour tout rle par les superutilisateurs de base
de donnes. Les rles qui possdent le privilge CREATEROLE peuvent modifier ces paramtres, mais uniquement pour les
rles qui ne sont pas superutilisateur. Les rles ordinaires ne peuvent modifier que leur mot de passe.
La deuxime variante permet de modifier le nom du rle. Les superutilisateurs peuvent renommer n'importe quel rle. Les rles
disposant du droit CREATEROLE peuvent renommer tout rle qui n'est pas superutilisateur. L'utilisateur de la session en cours
ne peut pas tre renomm. (On se connectera sous un autre utilisateur pour cela.) Comme les mots de passe chiffrs par MD5 utilisent le nom du rle comme grain de chiffrement, renommer un rle efface son mot de passe si ce dernier est chiffr avec MD5.
Les autres variantes modifient la valeur par dfaut d'une variable de configuration de session pour un rle, soit pour toutes les
bases soit, quand la clause IN DATABASE est spcifie, uniquement pour les sessions dans la base nomme. Quand le rle
lance une nouvelle session aprs cela, la valeur spcifie devient la valeur par dfaut de la session, surchargeant tout paramtrage prsent dans postgresql.conf ou provenant de la ligne de commande de postgres. Ceci arrive seulement lors de la
connexion ; excuter SET ROLE(7) ou SET SESSION AUTHORIZATION(7) ne cause pas la configuration de nouvelles valeurs pour les paramtres. L'ensemble des paramtres pour toutes les bases est surcharg par les paramtres spcifique cette
base attachs un rle Les superutilisateurs peuvent modifier les valeurs de session de n'importe quel utilisateur. Les rles disposant du droit CREATEROLE peuvent modifier les valeurs par dfaut pour les rles ordinaires (non superutilisateurs et non rplication). Les rles standards peuvent seulement configurer des valeurs par dfaut pour eux-mmes. Certaines variables ne
peuvent tre configures de cette faon ou seulement par un superutilisateur.

Paramtres
nom
Le nom du rle dont les attributs sont modifis.
SUPERUSER, NOSUPERUSER, CREATEDB, NOCREATEDB, CREATEROLE, NOCREATEROLE, CREATEUSER, NOCREATEUSER, INHERIT, NOINHERIT, LOGIN, NOLOGIN, REPLICATION, NOREPLICATION, CONNECTION LIMIT limite_connexion, PASSWORD motdepasse, ENCRYPTED, UNENCRYPTED, VALID UNTIL 'dateheure'
Ces clauses modifient les attributs originairement configurs par CREATE ROLE(7). Pour plus d'informations, voir la page
881

ALTER ROLE

de rfrence CREATE ROLE.


nouveau_nom
Le nouveau nom du rle.
nom_base
Le nom d'une base o se fera la configuration de la variable.
paramtre_configuration, valeur
Positionne la valeur de session par dfaut valeur pour le paramtre de configuration paramtre. Si DEFAULT est donn pour valeur ou, de faon quivalente, si RESET est utilis, le positionnement spcifique de la variable pour le rle est
supprim. De cette faon, le rle hrite de la valeur systme par dfaut pour les nouvelles sessions. RESET ALL est utilis
pour supprimer tous les paramtrages rle. SET FROM CURRENT sauvegarde la valeur de la session de ce paramtre en tant
que valeur du rle. Si IN DATABASE est prcis, le paramtre de configuration est intialis ou supprim seulement pour le
rle et la base indiqus.
Les paramtres spcifiques au rle ne prennent effet qu' la connexion ; SET ROLE(7) et SET SESSION AUTHORIZATION(7) ne traitent pas les paramtres de rles.
Voir SET(7) et Chapitre 18, Configuration du serveur pour plus d'informations sur les noms et les valeurs autoriss pour les
paramtres.

Notes
CREATE ROLE(7) est utilis pour ajouter de nouveaux rles et DROP ROLE(7) pour les supprimer.
ALTER ROLE ne peut pas modifier les appartenances un rle. GRANT(7) et REVOKE(7) sont conus pour cela.
Faites attention lorsque vous prcisez un mot de passe non chiffr avec cette commande. Le mot de passe sera transmis en clair au
serveur. Il pourrait se trouver tracer dans l'historique des commandes du client et dans les traces du serveur. psql(1) contient une
commande \password qui peut tre utilis pour changer le mot de passe d'un rle sans exposer le mot de passe en clair.
Il est galement possible de lier une valeur de session par dfaut une base de donnes plutt qu' un rle ; voir ALTER DATABASE(7). S'il y a un conflit, les paramtres spcifiques la paire base de donnes/rle surchargent ceux spcifiques au rle, qui
eux-mme surchargent ceux spcifiques la base de donnes.

Exemples
Modifier le mot de passe d'un rle :
ALTER ROLE davide WITH PASSWORD 'hu8jmn3';
Supprimer le mot de passe d'un rle :
ALTER ROLE davide WITH PASSWORD NULL;
Modifier la date d'expiration d'un mot de passe, en spcifiant que le mot de passe doit expirer midi le 4 mai 2015 fuseau horaire
UTC plus 1 heure :
ALTER ROLE chris VALID UNTIL 'May 4 12:00:00 2015 +1';
Crer un mot de passe toujours valide :
ALTER ROLE fred VALID UNTIL 'infinity';
Donner un rle la capacit de crer d'autres rles et de nouvelles bases de donnes :
ALTER ROLE miriam CREATEROLE CREATEDB;
Donner un rle une valeur diffrente de celle par dfaut pour le paramtre maintenance_work_mem :
ALTER ROLE worker_bee SET maintenance_work_mem = 100000;
Donner un rle une configuration duffrente, spcifique une base de donnes, du paramtre client_min_messages :
ALTER ROLE fred IN DATABASE devel SET client_min_messages = DEBUG;

Compatibilit
882

ALTER ROLE

L'instruction ALTER ROLE est une extension PostgreSQL.

Voir aussi
CREATE ROLE(7), DROP ROLE(7), SET(7)

883

Nom
ALTER SCHEMA Modifier la dfinition d'un schma

Synopsis
ALTER SCHEMA nom RENAME TO nouveau_nom
ALTER SCHEMA nom OWNER TO nouveau_propritaire

Description
ALTER SCHEMA modifie la dfinition d'un schma.
Seul le propritaire du schma peut utiliser ALTER SCHEMA. Pour renommer le schma, le droit CREATE sur la base est
obligatoire. Pour modifier le propritaire, il faut tre membre, direct ou indirect, du nouveau rle propritaire, et possder le
droit CREATE sur la base (les superutilisateurs ont automatiquement ces droits).

Paramtres
nom
Le nom du schma.
nouveau_nom
Le nouveau nom du schma. Il ne peut pas commencer par pg_, noms rservs aux schmas systme.
nouveau_propritaire
Le nouveau propritaire du schma.

Compatibilit
Il n'existe pas de relation ALTER SCHEMA dans le standard SQL.

Voir aussi
CREATE SCHEMA(7), DROP SCHEMA(7)

884

Nom
ALTER SEQUENCE Modifier la dfinition d'un gnrateur de squence

Synopsis
ALTER
[
[
[
[
[
ALTER
ALTER
ALTER

SEQUENCE nom [ INCREMENT [ BY ] increment ]


MINVALUE valeurmin | NO MINVALUE ] [ MAXVALUE valeurmax | NO MAXVALUE ]
START [ WITH ] dbut ]
RESTART [ [ WITH ] nouveau_dbut ] ]
CACHE cache ] [ [ NO ] CYCLE ]
OWNED BY { table.colonne | NONE } ]
SEQUENCE nom OWNER TO nouveau_propritaire
SEQUENCE nom RENAME TO nouveau_nom
SEQUENCE nom SET SCHEMA nouveau_schema

Description
ALTER SEQUENCE modifie les paramtres d'un gnrateur de squence. Tout paramtre non prcis dans la commande ALTER SEQUENCE conserve sa valeur prcdente. Pour modifier le propritaire, vous devez aussi tre un membre direct ou indirect du nouveau rle propritaire, et ce rle doit avoir le droit CREATE sur le schma de la squence (ces restrictions permettent de s'assurer que modifier le propritaire ne fait rien de plus que ce que vous pourriez faire en supprimant puis recrant la
squence ; nanmoins un superutilisateur peut dj modifier le propritaire de toute squence).
Seul le propritaire de la squence peut utiliser ALTER SEQUENCE. Pour modifier le schma de la squence, il faut possder
le droit CREATE sur le nouveau schma.

Paramtres
nom
Le nom de la squence modifier (ventuellement qualifi du nom du schma).
increment
La clause INCREMENT BY increment est optionnelle. Une valeur positive cre une squence croissante, une valeur ngative une squence dcroissante. Lorsque cette clause n'est pas spcifie, la valeur de l'ancien incrment est conserve.
valeurmin, NO MINVALUE
La clause optionnelle MINVALUE valeurmin, dtermine la valeur minimale de la squence. Si NO MINVALUE est utilis, les valeurs par dfaut, 1 et -263-1 sont utilises respectivement pour les squences croissantes et decroissantes. Si aucune
option n'est prcise, la valeur minimale courante est conserve.
valeurmax, NO MAXVALUE
La clause optionnelle MAXVALUE valeurmax dtermine la valeur maximale de la squence. Si NO MAXVALUE est utilis, les valeurs par dfaut 263-1 et -1 sont utilises respectivement pour les squences croissantes et dcroissantes. Si aucune
option n'est prcise, la valeur maximale courante est conserve.
dbut
La clause optionnelle START WITH dbut modifie la valeur de dpart enregistr pour la squence. Cela n'a pas d'effet
sur la valeur actuelle de celle-ci ; cela configure la valeur que les prochaines commandes ALTER SEQUENCE RESTART utiliseront.
restart
La clause optionnelle RESTART [ WITH restart ] modifie la valeur actuelle de la squence. C'est quivalent
l'appel de la fonction setval avec is_called = false : la valeur spcifie sera renvoye par le prochain appel
nextval. crire RESTART sans valeur pour restart est quivalent fournir la valeur de dbut enregistre par
CREATE SEQUENCE ou par ALTER SEQUENCE START WITH.
cache
La clause CACHE cache active la prallocation des numros de squences et leur stockage en mmoire pour en acclerer
l'accs. 1 est la valeur minimale (une seule valeur est engendre la fois, soit pas de cache). Lorsque la clause n'est pas spcifie, l'ancienne valeur est conserve.
CYCLE
Le mot cl optionnel CYCLE est utilis pour autoriser la squence boucler lorsque valeurmax ou valeurmin est at885

ALTER SEQUENCE

teint par, respectivement, une squence croissante ou dcroissante. Lorsque la limite est atteinte, le prochain numro engendr
est, respectivement, valeurmin ou valeurmax.
NO CYCLE
Si le mot cl optionnel NO CYCLE est spcifi, tout appel nextval alors que la squence a atteint sa valeur maximale,
dans le cas d'une squence croissante, ou sa valeur minimale dans le cas contraire, retourne une erreur. Lorsque ni CYCLE ni
NO CYCLE ne sont spcifis, l'ancien comportement est prserv.
OWNED BY table.colonne, OWNED BY NONE
L'option OWNED BY permet d'associer la squence une colonne spcifique d'une table pour que cette squence soit supprime automatiquement si la colonne (ou la table complte) est supprime. Si cette option est spcifie, cette association remplacera toute ancienne association de cette squence. La table indique doit avoir le mme propritaire et tre dans le mme
schma que la squence. Indiquer OWNED BY NONE supprime toute association existante, rendant la squence son
autonomie .
nouveau_propritaire
Le nom utilisateur du nouveau propritaire de la squence.
nouveau_nom
Le nouveau nom de la squence.
nouveau_schema
Le nouveau schma de la squence.

Notes
Pour viter de bloquer des transactions concurrentes lors de la demande de numros issus de la mme squence, les effets d'ALTER SEQUENCE sur les paramtres de gnration de la squence ne sont jamais annulables. Ces changements prennent effet
immdiatement et ne sont pas rversibles. Nanmoins, les clauses OWNED BY, OWNER TO, RENAME TO et SET SCHEMA sont
des modifications ordinaires du catalogue et, de ce fait, peuvent tre annules.
ALTER SEQUENCE n'affecte pas immdiatement les rsultats de nextval pour les sessions, l'exception de la session courante, qui ont prallou (cach) des valeurs de la squence. Elles puisent les valeurs en cache avant de prendre en compte les modifications sur les paramtres de gnration de la squence. La session l'origine de la commande est, quant elle, immdiatement
affecte.
ALTER SEQUENCE ne modifie pas le statut currval d'une squence (avant PostgreSQL 8.3, c'tait le cas quelque fois).
Pour des raisons historiques, ALTER TABLE peut aussi tre utilis avec les squences, mais seules les variantes d'ALTER
TABLE autorises pour les squences sont quivalentes aux formes affiches ci-dessus.

Exemples
Redmarrez la squence serial 105 :
ALTER SEQUENCE serial RESTART WITH 105;

Compatibilit
ALTER SEQUENCE est conforme au standard SQL, l'exception des variantes START WITH, OWNED BY, OWNER TO, RENAME TO et SET SCHEMA qui sont une extension PostgreSQL.

Voir aussi
CREATE SEQUENCE(7), DROP SEQUENCE(7)

886

Nom
ALTER SERVER modifier la dfinition d'un serveur distant

Synopsis
ALTER SERVER nom_serveur [ VERSION 'nouvelle_version' ]
[ OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ] ) ]
ALTER SERVER nom_serveur OWNER TO nouveau_propritaire

Description
ALTER SERVER modifie la dfinition d'un serveur distant. La premire forme modifie la chane de version du serveur ou les
options gnriques du serveur (au moins une clause est ncessaire). La seconde forme modifie le propritaire du serveur.
Pour modifier le serveur, vous devez tre le propritaire du serveur. De plus, pour modifier le propritaire, vous devez possder
le serveur ainsi qu'tre un membre direct ou indirect du nouveau rle, et vous devez avoir le droit USAGE sur le wrapper de donnes distantes du serveur. (Notez que les superutilisateurs satisfont tout ces critres automatiquement.)

Paramtres
nom_serveur
Le nom d'un serveur existant.
nouvelle_version
Nouvelle version du serveur.
OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ] )
Modifie des options pour le serveur. ADD, SET et DROP spcifient les actions excuter. Si aucune opration n'est spcifie
explicitement, l'action est ADD. Les noms d'options doivent tre uniques ; les noms et valeurs sont aussi valids en utilisant
la bibliothque de wrapper de donnes distantes.

Exemples
Modifier le serveur foo et lui ajouter des options de connexion :
ALTER SERVER foo OPTIONS (host 'foo', dbname 'dbfoo');
Modifier le serveur foo, modifier sa version, modifier son option host :
ALTER SERVER foo VERSION '8.4' OPTIONS (SET host 'baz');

Compatibilit
ALTER SERVER est conforme ISO/IEC 9075-9 (SQL/MED).

Voir aussi
CREATE SERVER(7), DROP SERVER(7)

887

Nom
ALTER TABLE Modifier la dfinition d'une table

Synopsis
ALTER TABLE [ ONLY ] nom [ * ]
action [, ... ]
ALTER TABLE [ ONLY ] nom [ * ]
RENAME [ COLUMN ] colonne TO nouvelle_colonne
ALTER TABLE nom
RENAME TO nouveau_nom
ALTER TABLE nom
SET SCHEMA nouveau_schema
o action peut tre :
ADD [ COLUMN ] colonne type [ COLLATE collation ] [ contrainte_colonne [ ... ] ]
DROP [ COLUMN ] [ IF EXISTS ] colonne [ RESTRICT | CASCADE ]
ALTER [ COLUMN ] colonne [ SET DATA ] TYPE type [ COLLATE collation ] [ USING
expression ]
ALTER [ COLUMN ] colonne SET DEFAULT expression
ALTER [ COLUMN ] colonne DROP DEFAULT
ALTER [ COLUMN ] colonne { SET | DROP } NOT NULL
ALTER [ COLUMN ] colonne SET STATISTICS entier
ALTER [ COLUMN ] column SET ( option_attribut = valeur [, ... ] )
ALTER [ COLUMN ] column RESET ( option_attribut [, ... ] )
ALTER [ COLUMN ] colonne SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
ADD contrainte_table [ NOT VALID ]
ADD contrainte_table_utilisant_index
VALIDATE CONSTRAINT constraint_name
DROP CONSTRAINT [ IF EXISTS ] nom_contrainte [ RESTRICT | CASCADE ]
DISABLE TRIGGER [ nom_declencheur | ALL | USER ]
ENABLE TRIGGER [ nom_declencheur | ALL | USER ]
ENABLE REPLICA TRIGGER nom_trigger
ENABLE ALWAYS TRIGGER nom_trigger
DISABLE RULE nom_regle_reecriture
ENABLE RULE nom_regle_reecriture
ENABLE REPLICA RULE nom_regle_reecriture
ENABLE ALWAYS RULE nom_regle_reecriture
CLUSTER ON nom_index
SET WITHOUT CLUSTER
SET WITH OIDS
SET WITHOUT OIDS
SET ( paramtre_stockage = valeur [, ... ] )
RESET ( paramtre_stockage [, ... ] )
INHERIT table_parent
NO INHERIT table_parent
OF nom_type
NOT OF
OWNER TO nouveau_proprietaire
SET TABLESPACE nouvel_espacelogique
et table_constraint_using_index est:
[ CONSTRAINT constraint_name ]
{ UNIQUE | PRIMARY KEY } USING INDEX index_name
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

Description
ALTER TABLE modifie la dfinition d'une table existante. Il existe plusieurs variantes :
ADD COLUMN
Ajoute une nouvelle colonne la table en utilisant une syntaxe identique celle de CREATE TABLE(7).
DROP COLUMN [ IF EXISTS ]
888

ALTER TABLE

Supprime une colonne de la table. Les index et les contraintes de table rfrenant cette colonne sont automatiquement supprims. L'option CASCADE doit tre utilise lorsque des objets en dehors de la table dpendent de cette colonne, comme par
exemple des rfrences de cls trangres ou des vues. Si IF EXISTS est indiqu et que la colonne n'existe pas, aucune erreur n'est renvoye. Dans ce cas, un message d'avertissement est envoy la place.
SET DATA TYPE
Change le type d'une colonne de la table. Les index et les contraintes simples de table qui impliquent la colonne sont automatiquement convertis pour utiliser le nouveau type de la colonne en r-analysant l'expression d'origine. La clause optionnelle
COLLATE spcifie une collation pour la nouvelle colonne. Si elle est omise, la collation utilise est la collation par dfaut
pour le nouveau type de la colonne. La clause optionnelle USING prcise comment calculer la nouvelle valeur de la colonne
partir de l'ancienne ; en cas d'omission, la conversion par dfaut est identique une affectation de transtypage de l'ancien type
vers le nouveau. Une clause USING doit tre fournie s'il n'existe pas de conversion implicite ou d'assignement entre les deux
types.
SET/DROP DEFAULT
Ajoute ou supprime les valeurs par dfaut d'une colonne. Les valeurs par dfaut ne s'appliquent qu'aux commandes INSERT
ultrieures. Elles ne modifient pas les lignes dj prsentes dans la table. Des valeurs par dfaut peuvent aussi tre cres pour
les vues. Dans ce cas, elles sont ajoutes aux commandes INSERT de la vue avant que la rgle ON INSERT de la vue ne soit
applique.
SET/DROP NOT NULL
Modifie l'autorisation de valeurs NULL. SET NOT NULL ne peut tre utilis que si la colonne ne contient pas de valeurs
NULL.
SET STATISTICS
Permet de modifier l'objectif de collecte de statistiques par colonne pour les oprations d'analyse (ANALYZE(7)) ultrieures.
L'objectif prend une valeur entre 0 et 10000. il est positionn -1 pour utiliser l'objectif de statistiques par dfaut du systme
(default_statistics_target). Pour plus d'informations sur l'utilisation des statistiques par le planificateur de requtes de PostgreSQL, voir Section 14.2, Statistiques utilises par le planificateur .
SET ( attribute_option = value [, ... ] ), RESET ( attribute_option [, ... ] )
Cette syntaxe permet de configurer ou de rinitialiser des proprits. Actuellement, les seules proprits acceptes sont
n_distinct et n_distinct_alled, qui surchargent l'estimation du nombre de valeurs distinctes calcule par ANALYZE(7) n_distinct affecte les statistiques de la table elle-mme alors que n_distinct_alled affecte les statistiques rcupres pour la table et les tables en hritant. Si configur une valeur positive, ANALYZE supposera que la colonne contient exactement le nombre spcifi de valeurs distinctes non NULL. Si configur une valeur ngative qui doit tre
suprieur ou gale -1, ANALYZE supposera que le nombre de valeurs distinctes non NULL dans la colonne est linaire par
rapport la taille de la table ; le nombre total est calculer en multipliant la taille estime de la table par la valeur absolue de
ce nombre. Par exemple, une valeur de -1 implique que toutes les valeurs dans la colonne sont distinctes alors qu'une valeur
de -0,5 implique que chaque valeur apparat deux fois en moyenne. Ceci peut tre utile quand la taille de la table change dans
le temps, car la multiplication par le nombre de lignes dans la table n'est pas ralise avant la planification. Spcifiez une valeur de 0 pour retourner aux estimations standards du nombre de valeurs distinctes. Pour plus d'informations sur l'utilisation
des statistiques par le planificateur de requtes PostgreSQL, rfrez vous Section 14.2, Statistiques utilises par le planificateur .
SET STORAGE
Modifie le mode de stockage pour une colonne. Cela permet de contrler si cette colonne est conserve en ligne ou dans une
deuxime table, appele table TOAST, et si les donnes sont ou non compresses. PLAIN, en ligne, non compress, est utilis
pour les valeurs de longueur fixe, comme les integer. MAIN convient pour les donnes en ligne, compressibles. EXTERNAL
est fait pour les donnes externes non compresses, EXTENDED pour les donnes externes compresses. EXTENDED est la
valeur par dfaut pour la plupart des types qui supportent les stockages diffrents de PLAIN. L'utilisation d'EXTERNAL permet d'acclrer les oprations d'extraction de sous-chanes sur les trs grosses valeurs de types text et bytea mais utilise plus
d'espace de stockage. SET STORAGE ne modifie rien dans la table, il configure la stratgie poursuivre lors des mises jour
de tables suivantes. Voir Section 55.2, TOAST pour plus d'informations.
ADD contrainte_table [ NOT VALID ]
Ajoute une nouvelle contrainte une table en utilisant une syntaxe identique CREATE TABLE(7), plus l'option NOT VALID, qui est actuellement seulement autorise pour les contraintes de type cl trangre. Si la contrainte est marque NOT
VALID, la vrification initiale, potentiellement lente, permettant de s'assurer que toutes les lignes de la table satisfont la
contrainte, est ignore. La contrainte sera toujours assure pour les insertions et mises jour suivantes (autrement dit, elles
choueront sauf s'il existe une ligne correspondante dans la table rfrence). Par contre, la base de donnes ne supposera pas
que la contrainte est valable pour toutes les lignes dans la table, tant que la contrainte n'a pas t valide en utilisant l'option
VALIDATE CONSTRAINT.
ADD table_constraint_using_index
Cette forme ajoute une nouvelle contrainte PRIMARY KEY ou UNIQUE sur une table, base sur un index unique existant au889

ALTER TABLE

paravant. Toutes les colonnes de l'index sont incluses dans la contrainte.


Cet index ne peut pas tre un index partiel, ni tre sur des expressions de colonnes. De plus, il doit tre un index b-tree avec
un ordre de tri par dfaut. Ces restrictions assurent que cet index soit quivalent un index qui aurait t cr par une commande standard ADD PRIMARY KEY ou ADD UNIQUE.
Si vous prcisez PRIMARY KEY, et que les colonnes de l'index ne sont pas dj spcifies comme NOT NULL, alors la commande va tenter d'appliquer la commande ALTER COLUMN SET NOT NULL sur chacune de ces colonnes. Cela ncessite
un parcours complet de la table pour vrifier que la ou les colonne(s) ne contiennent pas de null. Dans tous les autres cas, c'est
une opration rapide.
Si un nom de contrainte est fourni, alors l'index sera renomm afin de correspondre au nom de la contrainte. Sinon la
contrainte sera nomme comme l'index.
Une fois que la commande est excute, l'index est possd par la contrainte, comme si l'index avait t construit par une
commande ADD PRIMARY KEY ou ADD UNIQUE ordinaire. En particulier, supprimer la contrainte fait galement disparatre l'index.

Note
Ajouter une contrainte en utilisant un index existant peut tre utile dans les situations o il faut ajouter une
nouvelle contrainte, sans bloquer les mises jour de table trop longtemps. Pour faire cela, crez l'index avec
CREATE INDEX CONCURRENTLY, puis installez-la en tant que contrainte officielle en utilisant cette
syntaxe. Voir l'exemple ci-dessous.
VALIDATE CONSTRAINT
Cette forme valide une contrainte de type cl trangre qui a t prcdemment cre avec la clause NOT VALID. Elle le fait
en parcourant la table pour s'assurer qu'aucune ligne n'ait une rfrence invalide. Si la contrainte est dj marque valide, cette
clause ne fait rien.
La validation peut tre un processus long sur des tables volumineuses et ncessite actuellement un verrou ACCESS EXCLUSIVE. Sparer la validation de la cration initiale a comme intrt de pouvoir diffrer la validation un moment moins charg ou peut tre utilis pour donner un dlai supplmentaire pour corriger les erreurs pr-existantes tout en empchant l'ajout
de nouvelles erreurs.
DROP CONSTRAINT [ IF EXISTS ]
Supprime la contrainte de table prcise. Si IF EXISTS est prcis et que la contrainte n'existe pas, aucune erreur n'est renvoye. Par contre, un message d'avertissement est lanc.
DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGER
Configure l'excution des dclencheurs dfinis sur la table. Un dclencheur dsactiv est toujours connu par le systme mais
n'est plus excut lorsque l'vnement dclencheur survient. Pour un dclencheur retard, le statut d'activit est vrifi au moment o survient l'vnement, et non quand la fonction du dclencheur est rellement excute. Il est possible de dsactiver
ou d'activer un dclencheur spcifique (prcis par son nom), tous les dclencheurs d'une table ou seulement les dclencheurs
utilisateur de cette table (cette option exclut les dclencheurs gnrs en interne pour grer les contraintes comme ceux utiliss pour implanter les contraintes de cls trangres ou les contraintes dferrs uniques ou d'exclusion). Dsactiver ou activer
les dclencheurs implicites de contraintes requiert des droits de superutilisateur ; cela doit se faire avec prcaution car
l'intgrit de la contrainte ne peut pas tre garantie si les dclencheurs ne sont pas excuts. Le mcanisme de dclenchement
des triggers est aussi affect par la variable de configuration session_replication_role. Les triggers activs (ENABLE) se dclencheront quand le rle de rplication est origin (la valeur par dfaut) ou local . Les triggers configurs ENABLE
REPLICA se dclencheront seulement si la session est en mode replica et les triggers ENABLE ALWAYS se dclencheront chaque fois, quelque soit le mode de rplication.
DISABLE/ENABLE [ REPLICA | ALWAYS ] RULE
Ces formes configurent le dclenchement des rgles de rcriture appartenant la table. Une rgle dsactive est toujours
connue par le systme mais non applique lors de la rcriture de la requte. La smantique est identique celles des triggers
activs/dsactivs. Cette configuration est ignore pour les rgles ON SELECT qui sont toujours appliqus pour conserver le
bon fonctionnement des vues mme si la session actuelle n'est pas dans le rle de rplication par dfaut.
CLUSTER
Slectionne l'index par dfaut pour les prochaines oprations CLUSTER(7). La table n'est pas rorganise.
SET WITHOUT CLUSTER
Supprime de la table la spcification d'index CLUSTER(7) la plus rcemment utilise. Cela agit sur les oprations de rorganisation suivantes qui ne spcifient pas d'index.
SET WITH OIDS
Cette forme ajoute une colonne systme oid la table (voir Section 5.4, Colonnes systme ). Elle ne fait rien si la table a
890

ALTER TABLE

dj des OID.
Ce n'est pas quivalent ADD COLUMN oid oid. Cette dernire ajouterait une colonne normale nomme oid, qui n'est
pas une colonne systme.
SET WITHOUT OIDS
Supprime la colonne systme oid de la table. Cela est strictement quivalent DROP COLUMN oid RESTRICT, ceci
prs qu'aucun avertissement n'est mis si la colonne oid n'existe plus.
SET ( paramtre_stockage = valeur [, ... ] )
Cette forme modifie un ou plusieurs paramtres de stockage pour la table. Voir la section intitule Paramtres de stockage
pour les dtails sur les paramtres disponibles. Le contenu de la table ne sera pas modifi immdiatement par cette commande ; en fonction du paramtre, il pourra s'avrer ncessaire de rcrire la table pour obtenir les effets dsirs. Ceci peut se
faire avec VACUUM FULL, CLUSTER(7) ou une des formes d'ALTER TABLE qui force une rcriture de la table.

Note
Bien que CREATE TABLE autorise la spcification de OIDS avec la syntaxe WITH (paramtre_stockage), ALTER TABLE ne traite pas les OIDS comme un paramtre de stockage. la place,
utiliser les formes SET WITH OIDS et SET WITHOUT OIDS pour changer le statut des OID sur la table.
RESET ( paramtre_stockage [, ... ] )
Cette forme rinitialise un ou plusieurs paramtres de stockage leur valeurs par dfaut. Comme avec SET, une rcriture de
table pourrait tre ncessaire pour mettre jour entirement la table.
INHERIT table_parent
Cette forme ajoute la table cible comme nouvel enfant la table parent indique. En consquence, les requtes concernant le
parent ajouteront les enregistrements de la table cible. Pour tre ajoute en tant qu'enfant, la table cible doit dj contenir
toutes les colonnes de la table parent (elle peut avoir des colonnes supplmentaires). Les colonnes doivent avoir des types qui
correspondent, et s'il y a des contraintes NOT NULL dfini pour le parent, alors elles doivent aussi avoir les contraintes NOT
NULL pour l'enfant.
Il doit y avoir aussi une correspondance des contraintes de tables enfants pour toutes les contraintes CHECK. Actuellement, les
contraintes UNIQUE, PRIMARY KEY et FOREIGN KEY ne sont pas prises en compte mais ceci pourrait changer dans le futur.
NO INHERIT table_parent
Cette forme supprime une table cible de la liste des enfants de la table parent indique. Les requtes envers la table parent
n'incluront plus les enregistrements de la table cible.
OF nom_type
Cette forme lie la table un type composite comme si la commande CREATE TABLE OF l'avait cre. la liste des noms de
colonnes et leurs types doit correspondre prcisment ceux du type composite ; il est permis de diffrer la prsence d'une colonne systme oid. . La table ne doit pas hriter d'une autre table. Ces restrictions garantissent que la commande CREATE
TABLE OF pourrait permettre la dfinition d'une table quivalente.
NOT OF
Cette forme dissocie une table type de son type.
OWNER
Change le propritaire d'une table, d'une squence ou d'une vue. Le nouveau propritaire est celui pass en paramtre.
SET TABLESPACE
Remplace le tablespace de la table par le tablespace spcifi et dplace le(s) fichier(s) de donnes associ(s) la table vers le
nouveau tablespace. Les index de la table, s'il y en a, ne sont pas dplacs ; mais ils peuvent l'tre sparment l'aide de commandes SET TABLESPACE supplmentaires. Voir aussi CREATE TABLESPACE(7).
RENAME
Change le nom d'une table (d'un index, d'une squence ou d'une vue) ou le nom d'une colonne individuelle de la table. Cela
n'a aucun effet sur la donne stocke.
SET SCHEMA
Dplace la table dans un autre schma. Les index, les contraintes et les squences utilises dans les colonnes de table sont
galement dplacs.
Toutes les actions l'exception de RENAME et SET SCHEMA peuvent tre combines dans une liste d'altrations appliquer en
parallle. Par exemple, il est possible d'ajouter plusieurs colonnes et/ou de modifier le type de plusieurs colonnes en une seule
commande. Ceci est particulirement utile avec les grosses tables car une seule passe sur la table est alors ncessaire.
891

ALTER TABLE

Il faut tre propritaire de la table pour utiliser ALTER TABLE. Pour modifier le schma d'une table, le droit CREATE sur le
nouveau schma est requis. Pour ajouter la table en tant que nouvel enfant d'une table parent, vous devez aussi tre propritaire de
la table parent. Pour modifier le propritaire, il est ncessaire d'tre un membre direct ou indirect du nouveau rle et ce dernier
doit avoir le droit CREATE sur le schma de la table. (Ces restrictions assurent que la modification du propritaire ne diffre en
rien de ce qu'il est possible de faire par la suppression et le recration de la table. Nanmoins, un superutilisateur peut modifier le
propritaire de n'importe quelle table.)

Paramtres
nom
Le nom (ventuellement qualifi du nom du schma) de la table modifier. Si ONLY est indiqu avant le nom de la table,
seule cette table est modifie. Dans le cas contraire, la table et toutes ses tables filles (s'il y en a) sont modifies. En option, *
peut tre ajout aprs le nom de la table pour indiquer explicitement que les tables filles doivent tre inclues.
colonne
Le nom d'une colonne, existante ou nouvelle.
nouvelle_colonne
Le nouveau nom d'une colonne existante.
nouveau_nom
Le nouveau nom de la table.
type
Le type de donnes de la nouvelle colonne, ou le nouveau type de donnes d'une colonne existante.
contraintedetable
Une nouvelle contrainte de table pour la table.
nomdecontrainte
Le nom d'une contrainte existante supprimer.
CASCADE
Les objets qui dpendent de la colonne ou de la contrainte supprime sont automatiquement supprims (par exemple, les vues
rfrenant la colonne).
RESTRICT
La colonne ou la contrainte n'est pas supprime si des objets en dpendent. C'est le comportement par dfaut.
nom_declencheur
Le nom d'un dclencheur isol dsactiver ou activer.
ALL
Dsactiver ou activer tous les dclencheurs appartenant la table. (Les droits de superutilisateur sont ncessaires si l'un des
dclencheurs est un dclencheur interne pour la gestion d'une contrainte comme ceux utiliss pour implanter les contraintes de
type cls trangres ou les contraintes dferrables comme les contraintes uniques et d'exclusion.)
USER
Dsactiver ou activer tous les dclencheurs appartenant la table sauf les dclencheurs systmes permettant de grer en interne certaines contraintes, comme celles utilises pour implanter les contraintes de type cls trangres ou les contraintes dferrables comme les contraintes uniques et d'exclusion.)
nomindex
Le nom de l'index sur lequel la table doit tre rorganise.
paramtre_stockage
Le nom d'un paramtre de stockage de la table.
valeur
La nouvelle valeur d'un paramtre de stockage de la table. Cela peut tre un nombre ou un mot suivant le paramtre.
table_parent
Une table parent associer ou dissocier de cette table.
nouveau_propritaire
Le nom du nouveau propritaire de la table.
nouvel_espacelogique
Le nom du tablespace o dplacer la table.
892

ALTER TABLE

nouveau_schema
Le nom du schma o dplacer la table.

Notes
Le mot cl COLUMN n'est pas ncessaire. Il peut tre omis.
Quand une colonne est ajoute avec ADD COLUMN, toutes les lignes existantes de cette table sont initialises avec la valeur par
dfaut de la colonne (NULL si aucune clause DEFAULT n'a t dfinie).
Ajouter une colonne avec une valeur par dfaut diffrente de NULL ou modifier le type d'une colonne existante requiert que la
table entire et les index soient rcrits. Il existe une exception : si la clause USING ne change pas le contenu de la colonne et que
l'ancien type est soit transformable de faon binaire dans le nouveau type, ou bien un domaine sans contrainte reposant sur le nouveau type, alors il n'est pas ncessaire de rcrire la table, mais tous les index sur les colonnes affectes doivent quand mme tre
reconstruits. Le fait d'ajouter ou de supprimer une colonne systme oid ncessite galement une rcriture complte de la table.
Les reconstructions de table et/ou d'index peuvent prendre un temps significatif pour une grosse table, et peuvent ncessiter temporairement de doubler l'espace disque utilis.
Ajouter une contrainte CHECK ou NOT NULL requiert de parcourir la table pour vrifier que les lignes existantes respectent cette
contrainte.
La raison principale de la possibilit de spcifier des changements multiples l'aide d'une seule commande ALTER TABLE est
la combinaison en une seule passe sur la table de plusieurs parcours et rcritures.
La forme DROP COLUMN ne supprime pas physiquement la colonne, mais la rend simplement invisible aux oprations SQL. Par
la suite, les ordres d'insertion et de mise jour sur cette table stockent une valeur NULL pour la colonne. Ainsi, supprimer une colonne ne rduit pas immdiatement la taille de la table sur disque car l'espace occup par la colonne n'est pas rcupr. Cet espace
est rcupr au fur et mesure des mises jour des lignes de la table. (Ceci n'est pas vrai quand on supprime la colonne systme
oid ; ceci est fait avec une rcriture immdiate de la table.)
Pour forcer une rcriture immdiate de la table, vous pouvez utiliser VACUUM FULL, CLUSTER(7) ou bien une des formes de
la commande ALTER TABLE qui force une rcriture. Ceci ne cause pas de modifications visibles dans la table, mais limine des
donnes qui ne sont plus utiles.
L'option USING de SET DATA TYPE peut en fait utiliser une expression qui implique d'anciennes valeurs de la ligne ;
c'est--dire qu'il peut tre fait rfrence aussi bien aux autres colonnes qu' celle en cours de conversion. Cela permet d'effectuer
des conversions trs gnrales l'aide de la syntaxe SET DATA TYPE. cause de cette flexibilit, l'expression USING n'est pas
applique la valeur par dfaut de la colonne (s'il y en a une) : le rsultat pourrait ne pas tre une expression constante requise
pour une valeur par dfaut. Lorsqu'il n'existe pas de transtypage, implicite ou d'affectation, entre les deux types, SET DATA
TYPE peut chouer convertir la valeur par dfaut alors mme que la clause USING est spcifie. Dans de ce cas, il convient de
supprimer valeur par dfaut avec DROP DEFAULT, d'excuter ALTER TYPE et enfin d'utiliser SET DEFAULT pour ajouter une
valeur par dfaut approprie. Des considrations similaires s'appliquent aux index et contraintes qui impliquent la colonne.
Si une table est hrite, il n'est pas possible d'ajouter, de renommer ou de modifier le type d'une colonne dans la table parent sans
le faire aussi pour ses descendantes. De ce fait, la commande ALTER TABLE ONLY est rejete. Cela assure que les colonnes
des tables descendantes correspondent toujours celles de la table parent.
Un appel rcursif DROP COLUMN supprime la colonne d'une table descendante si et seulement si cette table n'hrite pas cette
colonne d'une autre table et que la colonne n'y a pas t dfinie indpendamment de tout hritage. Une suppression non rcursive
de colonne (ALTER TABLE ONLY ... DROP COLUMN) ne supprime jamais les colonnes descendantes ; elles sont marques
comme dfinies de manire indpendante, plutt qu'hrites.
Les actions TRIGGER, CLUSTER, OWNER, et TABLESPACE ne sont jamais propages aux tables descendantes ; c'est--dire
qu'elles agissent comme si ONLY est spcifi. Seuls les ajouts de contraintes CHECK sont propags, et c'est d'ailleurs obligatoire
pour ces contraintes.
Tout changement sur une table du catalogue systme est interdit.
Voir la commande CREATE TABLE(7) pour avoir une description plus complte des paramtres valides. Chapitre 5, Dfinition
des donnes fournit de plus amples informations sur l'hritage.

Exemples
Ajouter une colonne de type varchar une table :
ALTER TABLE distributeurs ADD COLUMN adresse varchar(30);
Supprimer une colonne de table :
893

ALTER TABLE

ALTER TABLE distributeurs DROP COLUMN adresse RESTRICT;


Changer les types de deux colonnes en une seule opration :
ALTER TABLE distributeurs
ALTER COLUMN adresse TYPE varchar(80),
ALTER COLUMN nom TYPE varchar(100);
Convertir une colonne de type integer (entier) contenant une estampille temporelle UNIX en timestamp with time zone l'aide
d'une clause USING :
ALTER TABLE truc
ALTER COLUMN truc_timestamp SET DATA TYPE timestamp with time zone
USING
timestamp with time zone 'epoch' + truc_timestamp * interval '1 second';
La mme, quand la colonne a une expression par dfaut qui ne sera pas convertie automatiquement vers le nouveau type de donnes :
ALTER TABLE truc
ALTER COLUMN truc_timestamp DROP DEFAULT,
ALTER COLUMN truc_timestamp TYPE timestamp with time zone
USING
timestamp with time zone 'epoch' + truc_timestamp * interval '1 second',
ALTER COLUMN truc_timestamp SET DEFAULT now();
Renommer une colonne existante :
ALTER TABLE distributeurs RENAME COLUMN adresse TO ville;
Renommer une table existante :
ALTER TABLE distributeurs RENAME TO fournisseurs;
Ajouter une contrainte NOT NULL une colonne :
ALTER TABLE distributeurs ALTER COLUMN rue SET NOT NULL;
Supprimer la contrainte NOT NULL d'une colonne :
ALTER TABLE distributeurs ALTER COLUMN rue DROP NOT NULL;
Ajouter une contrainte de vrification sur une table et tous ses enfants :
ALTER TABLE distributeurs ADD CONSTRAINT verif_cp CHECK (char_length(code_postal) = 5);
Supprimer une contrainte de vrification d'une table et de toutes ses tables filles :
ALTER TABLE distributeurs DROP CONSTRAINT verif_cp;
Pour enlever une contrainte check d'une table seule (pas sur ses enfants)
ALTER TABLE ONLY distributeurs DROP CONSTRAINT verif_cp;
(La contrainte check reste en place pour toutes les tables filles).
Ajouter une contrainte de cl trangre une table :
ALTER TABLE distributeurs ADD CONSTRAINT dist_fk FOREIGN KEY (adresse) REFERENCES
adresses (adresse) MATCH FULL;
Ajouter une contrainte unique (multicolonnes) une table :
ALTER TABLE distributeurs ADD CONSTRAINT dist_id_codepostal_key UNIQUE (dist_id,
code_postal);
Ajouter une cl primaire nomme automatiquement une table. Une table ne peut jamais avoir qu'une seule cl primaire.
ALTER TABLE distributeurs ADD PRIMARY KEY (dist_id);

894

ALTER TABLE

Dplacer une table dans un tablespace diffrent :


ALTER TABLE distributeurs SET TABLESPACE tablespacerapide;
Dplacer une table dans un schma diffrent :
ALTER TABLE mon_schema.distributeurs SET SCHEMA votre_schema;
Recrer une contrainte de cl primaire sans bloquer les mises jour pendant la reconstruction de l'index :
CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributeurs (dist_id);
ALTER TABLE distributeurs DROP CONSTRAINT distributeurs_pkey,
ADD CONSTRAINT distributeurs_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;

Compatibilit
Les formes ADD (without USING INDEX), DROP, SET DEFAULT et SET DATA TYPE (sans USING) se conforment au standard SQL. Les autres formes sont des extensions PostgreSQL, tout comme la possibilit de spcifier plusieurs manipulations en
une seule commande ALTER TABLE.
ALTER TABLE DROP COLUMN peut tre utilis pour supprimer la seule colonne d'une table, laissant une table dpourvue de
colonne. C'est une extension au SQL, qui n'autorise pas les tables sans colonne.

See Also
CREATE TABLE(7)

895

Nom
ALTER TABLESPACE Modifier la dfinition d'un tablespace

Synopsis
ALTER
ALTER
ALTER
ALTER

TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE

nom RENAME TO nouveau_nom


nom OWNER TO nouveau_propritaire
name SET ( option_tablespace = valeur [, ... ] )
name RESET ( option_tablespace [, ... ] )

Description
ALTER TABLESPACE modifie la dfinition d'un tablespace.
Seul le propritaire du tablespace peut utiliser ALTER TABLESPACE. Pour modifier le propritaire, il est ncessaire d'tre un
membre direct ou indirect du nouveau rle propritaire (les superutilisateurs ont automatiquement tous ces droits).

Paramtres
nom
Le nom du tablespace.
nouveau_nom
Le nouveau nom du tablespace. Le nouveau nom ne peut pas dbuter par pg_ car ces noms sont rservs aux espaces logiques systme.
nouveau_propritaire
Le nouveau propritaire du tablespace.
paramtre_tablespace
Un paramtre du tablespace configurer ou rinitialiser. Actuellement, les seuls paramtres disponibles sont
seq_page_cost et random_page_cost. Configurer une valeur pour un tablespace particulier surchargera
l'estimation habituelle du planificateur pour le cot de lecture de pages pour les tables du tablespace, comme indiqu par les
paramtres de configuration du mme nom (voir seq_page_cost, random_page_cost). Ceci peut tre utile si un tablespace se
trouve sur un disque qui est plus rapide ou plus lent du reste du systme d'entres/sorties.

Exemples
Renommer le tablespace espace_index en raid_rapide :
ALTER TABLESPACE espace_index RENAME TO raid_rapide;
Modifier le propritaire du tablespace espace_index :
ALTER TABLESPACE espace_index OWNER TO mary;

Compatibilit
Il n'existe pas d'instruction ALTER TABLESPACE dans le standard SQL.

Voir aussi
CREATE TABLESPACE(7), DROP TABLESPACE(7)

896

Nom
ALTER TEXT SEARCH CONFIGURATION modifier la dfinition d'une configuration de recherche plein texte

Synopsis
ALTER TEXT SEARCH CONFIGURATION nom
ADD MAPPING FOR type_jeton [, ... ] WITH nom_dictionnaire [, ... ]
ALTER TEXT SEARCH CONFIGURATION nom
ALTER MAPPING FOR type_jeton [, ... ] WITH nom_dictionnaire [, ... ]
ALTER TEXT SEARCH CONFIGURATION nom
ALTER MAPPING REPLACE vieux_dictionnaire WITH nouveau_dictionnaire
ALTER TEXT SEARCH CONFIGURATION nom
ALTER MAPPING FOR type_jeton [, ... ] REPLACE vieux_dictionnaire WITH
nouveau_dictionnaire
ALTER TEXT SEARCH CONFIGURATION nom
DROP MAPPING [ IF EXISTS ] FOR type_jeton [, ... ]
ALTER TEXT SEARCH CONFIGURATION nom RENAME TO nouveau_nom
ALTER TEXT SEARCH CONFIGURATION nom OWNER TO nouveau_proprietaire
ALTER TEXT SEARCH CONFIGURATION nom SET SCHEMA nouveau_schma

Description
ALTER TEXT SEARCH CONFIGURATION modifie la dfinition d'une configuration de recherche plein texte. Vous pouvez modifier les correspondances partir des types de jeton vers des dictionnaires, ou modifier le nom ou le propritaire de la
configuration.
Vous devez tre le propritaire de la configuration pour utiliser ALTER TEXT SEARCH CONFIGURATION.

Paramtres
nom
Le nom de la configuration de recherche plein texte (pouvant tre qualifi du schma).
type_jeton
Le nom d'un type de jeton qui est mis par l'analyseur de configuration.
nom_dictionnaire
Le nom d'un dictionnaire de recherche plein texte consulter pour le type de jeton spcifi. Si plusieurs dictionnaires sont
lists, ils sont consults dans l'ordre d'apparence.
ancien_dictionnaire
Le nom d'un dictionnaire de recherche plein texte remplacer dans la correspondance.
nouveau_dictionnaire
Le nom d'un dictionnaire de recherche plein texte substituer ancien_dictionnaire.
nouveau_nom
Le nouveau nom de la configuration de recherche plein texte.
newowner
Le nouveau propritaire de la configuration de recherche plein texte.
nouveau_schma
Le nouveau schma de la configuration de recherche plein texte.
La forme ADD MAPPING FOR installe une liste de dictionnaires consulter pour les types de jeton indiqus ; il y a une erreur
s'il y a dj une correspondance pour un des types de jeton. La forme ALTER MAPPING FOR fait de mme mais en commenant par supprimer toute correspondance existante avec ces types de jeton. Les formes ALTER MAPPING REPLACE substituent nouveau_dictionnaire par ancien_dictionnaire partout o ce dernier apparat. Ceci se fait pour les seuls
types de jeton indiqus quand FOR apparat ou pour toutes les correspondances de la configuration dans le cas contraire. La
forme DROP MAPPING supprime tous les dictionnaire pour les types de jeton spcifis, faisant en sorte que les jetons de ces
types soient ignors par la configuration de recherche plein texte. Il y a une erreur s'il n'y a pas de correspondance pour les types
de jeton sauf si IF EXISTS a t ajout.

897

ALTER TEXT SEARCH CONFIGURATION

Exemples
L'exemple suivant remplace le dictionnaire english avec le dictionnaire swedish partout o english est utilis dans
ma_config.
ALTER TEXT SEARCH CONFIGURATION ma_config
ALTER MAPPING REPLACE english WITH swedish;

Compatibilit
Il n'existe pas d'instructions ALTER TEXT SEARCH CONFIGURATION dans le standard SQL.

Voir aussi
CREATE TEXT SEARCH CONFIGURATION(7), DROP TEXT SEARCH CONFIGURATION(7)

898

Nom
ALTER TEXT SEARCH DICTIONARY modifier la dfinition d'un dictionnaire de recherche plein texte

Synopsis
ALTER TEXT
option
)
ALTER TEXT
ALTER TEXT
ALTER TEXT

SEARCH DICTIONARY nom (


[ = valeur ] [, ... ]
SEARCH DICTIONARY nom RENAME TO nouveau_nom
SEARCH DICTIONARY nom OWNER TO nouveau_proprietaire
SEARCH DICTIONARY nom SET SCHEMA nouveau_schma

Description
ALTER TEXT SEARCH DICTIONARY modifie la dfinition d'un dictionnaire de recherche plein texte. Vous pouvez modifier les options spcifiques au modle d'un dictionnaire. Vous pouvez aussi modifier le nom du dictionnaire et son propritaire.
Vous devez tre superutilisateur pour utiliser ALTER TEXT SEARCH DICTIONARY.

Paramtres
nom
Le nom du dictionnaire de recherche plein texte (pouvant tre qualifi du schma).
option
Le nom d'une option, spcifique au modle, configurer pour ce dictionnaire.
valeur
La nouvelle valeur utiliser pour une option spcifique au modle. Si le signe gale et la valeur sont omises, alors toute valeur prcdente de cette option est supprime du dictionnaire, permettant ainsi l'utilisation de la valeur par dfaut.
nouveau_nom
Le nouveau nom du dictionnaire de recherche plein texte.
nouveau_proprietaire
Le nouveau propritaire du dictionnaire de recherche plein texte.
nouveau_schma
Le nouveau schma du dictionnaire de recherche plein texte.
Les options spcifiques au modle peuvent apparatre dans n'importe quel ordre.

Exemples
La commande exemple suivant modifie la liste des mots d'arrt par un dictionnaire bas sur Snowball. Les autres paramtres
restent inchangs.
ALTER TEXT SEARCH DICTIONARY mon_dico ( StopWords = nouveaurusse );
La commande exemple suivante modifie la langue par le hollandais et supprime compltement l'option des mots d'arrt.
ALTER TEXT SEARCH DICTIONARY mon_dico ( language = dutch, StopWords );
La commande exemple suivante met jour la dfinition du dictionnaire sans rien modifier.
ALTER TEXT SEARCH DICTIONARY mon_dico ( dummy );
(Ceci fonctionne parce que le code de suppression de l'option ne se plaint pas s'il n'y a pas d'options.) Cette astuce est utile lors
de la modification des fichiers de configuration pour le dictionnaire : la commande ALTER forcera les sessions existantes relire les fichiers de configuration, ce qu'elles ne feraient jamais si elles les avaient dj lus.

899

ALTER TEXT SEARCH DICTIONARY

Compatibilit
Il n'existe pas d'instruction ALTER TEXT SEARCH DICTIONARY dans le standard SQL.

Voir aussi
CREATE TEXT SEARCH DICTIONARY(7), DROP TEXT SEARCH DICTIONARY(7)

900

Nom
ALTER TEXT SEARCH PARSER modifier la dfinition d'un analyseur de recherche plein texte

Synopsis
ALTER TEXT SEARCH PARSER nom RENAME TO nouveau_nom
ALTER TEXT SEARCH PARSER nom SET SCHEMA nouveau_schma

Description
ALTER TEXT SEARCH PARSER modifie la dfinition d'un analyseur de recherche plein texte. Actuellement, la seule fonctionnalit supporte est la modification du nom de l'analyseur.
Vous devez tre superutilisateur pour utiliser ALTER TEXT SEARCH PARSER.

Paramtres
nom
Le nom de l'analyseur de recherche plein texte (pouvant tre qualifi du schma).
nouveau_nom
Le nouveau nom de l'analyseur de recherche plein texte.
nouveau_schma
Le nouveau schma de l'analyseur de recherche plein texte.

Compatibilit
Il n'existe pas d'instruction ALTER TEXT SEARCH PARSER dans le standard SQL.

Voir aussi
CREATE TEXT SEARCH PARSER(7), DROP TEXT SEARCH PARSER(7)

901

Nom
ALTER TEXT SEARCH TEMPLATE modifier la dfinition d'un modle de recherche plein texte

Synopsis
ALTER TEXT SEARCH TEMPLATE nom RENAME TO nouveau_nom
ALTER TEXT SEARCH TEMPLATE nom SET SCHEMA nouveau_schma

Description
ALTER TEXT SEARCH TEMPLATE modifie la dfinition d'un modle de recherche plein texte. Actuellement, la seule
fonctionnalit supporte est la modification du nom du modle.
Vous devez tre superutilisateur pour utiliser ALTER TEXT SEARCH TEMPLATE.

Paramtres
nom
Le nom du modle de recherche plein texte (pouvant tre qualifi du schma).
nouveau_nom
Le nouveau nom du modle de recherche plein texte.
nouveau_schma
Le nouveau schma du modle de recherche plein texte.

Compatibilit
Il n'existe pas d'instruction ALTER TEXT SEARCH TEMPLATE dans le standard SQL.

Voir aussi
CREATE TEXT SEARCH TEMPLATE(7), DROP TEXT SEARCH TEMPLATE(7)

902

Nom
ALTER TRIGGER Modifier la dfinition d'un dclencheur

Synopsis
ALTER TRIGGER nom ON table RENAME TO nouveau_nom

Description
ALTER TRIGGER modifie les proprits d'un dclencheur. La clause RENAME renomme le dclencheur sans en changer la
dfinition.
Seul le propritaire de la table sur laquelle le dclencheur agit peut modifier ses proprits.

Paramtres
nom
Le nom du dclencheur modifier.
table
La table sur laquelle le dclencheur agit.
nouveau_nom
Le nouveau nom du dclencheur.

Notes
La possibilit d'activer ou de dsactiver temporairement un dclencheur est offerte par ALTER TABLE(7), et non par ALTER
TRIGGER qui ne permet pas d'agir sur tous les dclencheurs d'une table en une seule opration.

Exemples
Renommer un dclencheur :
ALTER TRIGGER emp_stamp ON emp RENAME TO emp_track_chgs;

Compatibilit
ALTER TRIGGER est une extension PostgreSQL au standard SQL.

Voir aussi
ALTER TABLE(7)

903

Nom
ALTER TYPE Modifier la dfinition d'un type

Synopsis
ALTER TYPE
ALTER TYPE
ALTER TYPE
RESTRICT ]
ALTER TYPE
ALTER TYPE

nom action [, ... ]


nom OWNER TO nouveau_propritaire
nom RENAME ATTRIBUTE nom_attribut TO nouveau_nom_attribut [ CASCADE |
nom RENAME TO nouveau_nom
nom SET SCHEMA nouveau_schma

ALTER TYPE nom ADD VALUE nouvelle_valeur_enumre [ { BEFORE | AFTER } valeur_enumre ] o


action fait partie de : ADD ATTRIBUTE nom_attributtype_de_donne [ COLLATE collationnement ] [
CASCADE | RESTRICT ] DROP ATTRIBUTE [ IF EXISTS ] nom_attribut [ CASCADE | RESTRICT ] ALTER ATTRIBUTE nom_attribut [ SET DATA ] TYPE type_de_donne [ COLLATE collationnement ] [ CASCADE | RESTRICT ]

Description
ALTER TYPE modifie la dfinition d'un type existant. Les variantes suivantes existent :
ADD ATTRIBUTE
Cette forme ajoute un nouvel attribut un type composite, avec la mme syntaxe que CREATE TYPE(7).
DROP ATTRIBUTE [ IF EXISTS ]
Cette forme supprime un attribut d'un type composite. Si IF EXISTS est spcifi et que l'attribut cible n'existe pas, aucun
message d'erreur ne sera mis, mais remplac par une alerte de niveau NOTICE.
SET DATA TYPE
Cette forme modifie le type d'un attribut d'un type composite.
OWNER
Cette forme modifie le propritaire d'un type.
RENAME
Cette forme permet de modifier le nom du type ou celui d'un attribut d'un type composite.
SET SCHEMA
Cette forme dplace le type dans un autre schma.
ADD VALUE [ BEFORE | AFTER ]
Cette forme ajoute une valeur une numration. Si la position de la nouvelle valeur n'est pas spcifie en utilisant BEFORE ou AFTER, le nouvel lment est plac en fin de liste.
CASCADE
Autorise la propagation automatique de la modification vers les tables types concernes par le type modifi, ainsi que leurs
ventuels descendants.
RESTRICT
Interdit l'opration si le type est dj rfrenc par des tables types. Il s'agit du comportement par dfaut.
Les actions ADD ATTRIBUTE, DROP ATTRIBUTE, et ALTER ATTRIBUTE peuvent tre combines dans une liste de modifications multiples appliquer en parallle. Il est ainsi possible d'ajouter et/ou modifier plusieurs attributs par une seule et mme
commande.
Seul le propritaire du type peut utiliser ALTER TYPE. Pour modifier le schma d'un type, le droit CREATE sur le nouveau
schma est requis. Pour modifier le propritaire, il faut tre un membre direct ou indirect du nouveau rle propritaire et ce rle
doit avoir le droit CREATE sur le schma du type (ces restrictions assurent que la modification du propritaire ne va pas au-del
de ce qui est possible par la suppression et la recration du type ; toutefois, un superutilisateur peut modifier le propritaire de
n'importe quel type).

Paramtres
nom
904

ALTER TYPE

Le nom du type modifier (ventuellement qualifi du nom du schma).


nouveau_nom
Le nouveau nom du type.
nouveau_propritaire
Le nom du nouveau propritaire du type.
nouveau_schema
Le nouveau schma du type.
nom_attribut
Le nom de l'attribut ajouter, modifier ou supprimer.
nouveau_nom_attribute
Le nouveau nom de l'attribut renommer.
type_de_donne
Le type de donne pour l'attribut ajouter ou modifier.
nouvelle_valeur_enumre
La nouvelle valeur ajouter la liste d'un type numr. Comme pour tous les littraux, la valeur devra tre dlimite par des
guillements simples.
valeur_enumre
La valeur existante d'une numration par rapport laquelle la nouvelle valeur doit tre ajoute (permet de dterminer l'ordre
de tri du type numr). Comme pour tous les littraux, la valeur existante devra tre dlimite par des guillements simples.

Notes
ALTER TYPE ... ADD VALUE (cette forme qui ajoute une nouvelle valeur une numration) ne peut tre excute
l'intrieur d'une transaction.
Les comparaisons faisant intervenir une valeur ajoute postriori peuvent quelquefois s'avrer plus lentes que celles portant uniquement sur les valeurs originales d'un type numr. Ce ralentissement ne devrait toutefois intervenir que si la position de la nouvelle valeur a t spcifie en utilisant les options BEFORE ou AFTER, au lieu d'insrer la nouvelle valeur en fin de liste. Ce ralentissement peut galement se produire, bien que la nouvelle valeur ait t insre en fin d'numration, en cas de bouclage du
compteur des OID depuis la cration du type numr. Le ralentissement est gnralement peu significatif ; mais s'il s'avre important, il est toujours possible de retrouver les performances optimales par une suppression / recration du type numr, ou encore par sauvegarde et rechargement de la base.

Exemples
Pour renommer un type de donnes :
ALTER TYPE courrier_electronique RENAME TO courriel;
Donner la proprit du type courriel joe :
ALTER TYPE courriel OWNER TO joe;
Changer le schma du type courriel en clients :
ALTER TYPE courriel SET SCHEMA clients;
Ajouter un nouvel attribut un type composite :
ALTER TYPE compfoo ADD ATTRIBUTE f3 int;
Ajouter une nouvelle valeur une numration, en spcifiant sa position de tri :
ALTER TYPE colors ADD VALUE 'orange' AFTER 'red';

Compatibilit
905

ALTER TYPE

Les variantes permettant d'ajouter et supprimer un attribut font partie du standard SQL ; les autres variantes sont des extensions
spcifiques PostgreSQL.

Voir aussi
CREATE TYPE(7), DROP TYPE(7)

906

Nom
ALTER USER Modifier un rle de la base de donnes

Synopsis
ALTER USER nom [ [ WITH ] option [ ... ] ]
o option peut tre :
|
|
|
|
|
|
|
|
|

SUPERUSER | NOSUPERUSER
CREATEDB | NOCREATEDB
CREATEROLE | NOCREATEROLE
CREATEUSER | NOCREATEUSER
INHERIT | NOINHERIT
LOGIN | NOLOGIN
REPLICATION | NOREPLICATION
CONNECTION LIMIT limite_connexion
[ ENCRYPTED | UNENCRYPTED ] PASSWORD 'motdepasse'
VALID UNTIL 'dateheure'

ALTER USER nom RENAME TO nouveau_nom


ALTER
ALTER
ALTER
ALTER

USER
USER
USER
USER

nom
nom
nom
nom

SET parametre_configuration { TO | = } { valeur | DEFAULT }


SET parametre_configuration FROM CURRENT
RESET parametre_configuration
RESET ALL

Description
ALTER USER est dsormais un alias de ALTER ROLE(7).

Compatibilit
La commande ALTER USER est une extension PostgreSQL. En effet, le standard SQL laisse le choix de la dfinition des
utilisateurs au SGBD.

Voir aussi
ALTER ROLE(7)

907

Nom
ALTER USER MAPPING change la dfinition d'une correspondance d'utilisateurs (user mapping)

Synopsis
ALTER USER MAPPING FOR { nom_utilisateur | USER | CURRENT_USER | PUBLIC }
SERVER nom_serveur
OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ] )

Description
ALTER USER MAPPING change la dfinition d'une correspondance d'utilisateur (user mapping).
Le propritaire d'un serveur distant peut aussi altrer les correspondances d'utilisateurs pour ce serveur pour tout utilisateur. Par
ailleurs, un utilisateur peut modifier une correspondance d'utilisateur pour son propre nom d'utilisateur s'il a reu le droit USAGE
sur le serveur distant.

Paramtres
nom_utilisateur
Nom d'utilisateur de la correspondance. CURRENT_USER et USER correspondent au nom de l'utilisateur courant. PUBLIC
est utilis pour correspondre tous les noms d'utilisateurs prsents et futurs du systme.
nom_serveur
Nom du serveur de la correspondance d'utilisateur.
OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ] )
Modifie l'option pour la correspondance d'utilisateur. La nouvelle option crase toute option prcdemment spcifie. ADD,
SET et DROP spcifient l'action excuter. Si aucune action n'est spcifie, l'action est ADD. Les noms d'options doivent
tre uniques ; les options sont aussi valides par le wrapper de donnes distantes du serveur.

Exemples
Modifier le mot de passe pour la correspondance d'utilisateur bob, et le serveur foo :
ALTER USER MAPPING FOR bob SERVER foo OPTIONS (user 'bob', password 'public');

Compatibilit
ALTER USER MAPPING est conforme la norme ISO/IEC 9075-9 (SQL/MED). Il y a un problme de syntaxe subtil : le
standard omet le mot cl FOR. Puisque CREATE USER MAPPING et DROP USER MAPPING utilisent tous les deux FOR
un endroit analogue et que DB2 d'IBM (l'autre implmentation majeure de SQL/MED) l'impose aussi pour ALTER USER
MAPPING, PostgreSQL diverge du standard pour des raisons de cohrence et de compatibilit.

Voir aussi
CREATE USER MAPPING(7), DROP USER MAPPING(7)

908

Nom
ALTER VIEW modifier la dfinition d'une vue

Synopsis
ALTER
ALTER
ALTER
ALTER
ALTER

VIEW
VIEW
VIEW
VIEW
VIEW

nom
nom
nom
nom
nom

ALTER [ COLUMN ] colonne SET DEFAULT expression


ALTER [ COLUMN ] colonne DROP DEFAULT
OWNER TO nouveau_propritaire
RENAME TO nouveau_nom
SET SCHEMA nouveau_schma

Description
ALTER VIEW modifie diffrentes proprits d'une vue. Si vous voulez modifier la requte dfinissant la vue, utilisez
CREATE OR REPLACE VIEW.)
Vous devez tre le propritaire de la vue pour utiliser ALTER VIEW. Pour modifier le schma d'une vue, vous devez aussi
avoir le droit CREATE sur le nouveau schma. Pour modifier le propritaire, vous devez aussi tre un membre direct ou indirect
de nouveau rle propritaire, et ce rle doit avoir le droit CREATE sur le schma de la vue. Ces restrictions permettent de
s'assurer que le changement de propritaire ne fera pas plus que ce que vous pourriez faire en supprimant et en recrant la vue.
Nanmoins, un superutilisateur peut changer le propritaire de n'importe quelle vue.

Paramtres
nom
Le nom de la vue (pouvant tre qualifi du schma).
SET/DROP DEFAULT
Ces formes ajoutent ou suppriment la valeur par dfaut pour une colonne. Une valeur par dfaut associe la colonne d'une
vue est insre avec des instructions INSERT sur la vue avant que la rgle ON INSERT ne soit applique, si INSERT
n'indique pas de valeur pour la colonne.
nouveau_propritaire
Nom utilisateur du nouveau propritaire de la vue.
nouveau_nom
Nouveau nom de la vue.
nouveau_schma
Nouveau schma de la vue.

Notes
Pour des raisons historiques, ALTER TABLE peut aussi tre utilis avec des vues ; mais seules les variantes de ALTER
TABLE qui sont acceptes avec les vues sont quivalentes celles affiches ci-dessus.

Exemples
Pour renommer la vue foo en bar :
ALTER VIEW foo RENAME TO bar;

Compatibilit
ALTER VIEW est une extensions PostgreSQL du standard SQL.

Voir aussi
CREATE VIEW(7), DROP VIEW(7)

909

Nom
ANALYZE Collecter les statistiques d'une base de donnes

Synopsis
ANALYZE [ VERBOSE ] [ table [ (colonne [, ...] ) ] ]

Description
ANALYZE collecte des statistiques sur le contenu des tables de la base de donnes et stocke les rsultats dans le catalogue systme pg_statistic. L'optimiseur de requtes les utilise pour dterminer les plans d'excution les plus efficaces.
Sans paramtre, ANALYZE examine chaque table de la base de donnes courante. Avec un paramtre, ANALYZE examine
seulement la table concerne. Il est possible de donner une liste de noms de colonnes, auquel cas seules les statistiques concernant ces colonnes sont collectes.

Paramtres
VERBOSE
L'affichage de messages de progression est activ.
table
Le nom (ventuellement qualifi du nom du schma) de la table analyser. Par dfaut, toutes les tables de la base de donnes courante sont analyses.
column
Le nom d'une colonne analyser. Par dfaut, toutes les colonnes le sont.

Sorties
Quand VERBOSE est spcifi, ANALYZE affiche des messages de progression pour indiquer la table en cours de traitement.
Diverses statistiques sur les tables sont aussi affiches.

Notes
Dans la configuration par dfaut de PostgreSQL, le dmon autovacumm (voir Section 23.1.5, Le dmon auto-vacuum )
l'analyse automatique des tables quand elle est remplie de donnes sont la premire fois, puis chaque fois qu'elles sont modifies via les oprations habituelles. Quand l'autovacuum est dsactiv, il est intressant de lancer ANALYZE priodiquement
ou juste aprs avoir effectu de grosses modifications sur le contenu d'une table. Des statistiques jour aident l'optimiseur
choisir le plan de requte le plus appropri et amliorent ainsi la vitesse du traitement des requtes. Une stratgie habituelle
consiste lancer VACUUM(7) et ANALYZE une fois par jour, au moment o le serveur est le moins sollicit.
ANALYZE ne requiert qu'un verrou en lecture sur la table cible. Il peut donc tre lanc en parallle d'autres activits sur la
table.
Les statistiques rcupres par ANALYZE incluent habituellement une liste des quelques valeurs les plus communes dans
chaque colonne et un histogramme affichant une distribution approximative des donnes dans chaque colonne. L'un ou les deux
peuvent tre omis si ANALYZE les juge inintressants (par exemple, dans une colonne cl unique, il n'y a pas de valeurs
communes) ou si le type de donnes de la colonne ne supporte pas les oprateurs appropris. Il y a plus d'informations sur les
statistiques dans le Chapitre 23, Planifier les tches de maintenance.
Pour les grosses tables, ANALYZE prend alatoirement plusieurs lignes de la table, au hasard, plutt que d'examiner chaque
ligne. Ceci permet des tables trs larges d'tre examines rapidement. Nanmoins, les statistiques ne sont qu'approximatives et
changent lgrement chaque fois qu'ANALYZE est lanc, mme si le contenu rel de la table n'a pas chang. Cela peut rsulter en de petites modifications dans les cots estims par l'optimiseur affichs par EXPLAIN(7). Dans de rares situations, ce
non-dterminisme entrane le choix par l'optimiseur d'un plan de requte diffrent entre deux lancements d'ANALYZE. Afin
d'viter cela, le nombre de statistiques rcupres par ANALYZE peut tre augment, comme cela est dcrit ci-dessous.
L'tendue de l'analyse est contrle par l'ajustement de la variable de configuration default_statistics_target ou colonne par colonne en initialisant la cible des statistiques par colonne avec ALTER TABLE ... ALTER COLUMN ... SET STATISTICS
(voir ALTER TABLE(7)). Cette valeur cible initialise le nombre maximum d'entres dans la liste des valeurs les plus communes
et le nombre maximum de points dans l'histogramme. La valeur cible par dfaut est fixe 100 mais elle peut tre ajuste vers le
haut ou vers le bas afin d'obtenir un bon compromis entre la prcision des estimations de l'optimiseur, le temps pris par ANA910

ANALYZE

LYZE et l'espace total occup dans pg_statistic. En particulier, initialiser la cible des statistiques zro dsactive la collecte
de statistiques pour cette colonne. Cela peut s'avrer utile pour les colonnes qui ne sont jamais utilises dans les clauses WHERE,
GROUP BY ou ORDER BY des requtes puisque l'optimiseur ne fait aucune utilisation des statistiques de ces colonnes.
La plus grande cible de statistiques parmi les colonnes en cours d'analyse dtermine le nombre de lignes testes pour prparer les
statistiques de la table. Augmenter cette cible implique une augmentation proportionnelle du temps et de l'espace ncessaires
l'excution d'ANALYZE.
Une des valeurs estimes par ANALYZE est le nombre de valeurs distinctes qui apparaissent dans chaque colonne. Comme seul
un sous-ensemble des lignes est examin, cette estimation peut parfoir tre assez inexacte, mme avec la cible statistique la plus
large possible. Si cette inexactitude amne de mauvais plans de requtes, une valeur plus prcise peut tre dtermine manuellement, puis configure avec ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...) (voir ALTER TABLE(7) pour plus
de dtails).
Si la table en cours d'analyse a un ou plusieurs enfants, ANALYZE rcuprera deux fois les statistiques : une fois sur les lignes de
la table parent seulement et une deuxime fois sur les lignes de la table parent et de tous ses enfants. Nanmoins, le dmon autovacuum ne considrera que les insertions et mises jour sur la table parent pour dcider du lancement automatique d'un ANALYZE.
Si des lignes sont rarement insres ou mises jour dans cette table, les statistiques d'hritage ne seront jour que si vous lancez
manuellement un ANALYZE.

Compatibilit
Il n'existe pas d'instruction ANALYZE dans le standard SQL.

Voir aussi
VACUUM(7), vacuumdb(1), Section 18.4.3, Report du VACUUM en fonction de son cot , Section 23.1.5, Le dmon autovacuum

911

Nom
BEGIN Dbuter un bloc de transaction

Synopsis
BEGIN [ WORK | TRANSACTION ] [ mode_transaction [, ...] ]
o mode_transaction peut tre :
ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ
UNCOMMITTED }
READ WRITE | READ ONLY
[ NOT ] DEFERRABLE

Description
BEGIN initie un bloc de transaction, c'est--dire que toutes les instructions apparaissant aprs la commande BEGIN sont excutes dans une seule transaction jusqu' ce qu'un COMMIT(7) ou ROLLBACK(7) explicite soit excut. Par dfaut (sans BEGIN), PostgreSQL excute les transactions en mode autocommit , c'est--dire que chaque instruction est excute dans sa
propre transaction et une validation (commit) est traite implicitement la fin de l'instruction (si l'excution a russi, sinon une
annulation est excute).
Les instructions sont excutes plus rapidement dans un bloc de transaction parce que la squence dbut/validation de transaction demande une activit significative du CPU et du disque. L'excution de plusieurs instructions dans une transaction est aussi
utile pour s'assurer d'une cohrence lors de la ralisation de certains modifications lies : les autres sessions ne voient pas les
tats intermdiaires tant que toutes les mises jour ne sont pas ralises.
Si le niveau d'isolation, le mode lecture/criture ou le mode diffrable sont spcifis, la nouvelle transaction possde ces caractristiques, comme si SET TRANSACTION(7) tait excute.

Paramtres
WORK, TRANSACTION
Mots cls optionnels. Ils n'ont pas d'effet.
SET TRANSACTION(7) prsente la signification des autres paramtres de cette instruction.

Notes
START TRANSACTION(7) a la mme fonctionnalit que BEGIN.
COMMIT(7) ou ROLLBACK(7) sont utiliss pour terminer un bloc de transaction.
Lancer BEGIN en tant dj dans un bloc de transaction provoque l'apparition d'un message d'avertissement, mais l'tat de la
transaction n'en est pas affect. Pour intgrer des transactions l'intrieur d'un bloc de transaction, les points de sauvegarde sont
utiliss (voir SAVEPOINT(7)).
Pour des raisons de compatibilit descendante, les virgules entre chaque mode_transaction peuvent tre omises.

Exemples
Commencer un bloc de transaction :
BEGIN;

Compatibilit
BEGIN, qui est une extension PostgreSQL, est quivalent la commande START TRANSACTION(7) du standard SQL. La
page de rfrence de cette commande contient des informations de compatibilit supplmentaires.
L'option DEFERRABLE de transaction_mode est une extension de PostgreSQL.
Le mot cl BEGIN est utilis dans un but diffrent en SQL embarqu. La smantique de la transaction doit tre tudie avec prcaution lors du portage d'applications.
912

BEGIN

Voir aussi
COMMIT(7), ROLLBACK(7), START TRANSACTION(7), SAVEPOINT(7)

913

Nom
CHECKPOINT Forcer un point de vrification dans le journal des transactions

Synopsis
CHECKPOINT

Description
Les WAL (Write-Ahead Log, journaux de transactions) placent un point de vrification dans le journal des transactions intervalle rgulier. (Pour ajuster cet intervalle, voir les options de configuration l'excution checkpoint_segments et checkpoint_timeout.) La commande CHECKPOINT force un point de vrification immdiat, sans attendre le point de vrification
planifi.
Un point de vrification est un point dans la squence du journal des transactions pour lequel tous les fichiers de donnes ont t
mis jour pour reflter l'information des journaux. Tous les fichiers de donnes sont crits sur le disque. Il convient de se rfrer
Chapitre 29, Fiabilit et journaux de transaction pour plus d'informations sur le systme WAL.
S'il est excut durant une restauration, la commande CHECKPOINT forcera un point de redmarrage plutt que l'criture d'un
nouveau point de vrification.
Seuls les superutilisateurs peuvent appeler CHECKPOINT. Cette commande ne doit pas tre utilise en fonctionnement normal.

Compatibilit
La commande CHECKPOINT est une extension PostgreSQL.

914

Nom
CLOSE Fermer un curseur

Synopsis
CLOSE { nom | ALL }

Description
CLOSE libre les ressources associes un curseur ouvert. Une fois le curseur ferm, aucune opration n'est autorise sur celuici. Un curseur doit tre ferm lorsqu'il n'est plus ncessaire.
Tout curseur volatil ouvert (NDT : On parle en anglais de non-holdable cursor, soit un curseur qui ne perdure pas audel de la transaction qui l'a cr) est ferm implicitement lorsqu'une transaction est termine avec COMMIT ou ROLLBACK.
Un curseur persistant (NDT : holdable cursor en anglais, ou curseur qui perdure au-del de la transaction initiale) est implicitement ferm si la transaction qui l'a cr est annule via ROLLBACK. Si cette transaction est valide (avec succs), ce
curseur reste ouvert jusqu' ce qu'une commande CLOSE explicite soit lance ou jusqu' la dconnexion du client.

Paramtres
name
Le nom du curseur ouvert fermer.
ALL
Ferme tous les curseurs ouverts.

Notes
PostgreSQL ne possde pas d'instruction explicite d'ouverture (OPEN) de curseur ; un curseur est considr ouvert sa dclaration. Un curseur est dclar l'aide de l'instruction DECLARE(7).
Vous pouvez voir tous les curseurs disponibles en excutant une requte sur la vue systme pg_cursors.
Si un curseur est ferm aprs un point de sauvegarde qui est annul par la suite, la commande CLOSE n'est pas annule ; autrement dit, le curseur reste ferm.

Exemples
Fermer le curseur liahona :
CLOSE liahona;

Compatibilit
CLOSE est totalement conforme au standard SQL. CLOSE ALL est une extension PostgreSQL.

Voir aussi
DECLARE(7), FETCH(7), MOVE(7)

915

Nom
CLUSTER Rorganiser une table en fonction d'un index

Synopsis
CLUSTER [VERBOSE] nom_table [ USING nom_index ]
CLUSTER [VERBOSE]

Description
CLUSTER rorganise (groupe) la table nom_table en fonction de l'index nom_index. L'index doit avoir t pralablement
dfini sur nom_table.
Une table reorganise est physiquement rordonne en fonction des informations de l'index. Ce regroupement est une opration
ponctuelle : les actualisations ultrieures ne sont pas rorganises. C'est--dire qu'aucune tentative n'est ralise pour stocker les
lignes nouvelles ou actualises d'aprs l'ordre de l'index. (Une rorganisation priodique peut tre obtenue en relanant la commande aussi souvent que souhait. De plus, configurer le paramtre FILLFACTOR moins de 100% peut aider prserver
l'ordre du cluster lors des mises jour car les lignes mises jour sont conserves dans la mme page si suffisamment d'espace
est disponible ici.)
Quand une table est rorganise, PostgreSQL enregistre l'index utilis cet effet. La forme CLUSTER nom_table rorganise la table en utilisant le mme index qu'auparavant. Vous pouvez aussi utiliser les formes CLUSTER ou SET WITHOUT
CLUSTER de ALTER TABLE(7) pour initialiser l'index de faon ce qu'il soit intgr aux prochaines oprations cluster our
pour supprimer tout prcdent paramtre.
CLUSTER, sans paramtre, rorganise toutes les tables de la base de donnes courante qui ont dj t rorganises et dont
l'utilisateur est propritaire, ou toutes les tables s'il s'agit d'un superutilisateur. Cette forme de CLUSTER ne peut pas tre excute l'intrieur d'une transaction.
Quand une table est en cours de rorganisation, un verrou ACCESS EXCLUSIVE est acquis. Cela empche toute opration sur
la table ( la fois en lecture et en criture) pendant l'excution de CLUSTER.

Paramtres
nom_table
Le nom d'une table (ventuellement qualifi du nom du schma).
nom_index
Le nom d'un index.
VERBOSE
Affiche la progression pour chaque table traite.

Notes
Lorsque les lignes d'une table sont accdes alatoirement et unitairement, l'ordre rel des donnes dans la table n'a que peu
d'importance. Toutefois, si certaines donnes sont plus accdes que d'autres, et qu'un index les regroupe, l'utilisation de CLUSTER peut s'avrer bnfique. Si une requte porte sur un ensemble de valeurs indexes ou sur une seule valeur pour laquelle
plusieurs lignes de la table correspondent, CLUSTER est utile. En effet, lorsque l'index identifie la page de la table pour la premire ligne correspondante, toutes les autres lignes correspondantes sont dj probablement sur la mme page de table, ce qui
diminue les accs disque et acclre la requte.
CLUSTER peut trier de nouveau en utilisant soit un parcours de l'index spcifi soit (si l'index est un Btree) un parcours squentiel suivi d'un tri. Il choisira la mthode qui lui semble la plus rapide, en se basant sur les paramtres de cot du planificateur et sur les statistiques disponibles.
Quand un parcours d'index est utilis, une copie temporaire de la table est cre. Elle contient les donnes de la table dans
l'ordre de l'index. Des copies temporaires de chaque index sur la table sont aussi cres. Du coup, vous devez disposer d'un espace libre sur le disque d'une taille au moins gale la somme de la taille de la table et des index.
Quand un parcours squentiel suivi d'un tri est utilis, un fichier de tri temporaire est aussi cr. Donc l'espace temporaire requis
correspond au maximum le double de la taille de la table et des index. Cette mthode est gnralement plus rapide que le parcours d'index mais si le besoin en espace disque est trop important, vous pouvez dsactiver ce choix en dsactivant temporairement enable_sort (off).
916

CLUSTER

Il est conseill de configurer maintenance_work_mem une valeur suffisamment large (mais pas plus importante que la quantit
de mmoire que vous pouvez ddier l'opration CLUSTER) avant de lancer la commande.
Puisque le planificateur enregistre les statistiques d'ordonnancement des tables, il est conseill de lancer ANALYZE(7) sur la table
nouvellement rorganise. Dans le cas contraire, les plans de requtes peuvent tre mal choisis par le planificateur.
Comme CLUSTER se rappelle les index utiliss pour cette opration, un utilisateur peut excuter manuellement des commandes
CLUSTER une premire fois, puis configurer un script de maintenance priodique qui n'excutera qu'un CLUSTER sans paramtres, pour que les tables soient frquemment tries physiquement.

Exemples
Rorganiser la table employes sur la base de son index employes_ind :
CLUSTER employes ON employes_ind;
Rorganiser la relation employes en utilisant le mme index que prcdemment :
CLUSTER employes;
Rorganiser toutes les tables de la base de donnes qui ont dj t pralablement rorganises :
CLUSTER;

Compatibilit
Il n'existe pas d'instruction CLUSTER dans le standard SQL.
La syntaxe
CLUSTER nom_index ON nom_table
est aussi supporte pour la compatibilit avec les versions de PostgreSQL antrieures la 8.3.

Voir aussi
clusterdb(1)

917

Nom
COMMENT Dfinir ou modifier le commentaire associ un objet

Synopsis
COMMENT ON
{
AGGREGATE nom_agrgat (type_agrgat [, ...] ) |
CAST (type_source AS type_cible) |
COLLATION nom_objet |
COLUMN nom_relation.nom_colonne |
CONSTRAINT nom_contrainte ON nom_table |
CONVERSION nom_objet |
DATABASE nom_objet |
DOMAIN nom_objet |
EXTENSION nom_objet |
FOREIGN DATA WRAPPER nom_objet |
FOREIGN TABLE nom_objet |
FUNCTION nom_fonction ( [ [ modearg ] [ nomarg ] typearg [, ...] ] ) |
INDEX nom_objet |
LARGE OBJECT oid_large_objet |
OPERATOR op (type_operande1, type_operande2) |
OPERATOR CLASS nom_objet USING mthode_indexage |
OPERATOR FAMILY nom_objet USING methode_index |
ROLE nom_objet |
RULE nom_rgle ON nom_table |
SCHEMA nom_objet |
SEQUENCE nom_objet |
SERVER nom_objet |
TABLE nom_objet |
TABLESPACE nom_objet |
TEXT SEARCH CONFIGURATION nom_objet |
TEXT SEARCH DICTIONARY nom_objet |
TEXT SEARCH PARSER nom_objet |
TEXT SEARCH TEMPLATE nom_objet |
TRIGGER nom_dclencheur ON nom_table |
TYPE nom_objet |
VIEW nom_objet
} IS 'texte'

Description
COMMENT stocke un commentaire sur un objet de la base de donnes.
Seule une chane de commentaire est stocke pour chaque objet, donc pour modifier un commentaire, lancer une nouvelle commande COMMENT pour le mme objet. Pour supprimer un commentaire, crire un NULL la place dans la chane de texte.
Les commentaires sont automatiquement supprimes quand leur objet est supprim.
Pour la plupart des types d'objet, seul le propritaire de l'objet peut configurer le commentaire. Les rles n'ont pas de propritaires, donc la rgle pour COMMENT ON ROLE est que vous devez tre superutilisateur pour commenter un rle superutilisateur
ou avoir l'attribut CREATEROLE pour commenter des rles standards. Bien sr, un superutilisateur peut ajouter un commentaire
sur n'importe quel objet.
Les commentaires sont visibles avec la famille de commandes \d, de psql. D'autres interfaces utilisateur de rcupration des
commentaires peuvent tre construites au-dessus des fonctions intgres qu'utilise psql, savoir obj_description,
col_description et shobj_description. (Voir Tableau 9.51, Fonctions d'informations sur les commentaires .)

Paramtres
nom_objet, nom_relation.nom_colonne, nom_agrgat, nom_contrainte, nom_fonction, op,
nom_oprateur, nom_rgle, nom_dclencheur
Le nom de l'objet commenter. Les noms des tables, agrgats, collationnements, conversions, domaines, tables distantes,
fonctions, index, oprateurs, classes d'oprateur, familles d'oprateur, squences, objets de la recherche plein texte, types et
vues peuvent tre qualifis du nom du schma. Lorsque le commentaire est plac sur une colonne, nom_relation doit
faire rfrence une table, une vue, un type composite ou une table distante.
918

COMMENT

type_agrgat
Un type de donnes en entre sur lequel l'agrgat opre. Pour rfrencer une fonction d'agrgat sans argument, utilisez * la
place de la liste des types de donnes en entre.
type_source
Le nom du type de donne source du transtypage.
type_cible
Le nom du type de donnes cible du transtypage.
modearg
Le mode d'un argument de la fonction : IN, OUT, INOUT ou VARIADIC. En cas d'omission, la valeur par dfaut est IN.
COMMENT ON FUNCTION ne tient pas compte, l'heure actuelle, des arguments OUT car seuls ceux en entre sont ncessaires pour dterminer l'identit de la fonction. Lister les arguments IN, INOUT et VARIADIC est ainsi suffisant.
nomarg
Le nom d'un argument de la fonction. COMMENT ON FUNCTION ne tient pas compte, l'heure actuelle, des noms des arguments, seuls les types de donnes des arguments tant ncessaires pour dterminer l'identit de la fonction.
typearg
Les types de donnes des arguments de la fonction (ventuellement qualifis du nom du schma).
oid_objet_large
L'OID de l'objet large.
type_gauche, type_droit
Les types de donnes des arguments de l'oprateur (avec en option le nom du schma). crire NONE pour l'argument manquant d'un oprateur prfixe ou postfixe.
PROCEDURAL
Inutilis.
texte
Le nouveau commentaire, rdig sous la forme d'une chane littrale ; ou NULL pour supprimer le commentaire.

Notes
Il n'existe pas de mcanisme de scurit pour visualiser les commentaires : tout utilisateur connect une base de donnes peut
voir les commentaires de tous les objets de la base. Pour les objets partags comme les bases, les rles et les tablespaces, les commentaires sont stockes globalement et tout utilisateur connect une base peut voir tous les commentaires pour les objets partags. Du coup, ne placez pas d'informations critiques pour la scurit dans vos commentaires.

Exemples
Attacher un commentaire la table matable :
COMMENT ON TABLE matable IS 'Ceci est ma table.';
Suppression du commentaire prcdent :
COMMENT ON TABLE matable IS NULL;
Quelques exemples supplmentaires :
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
base';
COMMENT
COMMENT
COMMENT
COMMENT

ON
ON
ON
ON
ON
ON
ON
ON
ON
ON
ON

AGGREGATE mon_agregat (double precision) IS 'Calcul d'une variance type';


CAST (text AS int4) IS 'Transtypage de text en int4';
COLLATION "fr_CA" IS 'Canadian French';
COLUMN ma_table.ma_colonne IS 'Numro employ';
CONVERSION ma_conv IS 'Conversion vers UTF8';
CONSTRAINT bar_col_cons ON bar IS 'Constrainte sur la colonne col';
DATABASE ma_base IS 'Base de donnes de dveloppement';
DOMAIN mon_domaine IS 'Domaine des adresses de courriel';
EXTENSION hstore IS 'implmente le type de donnes hstore';
FOREIGN DATA WRAPPER mon_wrapper IS 'mon wrapper de donnes distantes';
FOREIGN TABLE ma_table_distante IS 'Information employs dans une autre

ON
ON
ON
ON

FUNCTION ma_fonction (timestamp)


INDEX mon_index IS 'S'assurer de
LANGUAGE plpython IS 'Support de
LARGE OBJECT 346344 IS 'Document

IS 'Retourner des chiffres romains';


l'unicit de l'ID de l'employ';
Python pour les procedures stockes';
de planification';

919

COMMENT

COMMENT ON OPERATOR ^ (text, text) IS 'L\'intersection de deux textes';


COMMENT ON OPERATOR - (NONE, integer) IS 'Moins unaire';
COMMENT ON OPERATOR CLASS int4ops USING btree IS 'Oprateurs d'entiers sur quatre
octets pour les index btrees';
COMMENT ON OPERATOR FAMILY integer_ops USING btree IS 'Tous les oprateurs entiers pour
les index btree';
COMMENT ON ROLE mon_role IS 'Groupe d'administration pour les tables finance';
COMMENT ON RULE ma_regle ON my_table IS 'Tracer les mises jour des enregistrements
d\'employ';
COMMENT ON SCHEMA mon_schema IS 'Donnes du dpartement';
COMMENT ON SEQUENCE ma_sequence IS 'Utilis pour engendrer des cls primaires';
COMMENT ON SERVER mon_serveur IS 'mon serveur distant';
COMMENT ON TABLE mon_schema.ma_table IS 'Informations sur les employs';
COMMENT ON TABLESPACE mon_tablespace IS 'Tablespace pour les index';
COMMENT ON TEXT SEARCH CONFIGURATION my_config IS 'Filtre des mots spciaux';
COMMENT ON TEXT SEARCH DICTIONARY swedish IS 'Stemmer Snowball pour le sudois';
COMMENT ON TEXT SEARCH PARSER my_parser IS 'Divise le texte en mot';
COMMENT ON TEXT SEARCH TEMPLATE snowball IS 'Stemmer Snowball';
COMMENT ON TRIGGER mon_declencheur ON my_table IS 'Utilis pour RI';
COMMENT ON TYPE complex IS 'Type de donnes pour les nombres complexes';
COMMENT ON VIEW ma_vue IS 'Vue des cots dpartementaux';

Compatibilit
Il n'existe pas de commande COMMENT dans le standard SQL.

920

Nom
COMMIT Valider la transaction en cours

Synopsis
COMMIT [ WORK | TRANSACTION ]

Description
COMMIT valide la transaction en cours. Tout le monde peut dsormais voir les modifications ralises au cours de la transaction. De plus, leur persistance est garantie en cas d'arrt brutal du serveur.

Paramtres
WORK, TRANSACTION
Mots cls optionnels et sans effet.

Notes
ROLLBACK(7) est utilis pour annuler une transaction.
Lancer COMMIT l'extrieur d'une transaction n'a aucune consquence mais provoque l'affichage d'un message
d'avertissement.

Exemples
Valider la transaction courante et rendre toutes les modifications persistantes :
COMMIT;

Compatibilit
Le standard SQL ne spcifie que les deux formes COMMIT et COMMIT WORK. Pour le reste, cette commande est totalement
conforme.

Voir aussi
BEGIN(7), ROLLBACK(7)

921

Nom
COMMIT PREPARED Valider une transaction pralablement prpare en vue d'une validation en deux phases

Synopsis
COMMIT PREPARED id_transaction

Description
COMMIT PREPARED valide une transaction prpare.

Paramtres
id_transaction
L'identifiant de la transaction valider.

Notes
Seul l'utilisateur l'origine de la transaction ou un superutilisateur peut valider une transaction prpare. Il n'est cependant pas
ncessaire d'tre dans la session qui a initi la transaction.
Cette commande ne peut pas tre excute l'intrieur d'un bloc de transaction. La transaction prpare est valide immdiatement.
Toutes les transactions prpares disponibles sont listes dans la vue systme pg_prepared_xacts.

Exemples
Valider la transaction identifie par foobar :
COMMIT PREPARED 'foobar';

Voir aussi
PREPARE TRANSACTION(7), ROLLBACK PREPARED(7)

922

Nom
COPY Copier des donnes depuis/vers un fichier vers/depuis une table

Synopsis
COPY nom_table [ ( colonne [, ...] ) ]
FROM { 'nom_fichier' | STDIN }
[ [ WITH ] ( option [, ...] ) ]
COPY { nom_table [ ( colonne [, ...] ) ] | ( requte ) }
TO { 'nom_fichier' | STDOUT }
[ [ WITH ] ( option [, ...] ) ]
o option fait partie
de :
FORMAT nom_format
OIDS [ oids ]
DELIMITER 'caractre_dlimiteur'
NULL 'chane_null'
HEADER [ boolean ]
QUOTE 'caractre_guillemet'
ESCAPE 'caractre_chappement'
FORCE_QUOTE { ( colonne [, ...] ) | * }
FORCE_NOT_NULL ( colonne [, ...] )
ENCODING 'nom_encodage'

Description
COPY transfre des donnes entre les tables de PostgreSQL et les fichiers du systme de fichiers standard. COPY TO copie
le contenu d'une table vers un fichier tandis que COPY FROM copie des donnes depuis un fichier vers une table (ajoutant les
donnes celles dj dans la table). COPY TO peut aussi copier le rsultat d'une requte SELECT.
Si une liste de colonnes est prcise, COPY ne copie que les donnes des colonnes spcifies vers ou depuis le fichier. COPY
FROM insre les valeurs par dfaut des colonnes qui ne sont pas prcises dans la liste.
Si un nom de fichier est prcis, COPY lit ou crit directement dans le fichier. Ce fichier doit tre accessible par le serveur et
son nom doit tre spcifi du point de vue du serveur. Si STDIN ou STDOUT est indiqu, les donnes sont transmises au travers
de la connexion entre le client et le serveur.

Paramtres
nom_table
Le nom de la table (ventuellement qualifi du nom du schma).
colonne
Une liste optionnelle de colonnes copier. Sans prcision, toutes les colonnes de la table seront copies.
requte
Une commande SELECT(7) ou VALUES(7) dont les rsultats doivent tre copis. Notez que les parenthses sont requises
autour de la requte.
nom_fichier
Le chemin absolu du fichier en entre ou en sortie. Les utilisateurs sous Windows peuvent avoir besoin d'utiliser une chane
E'' et de doubler tous les antislashs utiliss comme sparateurs de chemin.
STDIN
Les donnes en entre proviennent de l'application cliente.
STDOUT
Les donnes en sortie vont sur l'application cliente.
boolean
Spcifie si l'option slectionne doit tre active ou non. Vous pouvez crire TRUE, ON ou 1 pour activer l'option, et
FALSE, OFF ou 0 pour la dsactiver. La valeur boolean peut aussi tre omise, auquel cas la valeur TRUE est prise en
923

COPY

compte.
FORMAT
Slectionne le format des donnes pour la lecture ou l'criture : text, csv (valeurs spares par des virgules), ou binary.
la valeur par dfaut est text.
OIDS
Copie l'OID de chaque ligne. Une erreur est rapporte si OIDS est utilis pour une table qui ne possde pas d'OID, ou dans le
cas de la copie du rsultat d'une requte.
DELIMITER
Spcifie le caractre qui spare les colonnes sur chaque ligne du fichier. La valeur par dfaut est une tabulation dans le format
texte et une virgule dans le format CSV. Il doit tre un seul caractre sur un seul octet. Cette option n'est pas autorise lors de
l'utilisation du format binary.
NULL
Spcifie la chane qui reprsente une valeur NULL. La valeur par dfaut est \N (antislash-N) dans le format texte et une
chane vide sans guillemets dans le format CSV. Vous pouvez prfrer une chane vide mme dans le format texte pour les cas
o vous ne voulez pas distinguer les valeurs NULL des chanes vides. Cette option n'est pas autorise lors de l'utilisation du
format binary.

Note
Lors de l'utilisation de COPY FROM, tout lment de donnes qui correspond cette chane est stock
comme valeur NULL. Il est donc utile de s'assurer que c'est la mme chane que celle prcise pour le COPY
TO qui est utilise.
HEADER
Le fichier contient une ligne d'en-tte avec les noms de chaque colonne. En sortie, la premire ligne contient les noms de colonne de la table. En entre, elle est ignore. Cette option n'est autorise que lors de l'utilisation du format CSV.
QUOTE
Spcifie le caractre guillemet utiliser lorsqu'une valeur doit tre entre guillemets. Par dfaut, il s'agit du guillemet double.
Cela doit de toute faon tre un seul caractre sur un seul octet. Cette option n'est autorise que lors de l'utilisation du format
CSV.
ESCAPE
Spcifie le caractre qui doit apparatre avant un caractre de donnes qui correspond la valeur QUOTE. La valeur par dfaut
est la mme que la valeur QUOTE (du coup, le caractre guillemet est doubl s'il apparat dans les donnes). Cela doit tre un
seul caractre cod en un seul octet. Cette option n'est autorise que lors de l'utilisation du format CSV.
FORCE_QUOTE
Force l'utilisation des guillemets pour toutes les valeurs non NULL dans chaque colonne spcifie. La sortie NULL n'est jamais
entre guillemets. Si * est indiqu, les valeurs non NULL seront entre guillemets pour toutes les colonnes. Cette option est
seulement autorise avec COPY TO et seulement quand le format CSV est utilis.
FORCE_NOT_NULL
Ne fait pas correspondre les valeurs des colonnes spcifies avec la chane nulle. Dans le cas par dfaut o la chane nulle est
vide, cela signifie que les valeurs vides seront lues comme des chanes de longueur nulle plutt que comme des NULL, mme
si elles ne sont pas entre guillemets. Cette option est seulement autorise avec COPY FROM et seulement quand le format
CSV est utilis.
ENCODING
Spcifie que le fichier est dans l'encodage nom_encodage. Si cette option est omis, l'encodage client par dfaut est utilis.
Voir la partie Notes ci-dessous pour plus de dtails.

Affichage
En cas de succs, une commande COPY renvoie une balise de la forme
COPY nombre
Le nombre correspond au nombre de lignes copies.

Notes
924

COPY

COPY ne peut tre utilis qu'avec des tables relles, pas avec des vues. Nanmoins, vous pouvez crire COPY (SELECT *
FROM nom_vue) TO ....
COPY gre seulement la table nomme ; cette commande ne copie pas les donnes provenant ou vers des tables filles. Donc, par
exemple, COPY table TO affiche les mmes donnes que SELECT * FROM ONLY table. Mais COPY (SELECT *
FROM table) TO ... peut tre utilis pour sauvegarder toutes les donnes d'un hritage.
Le droit SELECT est requis sur la table dont les valeurs sont lues par COPY TO et le droit INSERT sur la table dont les valeurs
sont insres par COPY FROM. Il est suffisant d'avoir des droits sur les colonnes listes dans la commande.
Les fichiers nomms dans une commande COPY sont lus ou crits directement par le serveur, non par l'application cliente. De ce
fait, la machine hbergeant le serveur de bases de donnes doit les hberger ou pouvoir y accder. L'utilisateur PostgreSQL
(l'identifiant de l'utilisateur qui excute le serveur), non le client, doit pouvoir y accder et les lire ou les modifier. L'utilisation de
COPY avec un fichier n'est autoris qu'aux superutilisateurs de la base de donnes car COPY autorise la lecture et l'criture de
tout fichier accessible au serveur.
Il ne faut pas confondre COPY et l'instruction \copy de psql. \copy appelle COPY FROM STDIN ou COPY TO STDOUT, puis
lit/stocke les donnes dans un fichier accessible au client psql. L'accs au fichier et les droits d'accs dpendent alors du client et
non du serveur.
Il est recommand que le chemin absolu du fichier utilis dans COPY soit toujours prcis. Ceci est assur par le serveur dans le
cas d'un COPY TO mais, pour les COPY FROM, il est possible de lire un fichier spcifi par un chemin relatif. Le chemin est
interprt relativement au rpertoire de travail du processus serveur (habituellement dans le rpertoire des donnes), pas par rapport au rpertoire de travail du client.
COPY FROM appelle tous les dclencheurs et contraintes de vrification sur la table de destination, mais pas les rgles.
L'entre et la sortie de COPY sont sensibles datestyle. Pour assurer la portabilit vers d'autres installations de
PostgreSQL qui ventuellement utilisent des paramtrages datestyle diffrents de ceux par dfaut, il est prfrable de configurer datestyle en ISO avant d'utiliser COPY TO. viter d'exporter les donnes avec le IntervalStyle configur
sql_standard est aussi une bonne ide car les valeurs ngatives d'intervalles pourraient tre mal interprtes par un serveur
qui a une autre configuration pour IntervalStyle.
Les donnes en entre sont interprtes suivant la clause ENCODING ou suivant l'encodage actuel du client. Les donnes en sortie
sont codes suivant la clause ENCODING ou suivant l'encodage actuel du client. Ceci est valable mme si les donnes ne passent
pas par le client, c'est--dire si elles sont lues et crites directement sur un fichier du serveur.
COPY stoppe l'opration la premire erreur. Si cela ne porte pas consquence dans le cas d'un COPY TO, il en va diffremment dans le cas d'un COPY FROM. Dans ce cas, la table cible a dj reu les lignes prcdentes. Ces lignes ne sont ni visibles,
ni accessibles, mais occupent de l'espace disque. Il peut en rsulter une perte importante d'espace disque si l'chec se produit lors
d'une copie volumineuse. L'espace perdu peut alors tre rcupr avec la commande VACUUM.
Les donnes en entre sont interprtes suivant l'encodage actuel du client et les donnes en sortie sont encodes suivant
l'encodage client mme si les donnes ne passent pas par le client mais sont lues partir d'un fichier ou crites dans un fichier.

Formats de fichiers
Format texte
Quand le format text est utilis, les donnes sont lues ou crites dans un fichier texte, chaque ligne correspondant une ligne de
la table. Les colonnes sont spares, dans une ligne, par le caractre de dlimitation. Les valeurs des colonnes sont des chanes, engendres par la fonction de sortie ou utilisables par celle d'entre, correspondant au type de donnes des attributs. La chane de
spcification des valeurs NULL est utilise en lieu et place des valeurs nulles. COPY FROM lve une erreur si une ligne du fichier ne contient pas le nombre de colonnes attendues. Si OIDS est prcis, l'OID est lu ou crit dans la premire colonne, avant
celles des donnes utilisateur.
La fin des donnes peut tre reprsente par une ligne ne contenant qu'un antislash et un point (\.). Ce marqueur de fin de donnes n'est pas ncessaire lors de la lecture d'un fichier, la fin du fichier tenant ce rle. Il n'est rellement ncessaire que lors d'une
copie de donnes vers ou depuis une application cliente qui utilise un protocole client antrieur au 3.0.
Les caractres antislash (\) peuvent tre utiliss dans les donnes de COPY pour chapper les caractres qui, sans cela, seraient
considrs comme des dlimiteurs de ligne ou de colonne. Les caractres suivants, en particulier, doivent tre prcds d'un antislash s'ils apparaissent dans la valeur d'une colonne : l'antislash lui-mme, le saut de ligne, le retour chariot et le dlimiteur courant.
La chane NULL spcifie est envoye par COPY TO sans ajout d'antislash ; au contraire, COPY FROM teste l'entre au regard
de la chane NULL avant la suppression des antislash. Ainsi, une chane NULL telle que \N ne peut pas tre confondue avec la
valeur de donne relle \N (reprsente dans ce cas par \\N).
925

COPY

Les squences spciales suivantes sont reconnues par COPY FROM :


Squence

Reprsente

\b

Retour arrire (backspace) (ASCII 8)

\f

Retour chariot (ASCII 12)

\n

Nouvelle ligne (ASCII 10)

\r

Retour chariot (ASCII 13)

\t

Tabulation (ASCII 9)

\v

Tabulation verticale (ASCII 11)

\chiffres

Antislash suivi d'un trois chiffres en octal reprsente le caractre qui possde ce
code numrique

\xdigits

Antislash x suivi d'un ou deux chiffres hexadcimaux reprsente le caractre qui possde ce code numrique

Actuellement, COPY TO n'met pas de squence octale ou hexadcimale mais utilise les autres squences listes ci-dessus pour
les caractres de contrle.
Tout autre caractre prcd d'un antislash se reprsente lui-mme. Cependant, il faut faire attention ne pas ajouter d'antislash
qui ne soit pas absolument ncessaire afin d'viter le risque d'obtenir accidentellement une correspondance avec le marqueur de fin
de donnes (\.) ou la chane NULL (\N par dfaut) ; ces chanes sont reconnues avant tout traitement des antislashs.
Il est fortement recommand que les applications qui engendrent des donnes COPY convertissent les donnes de nouvelle ligne
et de retour chariot par les squences respectives \n et \r. A l'heure actuelle, il est possible de reprsenter un retour chariot par un
antislash et un retour chariot, et une nouvelle ligne par un antislash et une nouvelle ligne. Cependant, il n'est pas certain que ces
reprsentations soient encore acceptes dans les prochaines versions. Celles-ci sont, de plus, extrmement sensibles la corruption
si le fichier de COPY est transfr sur d'autres plateformes (d'un Unix vers un Windows ou inversement, par exemple).
COPY TO termine chaque ligne par une nouvelle ligne de style Unix ( \n ). Les serveurs fonctionnant sous Microsoft Windows engendrent un retour chariot/nouvelle ligne ( \r\n ), mais uniquement lorsque les donnes engendres par COPY sont
envoyes dans un fichier sur le serveur. Pour des raisons de cohrence entre les plateformes, COPY TO STDOUT envoie toujours \n quelque soit la plateforme du serveur. COPY FROM sait grer les lignes terminant par une nouvelle ligne, un retour
chariot ou un retour chariot suivi d'une nouvelle ligne. Afin de rduire les risques d'erreurs engendres par des nouvelles lignes ou
des retours chariot non prcds d'antislash, considr de fait comme des donnes, COPY FROM met un avertissement si les
fins de lignes ne sont pas toutes identiques.

Format CSV
Ce format est utilis pour importer et exporter des donnes au format de fichier CSV (acronyme de Comma Separated Value, littralement valeurs spares par des virgules). Ce format est utilis par un grand nombre de programmes, tels les tableurs. la place
des rgles d'chappement utilises par le format texte standard de PostgreSQL, il produit et reconnat le mcanisme
d'chappement habituel de CSV.
Les valeurs de chaque enregistrement sont spares par le caractre DELIMITER. Si la valeur contient ce caractre, le caractre
QUOTE, la chane NULL, un retour chariot ou un saut de ligne, la valeur complte est prfixe et suffixe par le caractre QUOTE.
De plus, toute occurrence du caractre QUOTE ou du caractre ESCAPE est prcde du caractre d'chappement. FORCE QUOTE
peut galement tre utilis pour forcer les guillemets lors de l'affichage de valeur non-NULL dans des colonnes spcifiques.
Le format CSV n'a pas de faon standard de distinguer une valeur NULL d'une chane vide. La commande COPY de
PostgreSQL gre cela avec les guillemets. Un NULL est affich suivant le paramtre NULL et n'est pas entre guillemets, alors
qu'une valeur non NULL correspondant au paramtre NULL est entre guillemets. Par exemple, avec la configuration par dfaut, un
NULL est crit avec la chane vide sans guillemets alors qu'une chane vide est crit avec des guillemets doubles (""). La lecture
des valeurs suit des rgles similaires. Vous pouvez utiliser FORCE NOT NULL pour empcher les comparaisons d'entre NULL
pour des colonnes spcifiques.
L'antislash n'est pas un caractre spcial dans le format CSV. De ce fait, le marqueur de fin de donnes, \., peut apparatre dans
les donne. Afin d'viter toute mauvaise interprtation, une valeur \. qui apparat seule sur une ligne est automatiquement place
entre guillemets en sortie. En entre, si elle est entre guillemets, elle n'est pas interprte comme un marqueur de fin de donnes.
Lors du chargement d'un fichier qui ne contient qu'une colonne, dont les valeurs ne sont pas places entre guillemets, cr par une
autre application, qui contient une valeur \., il est ncessaire de placer cette valeur entre guillemets.

Note
926

COPY

Dans le format CSV, tous les caractres sont significatifs. Une valeur entre guillemets entoure d'espaces ou de tout
autre caractre diffrent de DELIMITER inclut ces caractres. Cela peut tre source d'erreurs en cas d'import de
donnes partir d'un systme qui complte les lignes CSV avec des espaces fines pour atteindre une longueur fixe.
Dans ce cas, il est ncessaire de pr-traiter le fichier CSV afin de supprimer les espaces de compltement avant
d'insrer les donnes dans PostgreSQL.

Note
Le format CSV sait reconnatre et produire des fichiers CSV dont les valeurs entre guillemets contiennent des retours chariot et des sauts de ligne. De ce fait, les fichiers ne contiennent pas strictement une ligne par ligne de table
comme les fichiers du format texte.

Note
Beaucoup de programmes produisent des fichiers CSV tranges et parfois pervers ; le format de fichier est donc
plus une convention qu'un standard. Il est alors possible de rencontrer des fichiers que ce mcanisme ne sait pas importer. De plus, COPY peut produire des fichiers inutilisables par d'autres programmes.

Format binaire
Le format binary fait que toutes les donnes sont stockes/lues au format binaire plutt que texte. Il est un peu plus rapide que
les formats texte et CSV mais un fichier au format binaire est moins portable suivant les architectures des machines et les versions
de PostgreSQL. De plus, le format binaire est trs spcifique au type des donnes ; par exemple, un export de donnes binaires
d'une colonne smallint ne pourra pas tre import dans une colonne integer, mme si cela aurait fonctionn dans le format texte.
Le format de fichier binary consiste en un en-tte de fichier, zro ou plusieurs lignes contenant les donnes de la ligne et un basde-page du fichier. Les en-ttes et les donnes sont dans l'ordre rseau des octets.

Note
Les versions de PostgreSQL antrieures la 7.4 utilisaient un format de fichier binaire diffrent.
Entte du fichier

L'en-tte du fichier est constitute de 15 octets de champs fixes, suivis par une aire d'extension de l'en-tte de longueur variable.
Les champs fixes sont :
Signature
squence de 11 octets PGCOPY\n\377\r\n\0 -- l'octet zro est une partie obligatoire de la signature. La signature est
conue pour permettre une identification aise des fichiers qui ont t dteriors par un transfert non respectueux des huit bits.
Cette signature est modifie par les filtres de traduction de fin de ligne, la suppression des octets zro, la suppression des bits
de poids forts ou la modification de la parit.
Champs de commutateurs
masque entier de 32 bits dcrivant les aspects importants du format de fichier. Les bits sont numrots de 0 (LSB, ou Least Significant Bit, bit de poids faible) 31 (MSB, ou Most Significant Bit, bit de poids fort). Ce champ est stock dans l'ordre rseau des octets (l'octet le plus significatif en premier), comme le sont tous les champs entier utiliss dans le format de fichier.
Les bits 16 31 sont rservs aux problmes critiques de format de fichier ; tout lecteur devrait annuler l'opration s'il trouve
un bit inattendu dans cet ensemble. Les bits 0 15 sont rservs pour signaler les problmes de compatibilit de formats ; un
lecteur devrait simplement ignorer les bits inattendus dans cet ensemble. Actuellement, seul un bit est dfini, le reste doit tre
zro :
Bit 16
si 1, les OID sont inclus dans la donne ; si 0, non
Longueur de l'aire d'extension de l'en-tte
entier sur 32 bits, longueur en octets du reste de l'en-tte, octets de stockage de la longueur non-compris. l'heure actuelle ce
champ vaut zro. La premire ligne suit immdiatement. De futures modifications du format pourraient permettre la prsence
de donnes supplmentaires dans l'en-tte. Tout lecteur devrait ignorer silencieusement toute donne de l'extension de
l'en-tte qu'il ne sait pas traite.

927

COPY

L'aire d'extension de l'en-tte est prvue pour contenir une squence de morceaux s'auto-identifiant. Le champ de commutateurs
n'a pas pour but d'indiquer aux lecteurs ce qui se trouve dans l'aire d'extension. La conception spcifique du contenu de l'extension
de l'en-tte est pour une prochaine version.
Cette conception permet l'ajout d'en-ttes compatible (ajout de morceaux d'extension d'en-tte, ou initialisation des octets commutateurs de poids faible) et les modifications non compatibles (initialisation des octets commutateurs de poids fort pour signaler de
telles modifications, et ajout des donnes de support dans l'aire d'extension si ncessaire).
Tuples

Chaque tuple dbute par un compteur, entier cod sur 16 bits, reprsentant le nombre de champs du tuple. (Actuellement, tous les
tuples d'une table ont le mme compteur, mais il est probable que cela ne soit pas toujours le cas.) On trouve ensuite, rpt pour
chaque champ du tuple, un mot de 32 bits annonant le nombre d'octets de stockage de la donne qui suivent. (Ce mot n'inclut pas
sa longueur propre et peut donc tre nul.) -1, cas spcial, indique une valeur de champ NULL. Dans ce cas, aucun octet de valeur
ne suit.
Il n'y a ni compltement d'alignement ni toute autre donne supplmentaire entre les champs.
Actuellement, toutes les valeurs d'un fichier d'un format binaire sont supposes tre dans un format binaire (code de format). Il est
probable qu'une extension future ajoute un champ d'en-tte autorisant la spcification de codes de format par colonne.
La consultation du code source de PostgreSQL, et en particulier les fonctions *send et *recv associes chaque type de donnes de la colonne, permet de dterminer le format binaire appropri la donne relle. Ces fonctions se situent dans le rpertoire
src/backend/utils/adt/ des sources.
Lorsque les OID sont inclus dans le fichier, le champ OID suit immdiatement le compteur de champ. C'est un champ normal,
ceci prs qu'il n'est pas inclus dans le compteur. En fait, il contient un mot de stockage de la longueur -- ceci permet de faciliter le
passage d'OID sur quatre octets aux OID sur huit octets et permet d'afficher les OID comme tant NULL en cas de besoin.
Queue du fichier

La fin du fichier consiste en un entier sur 16 bits contenant -1. Cela permet de le distinguer aisment du compteur de champs d'un
tuple.
Il est souhaitable que le lecteur rapporte une erreur si le mot compteur de champ ne vaut ni -1 ni le nombre attendu de colonnes.
Cela assure une vrification supplmentaire d'une ventuelle dsynchronisation d'avec les donnes.

Exemples
Copier une table vers le client en utilisant la barre verticale (|) comme dlimiteur de champ :
COPY pays TO STDOUT (DELIMITER '|');
Copier des donnes d'un fichier vers la table pays :
COPY pays FROM '/usr1/proj/bray/sql/pays_donnees';
Pour copier dans un fichier les pays dont le nom commence par 'A' :
COPY (SELECT * FROM pays WHERE nom_pays LIKE 'A%') TO
'/usr1/proj/bray/sql/une_liste_de_pays.copy';
Exemple de donnes convenables pour une copie vers une table depuis STDIN :
AF
AL
DZ
ZM
ZW

AFGHANISTAN
ALBANIE
ALGERIE
ZAMBIE
ZIMBABWE

L'espace sur chaque ligne est en fait un caractre de tabulation.


Les mmes donnes, extraites au format binaire. Les donnes sont affiches aprs filtrage au travers de l'outil Unix od -c. La table
a trois colonnes ; la premire est de type char(2), la deuxime de type text et la troisime de type integer. Toutes les lignes ont une
valeur NULL sur la troisime colonne.
0000000
0000020
0000040
0000060

P
\0
F
\0

G
\0
G
\0

C
O
P
\0 \0 003
H
A
N
\0 002
A

Y
\0
I
L

\n 377 \r \n \0 \0 \0 \0 \0 \0
\0 \0 002
A
F \0 \0 \0 013
A
S
T
A
N 377 377 377 377 \0 003
\0 \0 \0 007
A
L
B
A
N
I
928

COPY

0000100
E 377 377 377 377
0000120 007
A
L
G
E
0000140 \0 002
Z
M \0
0000160 377 377 \0 003 \0
0000200
M
B
A
B
W

\0 003 \0 \0 \0 002
D
R
I
E 377 377 377 377
\0 \0 006
Z
A
M
B
\0 \0 002
Z
W \0 \0
E 377 377 377 377 377 377

Z \0 \0 \0
\0 003 \0 \0
I
E 377 377
\0 \b
Z
I

Compatibilit
Il n'existe pas d'instruction COPY dans le standard SQL.
La syntaxe suivante tait utilise avant PostgreSQL 9.0 et est toujours supporte :
COPY nomtable [ ( colonne [, ...] ) ]
FROM { 'nomfichier' | STDIN }
[ [ WITH ]
[ BINARY ]
[ OIDS ]
[ DELIMITER [ AS ] 'dlimiteur' ]
[ NULL [ AS ] 'chane NULL' ]
[ CSV [ HEADER ]
[ QUOTE [ AS ] 'guillemet' ]
[ ESCAPE [ AS ] 'chappement' ]
[ FORCE NOT NULL colonne [, ...] ] ] ]
COPY { nomtable [ ( colonne [, ...] ) ] | ( requte ) }
TO { 'nomfichier' | STDOUT }
[ [ WITH ]
[ BINARY ]
[ OIDS ]
[ DELIMITER [ AS ] 'dlimiteur' ]
[ NULL [ AS ] 'chane NULL' ]
[ CSV [ HEADER ]
[ QUOTE [ AS ] 'guillemet' ]
[ ESCAPE [ AS ] 'chappement' ]
[ FORCE QUOTE colonne [, ...] | * } ] ] ]
Notez que, dans cette syntaxe, BINARY et CSV sont traits comme des mots-cls indpendants, pas comme des arguments
l'option FORMAT.
La syntaxe suivante, utilise avant PostgreSQL version 7.3, est toujours supporte :
COPY [ BINARY ] nom_table [ WITH OIDS ]
FROM { 'nom_fichier' | STDIN }
[ [USING] DELIMITERS 'caractre_dlimiteur' ]
[ WITH NULL AS 'chane NULL' ]
COPY [ BINARY ] nom_table [ WITH OIDS ]
TO { 'nom_fichier' | STDOUT }
[ [USING] DELIMITERS 'caractre_dlimiteur' ]
[ WITH NULL AS 'chane NULL' ]

929

Nom
CREATE AGGREGATE Dfinir une nouvelle fonction d'agrgat

Synopsis
CREATE AGGREGATE nom ( type_donne_entre [ , ... ] ) (
SFUNC = sfonc,
STYPE = type_donne_tat
[ , FINALFUNC = ffonc ]
[ , INITCOND = condition_initiale ]
[ , SORTOP = operateur_tri ]
)
ou l'ancienne syntaxe
CREATE AGGREGATE nom (
BASETYPE = type_base,
SFUNC = sfonc,
STYPE = type_donne_tat
[ , FINALFUNC = ffonc ]
[ , INITCOND = condition_initiale ]
[ , SORTOP = operateur_tri ]
)

Description
CREATE AGGREGATE dfinit une nouvelle fonction d'agrgat. Quelques fonctions d'agrgat basiques et largement utilises
sont fournies dans la distribution standard ; elles sont documentes dans le Section 9.18, Fonctions d'agrgat . CREATE
AGGREGATE est utilise pour ajouter des fonctionnalits lors de la dfinition de nouveaux types ou si une fonction d'agrgat
n'est pas fournie.
Si un nom de schma est donn (par exemple, CREATE AGGREGATE monschema.monagg ...), alors la fonction
d'agrgat est cre dans le schma prcis. Sinon, elle est cre dans le schma courant.
Une fonction d'agrgat est identifie par son nom et son (ou ses) types de donnes en entre. Deux agrgats dans le mme schma peuvent avoir le mme nom s'ils oprent sur des types diffrents en entre. Le nom et le(s) type(s) de donnes en entre d'un
agrgat doivent aussi tre distincts du nom et du type de donnes de toutes les fonctions ordinaires du mme schma.
Une fonction d'agrgat est ralise partir d'une ou deux fonctions ordinaires : une fonction de transition d'tat sfonc, et une
fonction de traitement final optionnelle ffonc. Elles sont utilises ainsi :
sfonc( tat-interne, nouvelle-valeur-donnes ) ---> prochain-tat-interne
ffonc( tat-interne ) ---> valeur-agrgat
PostgreSQL cre une variable temporaire de type stype pour contenir l'tat interne courant de l'agrgat. chaque ligne en
entre, la valeur de l'argument de l'agrgat est calculeet la fonction de transition d'tat est appel avec la valeur d'tat courante
et la valeur du nouvel argument pour calculer une nouvelle valeur d'tat interne. Une fois que toutes les lignes sont traites, la
fonction finale est appele une seule fois pour calculer la valeur de retour de l'agrgat. S'il n'existe pas de fonction finale, alors la
valeur d'tat final est retourne en l'tat.
Une fonction d'agrgat peut fournir une condition initiale, c'est--dire une valeur initiale pour la valeur de l'tat interne. Elle est
spcifie et stocke en base comme une valeur de type text mais doit tre une reprsentation externe valide d'une constante du
type de donne de la valeur d'tat. Si elle n'est pas fournie, la valeur d'tat est initialement positionne NULL.
Si la fonction de transition d'tat est dclare strict , alors elle ne peut pas tre appele avec des entres NULL. Avec une
telle fonction de transition, l'excution d'agrgat se comporte comme suit. Les lignes avec une valeur NULL en entre sont ignores (la fonction n'est pas appel et la valeur de l'tat prcdent est conserv). Si la valeur de l'tat initial est NULL, alors, la
premire ligne sans valeur NULL, la premire valeur de l'argument remplace la valeur de l'tat, et la fonction de transition est
appele pour les lignes suivantes avec toutes les valeurs non NULL en entre. Cela est pratique pour implmenter des agrgats
comme max. Ce comportement n'est possible que quand type_donne_tat est identique au premier
type_donne_entre. Lorsque ces types sont diffrents, une condition initiale non NULL doit tre fournie, ou une fonction de transition non stricte utilise.
Si la fonction de transition d'tat n'est pas stricte, alors elle sera appele sans condition pour chaque ligne en entre et devra grer les entres NULL et les valeurs de transition NULL. Cela permet l'auteur de l'agrgat d'avoir le contrle complet sur la gestion des valeurs NULL par l'agrgat.
930

CREATE AGGREGATE

Si la fonction finale est dclare strict , alors elle ne sera pas appele quand la valeur d'tat finale est NULL ; la place, un rsultat NULL sera retourn automatiquement. C'est le comportement normal de fonctions strictes. Dans tous les cas, la fonction finale peut retourner une valeur NULL. Par exemple, la fonction finale pour avg renvoie NULL lorsqu'elle n'a aucune lignes en entre.
Les agrgats qui se comportent comme MIN ou MAX peuvent parfois tre optimiss en cherchant un index au lieu de parcourir
toutes les lignes en entre. Si un agrgat peut tre optimis, un oprateur de tri est spcifi. Dans ce cas, il est ncessaire que
l'agrgat fournisse le premier lment dans l'ordre impos par l'oprateur ; en d'autres mots :
SELECT agg(col) FROM tab;
doit tre quivalent :
SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
On suppose galement que l'agrgat ignore les entres NULL et qu'il fournit un rsultat NULL si et seulement s'il n'y a aucune entre NULL. D'ordinaire, l'oprateur < d'un type de donnes est le bon oprateur de tri pour MIN et > celui pour MAX.
L'optimisation ne prend jamais effet sauf si l'oprateur spcifi est membre de la stratgie less than (NdT : plus petit que) ou
greater than (NdT : plus grand que) d'une classe d'oprateur pour un index B-tree.

Paramtres
nom
Le nom de la fonction d'agrgat crer (ventuellement qualifi du nom du schma).
type_donne_entre
Un type de donne en entre sur lequel opre la fonction d'agrgat. Pur crer une fonction d'agrgat sans argument, placez *
la place de la liste des types de donnes en entre. (la fonction count(*) en est un bon exemple.)
type_base
Dans l'ancienne syntaxe de CREATE AGGREGATE, le type de donnes en entre est spcifie par un paramtre
type_base plutt que d'tre crit la suite du nom de l'agrgat. Notez que cette syntaxe autorise seulement un paramtre en
entre. Pour dfinir une fonction d'agrgat sans argument, indiquez only one input parameter. To define a zero-argument aggregate function, "ANY" (et non pas *) pour le type_base.
sfonc
Le nom de la fonction de transition de l'tat appeler pour chaque ligne en entre. Pour une fonction d'agrgat avec N arguments, sfonc doit prendre N+1 arguments, le premier tant de type type_donnes_tat et le reste devant correspondre
aux types de donnes en entre dclars pour l'agrgat. La fonction doit renvoyer une valeur de type
type_donnes_tat. Cette fonction prend la valeur actuelle de l'tat et les valeurs actuelles des donnes en entre. Elle
renvoit la prochaine valeur de l'tat.
type_donne_tat
Le type de donne pour la valeur d'tat de l'agrgat.
ffonc
Le nom de la fonction finale appeler pour traiter le rsultat de l'agrgat une fois que toutes les lignes en entre ont t parcourues. La fonction prend un seul argument de type type_donne_tat. Le type de retour de l'agrgat de la fonction est
dfini comme le type de retour de cette fonction. Si ffonc n'est pas spcifie, alors la valeur d'tat finale est utilise comme
rsultat de l'agrgat et le type de retour est type_donne_tat.
condition_initiale
La configuration initiale pour la valeur de l'tat. Elle doit tre une constante de type chane de caractres dans la forme accepte par le type de donnes type_donne_tat. Si non spcifi, la valeur d'tat est initialement positionne NULL.
sort_operator
L'oprateur de tri associ pour un agrgat de type MIN ou MAX. C'est seulement le nom de l'oprateur (ventuellement qualifi
du nom du schma). L'oprateur est suppos avoir les mmes types de donnes en entre que l'agrgat (qui doit tre un agrgat un seul argument).
Les paramtres de CREATE AGGREGATE peuvent tre crits dans n'importe quel ordre, pas uniquement dans l'ordre illustr
ci-dessus.

Exemples
Voir Section 35.10, Agrgats utilisateur .

931

CREATE AGGREGATE

Compatibilit
CREATE AGGREGATE est une extension PostgreSQL. Le standard SQL ne fournit pas de fonctions d'agrgat utilisateur.

Voir aussi
ALTER AGGREGATE(7), DROP AGGREGATE(7)

932

Nom
CREATE CAST Dfinir un transtypage

Synopsis
CREATE CAST (type_source AS type_cible)
WITH FUNCTION nom_fonction (type_argument [, ...])
[ AS ASSIGNMENT | AS IMPLICIT ]
CREATE CAST (type_source AS type_cible)
WITHOUT FUNCTION
[ AS ASSIGNMENT | AS IMPLICIT ]
CREATE CAST (type_source AS type_cible)
WITH INOUT
[ AS ASSIGNMENT | AS IMPLICIT ]

Description
CREATE CAST dfinit un transtypage. Un transtypage spcifie l'opration de conversion entre deux types de donnes. Par
exemple :
SELECT CAST(42 AS float8);
convertit la constante entire 42 en float8 en appelant une fonction prcdemment dfinie, float8(int4) dans le cas prsent
(si aucun transtypage convenable n'a t dfini, la conversion choue).
Deux types peuvent tre coercibles binairement, ce qui signifie que le transtypage peut tre fait gratuitement sans invoquer
aucune fonction. Ceci impose que les valeurs correspondantes aient la mme reprsentation interne. Par exemple, les types text
et varchar sont coercibles binairement dans les deux sens. La coercibilit binaire n'est pas forcment une relation symtrique.
Par exemple, le transtypage du type xml au type text peut tre fait gratuitement dans l'implmentation actuelle, mais l'opration
inverse ncessite une fonction qui fasse au moins une validation syntaxique. (Deux types qui sont coercibles binairement dans
les deux sens sont aussi appels binairement compatibles.)
Vous pouvez dfinir un transtypage comme transtypage I/O en utilisant la syntaxe WITH INOUT. Un transtype I/O est effectu
en appelant la fonction de sortie du type de donnes source, et en passant la chane rsultante la fonction d'entre du type de
donnes cible. Dans la plupart des cas, cette fonctionnalit vite d'avoir crire une fonction de transtypage spare pour la
conversion. Un transtypage I/O agit de la mme faon qu'un transtypage standard bas sur une fonction. Seule l'implmentation
diffre.
Un transtypage peut tre appel explicitement. Par exemple : CAST(x AS nomtype) ou x::nomtype.
Si le transtypage est marqu AS ASSIGNMENT (NDT : l'affectation), alors son appel peut tre implicite lors de l'affectation
d'une valeur une colonne du type de donne cible. Par exemple, en supposant que foo.f1 soit une colonne de type text :
INSERT INTO foo (f1) VALUES (42);
est autoris si la conversion du type integer vers le type text est indique AS ASSIGNMENT. Dans le cas contraire, c'est interdit.
Le terme de transtypage d'affectation est utilis pour dcrire ce type de conversion.
Si la conversion est marque AS IMPLICIT, alors elle peut tre appele implicitement dans tout contexte, soit par une affectation soit en interne dans une expression (nous utilisons gnralement le terme conversion implicite pour dcrire ce type de
conversion.) Par exemple, voici une requte :
SELECT 2 + 4.0;
L'analyseur marque au dbut les constantes comme tant de type integer et numeric respectivement. Il n'existe pas d'oprateur
integer + numeric dans les catalogues systmes mais il existe un oprateur numeric + numeric. La requte sera un succs si une
conversion de integer vers numeric est disponible et marque AS IMPLICIT -- ce qui est le cas. L'analyseur appliquera la
conversion implicite et rsoudra la requte comme si elle avait t crite de cette faon :
SELECT CAST ( 2 AS numeric ) + 4.0;
Maintenant, les catalogues fournissent aussi une conversion de numeric vers integer. Si cette conversion tait marque AS IMPLICIT -- mais ce n'est pas le cas -- alors l'analyseur devra choisir entre l'interprtation ci-dessus et son alternative (la conver933

CREATE CAST

sion de la constante numeric en un integer) et appliquer l'oprateur integer + integer. Comme il n'a aucune information qui lui permettrait de choisir le meilleur moyen, il abandonne et dclare la requte comme tant ambige. Le fait qu'une seule des conversions est indique comme implicite est le moyen par lequel nous apprenons l'analyseur de prfrer la premire solution
(c'est--dire de transformer une expression numeric-and-integer en numeric) ; il n'y a pas d'autre moyen.
Il est conseill d'tre conservateur sur le marquage du caractre implicite des transtypages. Une surabondance de transtypages implicites peut conduire PostgreSQL interprter trangement des commandes, voire se retrouver dans l'incapacit totale de les
rsoudre parce que plusieurs interprtations s'avrent envisageables. Une bonne rgle est de ne raliser des transtypages implicites
que pour les transformations entre types de la mme catgorie gnrale et qui prservent l'information. Par exemple, la conversion
entre int2 et int4 peut tre raisonnablement implicite mais celle entre float8 et int4 est probablement rserve l'affectation. Les
transtypages inter-catgories, tels que de text vers int4, sont prfrablement excuts dans le seul mode explicite.

Note
Il est parfois ncessaire, pour des raisons de convivialit ou de respect des standards, de fournir plusieurs transtypages implicites sur un ensemble de types de donnes. Ceux-ci peuvent alors entraner des ambiguits qui ne
peuvent tre vites, comme ci-dessus. L'analyseur possde pour ces cas une heuristique de secours s'appuyant sur
les catgories de types et les types prfrs, qui peut aider fournir le comportement attendu dans ce genre de cas.
Voir CREATE TYPE(7) pour plus de dtails.
Pour crer un transtypage, il faut tre propritaire du type source ou destination. Seul le superutilisateur peut crer un transtypage
binairement compatible (une erreur sur un tel transtypage peut aisment engendrer un arrt brutal du serveur).

Paramtres
typesource
Le nom du type de donne source du transtypage.
typecible
Le nom du type de donne cible du transtypage.
nom_fonction (type_argument [, ...])
La fonction utilise pour effectuer la conversion. Le nom de la fonction peut tre qualifi du nom du schma. Si ce n'est pas le
cas, la fonction est recherche dans le chemin des schmas. Le type de donnes rsultant de la fonction doit correspondre au
type cible du transtypage. Ses arguments sont explicits ci-dessous.
WITHOUT FUNCTION
Indication d'une compatibilit binaire entre le type source et le type cible pour qu'aucune fonction ne soit requise pour effectuer la conversion.
WITH INOUT
Inique que le transtypage est un transtypage I/O, effectu en appelant la fonction de sortie du type de donnes source, et en
passant la chane rsultante la fonction d'entre du type de donnes cible.
AS ASSIGNMENT
Lors d'une affectation, l'invocation du transtypage peut tre implicite.
AS IMPLICIT
L'invocation du transtypage peut tre implicite dans tout contexte.
Les fonctions de transtypage ont un trois arguments. Le premier argument est du mme type que le type source ou doit tre compatible avec ce type. Le deuxime argument, si fourni, doit tre de type integer. Il stocke le modificateur de type associ au type
de destination, ou -1 en l'absence de modificateur. Le troisime argument, si fourni, doit tre de type boolean. Il vaut true si la
conversion est explicite, false dans le cas contraire. Bizarrement, le standard SQL appelle des comportements diffrents pour
les transtypages explicites et implicites dans certains cas. Ce paramtre est fourni pour les fonctions qui implmentent de tel transtypages. Il n'est pas recommand de concevoir des types de donnes utilisateur entrant dans ce cas de figure.
Le type de retour d'une fonction de transtypage doit tre identique ou coercible binairement avec le type cible du transtypage.
En gnral, un transtypage correspond des type source et destination diffrents. Cependant, il est permis de dclarer un transtypage entre types source et destination identiques si la fonction de transtypage a plus d'un argument. Cette possibilit est utilise
pour reprsenter dans le catalogue systme des fonctions de transtypage agissant sur la longueur d'un type. La fonction nomme
est utilise pour convertir la valeur d'un type la valeur du modificateur de type fournie par le second argument.
Quand un transtypage concerne des types source et destination diffrents et que la fonction a plus d'un argument, le transtypage et
la conversion de longeur du type destination sont faites en une seule etape. Quand une telle entre n'est pas disponible, le transtypage vers un type qui utilise un modificateur de type implique deux tapes, une pour convertir les types de donnes et la seconde
934

CREATE CAST

pour appliquer le modificateur.

Notes
DROP CAST(7) est utilis pour supprimer les transtypages utilisateur.
Pour convertir les types dans les deux sens, il est obligatoire de dclarer explicitement les deux sens.
Il est n'est pas ncessaire habituellement de crer des conversions entre des types dfinis par l'utilisateur et des types de chane
standards (text, varchar etchar(n), pas plus que pour des types dfinis par l'utilisateur dfinis comme entrant dans la catgorie des
chanes). PostgreSQL fournit un transtypage I/O automatique pour cela. Ce transtypage automatique vers des types chanes est
trait comme des transtypages d'affectation, alors que les transtypages automatiques partir de types chane sont de type explicite
seulement. Vous pouvez changer ce comportement en dclarant votre propre conversion pour remplacer une conversion automatique. La seule raison usuelle de le faire est de vouloir rendre l'appel de la conversion plus simple que le paramtrage standard
(affectation seulement ou explicite seulement). Une autre raison envisageable est de vouloir que la conversion se comporte diffrement de la fonction I/O du type ; mais c'est suffisamment droutant pour que vous y pensiez deux fois avant de le faire. (Un petit
nombre de types internes ont en fait des comportements diffrents pour les conversions, principalement cause des besoins du
standard SQL.)
Avant PostgreSQL 7.3, toute fonction qui portait le mme nom qu'un type de donnes, retournait ce type de donnes et prenait
un argument d'un autre type tait automatiquement dtecte comme une fonction de conversion. Cette convention a t abandonne du fait de l'introduction des schmas et pour pouvoir reprsenter des conversions binairement compatibles dans les catalogues
systme. Les fonctions de conversion intgres suivent toujours le mme schma de nommage mais elle doivent galement tre
prsentes comme fonctions de transtypage dans le catalogue systme pg_cast.
Bien que cela ne soit pas requis, il est recommand de suivre l'ancienne convention de nommage des fonctions de transtypage en
fonction du type de donnes de destination. Beaucoup d'utilisateurs sont habitus convertir des types de donnes l'aide d'une
notation de style fonction, c'est--dire nom_type(x). En fait, cette notation n'est ni plus ni moins qu'un appel la fonction
d'implantation du transtypage ; sa gestion n'est pas spcifique un transtypage. Le non-respect de cette convention peut surprendre
certains utilisateurs. Puisque PostgreSQL permet de surcharger un mme nom de fonction avec diffrents types d'argument, il
n'y a aucune difficult avoir plusieurs fonctions de conversion vers des types diffrents qui utilisent toutes le mme nom de type
destination.

Note
En fait, le paragraphe prcdent est une sur-simplification : il existe deux cas pour lesquels une construction d'appel
de fonction sera traite comme une demande de conversion sans qu'il y ait correspondance avec une fonction relle.
Si un appel de fonction nom(x) ne correspond pas exactement une fonction existante, mais que nom est le nom
d'un type de donnes et que pg_cast fournit une conversion compatible binairement vers ce type partir du type x,
alors l'appel sera construit partir de la conversion compatible binairement. Cette exception est faite pour que les
conversions compatibles binairement puissent tre appeles en utilisant la syntaxe fonctionnelle, mme si la fonction manque. De ce fait, s'il n'y pas d'entre dans pg_cast mais que la conversion serait partir de ou vers un type
chapne, l'appel sera ralis avec une conversion I/O. Cette exception autorise l'appel de conversion I/O en utilisant
la syntaxe fonctionnelle.

Note
Il existe aussi une exception l'exception : le transtypage I/O convertissant des types composites en types chane de
caractres ne peut pas tre appel en utilisant la syntaxe fonctionnelle, mais doit tre crite avec la syntaxe de transtypage explicite (soit CAST soit ::). Cette exception a t ajoute car, aprs l'introduction du transtypage I/O automatique, il tait trop facile de provoquer par erreur une telle conversion alors que l'intention tait de rfrencer une
fonction ou une colonne.

Exemples
Cration d'un transtypage d'affectation du type bigint vers le type int4 l'aide de la fonction int4(bigint) :
CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;
(Ce transtypage est dj prdfini dans le systme.)

Compatibilit
La commande CREATE CAST est conforme SQL ceci prs que SQL ne mentionne pas les types binairement compatibles et
935

CREATE CAST

les arguments supplmentaires pour les fonctions d'implantation. AS IMPLICIT est aussi une extension PostgreSQL.

Voir aussi
CREATE FUNCTION(7), CREATE TYPE(7), DROP CAST(7)

936

Nom
CREATE COLLATION dfinit une nouvelle collation

Synopsis
CREATE COLLATION nom (
[ LOCALE = locale, ]
[ LC_COLLATE = lc_collate, ]
[ LC_CTYPE = lc_ctype ]
)
CREATE COLLATION nom FROM collation_existante

Description
CREATE COLLATION dfinit une nouvelle collation utilisant la configuration de locale du systme d'exploitation spcifie
ou par copie d'une collation existante.
Pour pouvoir crer une collation, vous devez possder le privilge CREATE sur le schma de destination.

Paramtres
nom
Le nom de la collation. Le nom de la collation peut tre qualifi par le schma. Si ce n'est pas le cas, la collation est dfinie
dans le schma courant. Le nom de la collation doit tre unique au sein de ce schma. (Le catalogue systme peut contenir
des collations de mme nom pour d'autres encodages, mais ces dernires sont ignores si l'encodage de la base de donnes
ne correspond pas).
locale
Ceci est un raccourci pour positionner d'un mme coup LC_COLLATE et LC_CTYPE. Si vous spcifiez cela, vous ne pouvez plus spcifier aucun de ces deux paramtres-ci.
lc_collate
Utilise la locale systme spcifie comme catgorie de locale de LC_COLLATE. La locale doit tre applicable l'encodage
de la base courante. (cf. CREATE DATABASE(7)pour les rgles prcises.)
lc_ctype
Utilise la locale systme spcifie comme catgorie de locale de LC_CTYPE. La locale doit tre applicable l'encodage de
la base courante. (cf. CREATE DATABASE(7)pour les rgles prcises.)
collation_existante
Le nom d'une collation existante copier. La nouvelle collation aura les mmes proprits que celle copie, mais ce sera un
objet indpendant.

Notes
Utilisez DROP COLLATION pour supprimer une collation dfinie par l'utilisateur.
Voir Section 22.2, Support des collations pour plus d'informations sur le support des collations dans PostgreSQL.

Exemples
Crer une collation partir de la locale systme fr_FR.utf8 (en supposant que l'encodage de la base courante est UTF8):
CREATE COLLATION french (LOCALE = 'fr_FR.utf8');
Crer une collation partir d'une collation existante :
CREATE COLLATION german FROM "de_DE";
Ceci peut tre pratique pour pouvoir utiliser dans des applications des noms de collation indpendants du systme d'exploitation.

937

CREATE COLLATION

Compatibilit
Dans le standard SQL se trouve un ordre CREATE COLLATION, mais il est limit la copie d'une collation existante. La syntaxe de cration d'une nouvelle collation est une extension PostgreSQL.

Voir galement
ALTER COLLATION(7), DROP COLLATION(7)

938

Nom
CREATE CONVERSION Dfinir une nouvelle conversion d'encodage

Synopsis
CREATE [ DEFAULT ] CONVERSION nom
FOR codage_source TO codage_dest FROM nom_fonction

Description
CREATE CONVERSION dfinit une nouvelle conversion entre les encodages de caractres. De plus, les conversions marques DEFAULT peuvent tre utilises pour automatiser une conversion d'encodage entre le client et le serveur. Pour cela, deux
conversions, de l'encodage A vers l'encodage B et de l'encodage B vers l'encodage A, doivent tre dfinies.
Pour crer une conversion, il est ncessaire de possder les droits EXECUTE sur la fonction et CREATE sur le schma de destination.

Paramtres
DEFAULT
La clause DEFAULT indique une conversion par dfaut entre l'encodage source et celui de destination. Il ne peut y avoir,
dans un schma, qu'une seule conversion par dfaut pour un couple d'encodages.
nom
Le nom de la conversion. Il peut tre qualifi du nom du schma. Dans la cas contraire, la conversion est dfinie dans le
schma courant. Le nom de la conversion est obligatoirement unique dans un schma.
codage_source
Le nom de l'encodage source.
codage_dest
Le nom de l'encodage destination.
nom_fonction
La fonction utilise pour raliser la conversion. Son nom peut tre qualifi du nom du schma. Dans le cas contraire, la
fonction est recherche dans le chemin.
La fonction a la signature suivante :
conv_proc(
integer, -integer, -cstring, -internal, -integer
-) RETURNS void;

ID encodage source
ID encodage destination
chane source (chane C termine par un caractre nul)
destination (chane C termine par un caractre nul)
longueur de la chane source

Notes
DROP CONVERSION est utilis pour supprimer une conversion utilisateur.
Il se peut que les droits requis pour crer une conversion soient modifies dans une version ultrieure.

Exemples
Cration d'une conversion de l'encodage UTF8 vers l'encodage LATIN1 en utilisant mafonc :
CREATE CONVERSION maconv FOR 'UTF8' TO 'LATIN1' FROM mafonc;

Compatibilit
CREATE CONVERSION est une extension PostgreSQL. Il n'existe pas d'instruction CREATE CONVERSION dans le
standard SQL. Par contre, il existe une instruction CREATE TRANSLATION qui est trs similaire dans son but et sa syntaxe.

939

CREATE CONVERSION

Voir aussi
ALTER CONVERSION(7), CREATE FUNCTION(7), DROP CONVERSION(7)

940

Nom
CREATE DATABASE Crer une nouvelle base de donnes

Synopsis
CREATE DATABASE nom
[ [ WITH ] [ OWNER [=] nom_utilisateur ]
[ TEMPLATE [=] modle ]
[ ENCODING [=] codage ]
[ LC_COLLATE [=] lc_collate ]
[ LC_CTYPE [=] lc_ctype ]
[ TABLESPACE [=] tablespace ]
[ CONNECTION LIMIT [=] limite_connexion ] ]

Description
CREATE DATABASE cre une nouvelle base de donnes.
Pour crer une base de donnes, il faut tre superutilisateur ou avoir le droit spcial CREATEDB. Voir ce sujet CREATE
USER(7).
Par dfaut, la nouvelle base de donnes est cre en clonant la base systme standard template1. Un modle diffrent peut
tre utilis en crivant TEMPLATE nom. En particulier, la clause TEMPLATE template0 permet de crer une base de donnes vierge qui ne contient que les objets standards pr-dfinis dans la version de PostgreSQL utilise. C'est utile pour ne pas
copier les objets locaux ajouts template1.

Paramtres
nom
Le nom de la base de donnes crer.
nom_utilisateur
Le nom de l'utilisateur propritaire de la nouvelle base de donnes ou DEFAULT pour l'option par dfaut (c'est--dire le
nom de l'utilisateur qui excute la commande). Pour crer une base de donnes dont le propritaire est un autre rle, vous
devez tre un membre direct ou direct de ce rle, ou tre un superutilisateur.
modle
Le nom du modle squelette de la nouvelle base de donnes ou DEFAULT pour le modle par dfaut (template1).
codage
Le jeu de caractres de la nouvelle base de donnes. Peut-tre une chane (par exemple 'SQL_ASCII'), un nombre de jeu
de caractres de type entier ou DEFAULT pour le jeu de caractres par dfaut (en fait, celui de la base modle). Les jeux de
caractres supports par le serveur PostgreSQL sont dcrits dans Section 22.3.1, Jeux de caractres supports . Voir
ci-dessous pour des restrictions supplmentaires.
lc_collate
L'ordre de tri (LC_COLLATE) utiliser dans la nouvelle base. Ceci affecte l'odre de tri appliqu aux chanes, par exemple
dans des requtes avec ORDER BY, ainsi que l'ordre utilis dans les index sur les colonnes texte. Le comportement par dfaut est de choisir l'ordre de tri de la base de donnes modle. Voir ci-dessous pour les restrictions supplmentaires.
lc_ctype
La classification du jeu de caractres (LC_CTYPE) utiliser dans la nouvelle base. Ceci affecte la catgorisation des caractres, par exemple minuscule, majuscule et chiffre. Le comportement par dfaut est d'utiliser la classification de la base de
donnes modle. Voir ci-dessous pour les restrictions supplmentaires.
tablespace
Le nom du tablespace associ la nouvelle base de donnes ou DEFAULT pour le tablespace de la base de donnes modle.
Ce tablespace est celui par dfaut pour les objets crs dans cette base de donnes. Voir CREATE TABLESPACE(7) pour
plus d'informations.
limite_connexion
Le nombre de connexions concurrentes la base de donnes. -1 (valeur par dfaut) signifie qu'il n'y a pas de limite.
L'ordre des paramtres optionnels n'a aucune importance.
941

CREATE DATABASE

Notes
La commande CREATE DATABASE ne peut pas tre excute l'intrieur d'un bloc de transactions.
Les erreurs sur la ligne ne peut initialiser le rpertoire de la base de donnes ( could not initialize database directory dans la
version originale) sont le plus souvent dues des droits insuffisants sur le rpertoire de donnes, un disque plein ou un autre
problme relatif au systme de fichiers.
L'instruction DROP DATABASE(7) est utilise pour supprimer la base de donnes.
Le programme createdb(1) est un enrobage de cette commande fourni par commodit.
Bien qu'il soit possible de copier une base de donnes autre que template1 en spcifiant son nom comme modle, cela n'est pas
(encore) prvu comme une fonctionnalit COPY DATABASE d'usage gnral. La limitation principale est qu'aucune autre
session ne peut tre connecte la base modle pendant sa copie. CREATE DATABASE chouera s'il y a une autre connexion
au moment de son excution ; sinon, les nouveaux connexions la base modle seront verrouilles jusqu' la fin de la commande
CREATE DATABASE. La Section 21.3, Bases de donnes modles fournit plus d'informations ce sujet.
L'encodage du jeu de caractre spcifi pour la nouvelle base de donnes doit tre compatible avec les paramtre de locale
(LC_COLLATE et LC_CTYPE). Si la locale est C (ou de la mme faon POSIX), alors tous les encodages sont autoriss. Pour
d'autres paramtres de locale, il n'y a qu'un encodage qui fonctionnera correctement. (Nanmoins, sur Windows, l'encodage UTF-8
peut tre utilise avec toute locale.) CREATE DATABASE autorisera les superutilisateurs spcifier l'encodage SQL_ASCII
quelque soit le paramtre locale mais ce choix devient obsolte et peut occasionner un mauvais comportement des fonctions sur
les chanes si des donnes dont l'encodage n'est pas compatible avec la locale sont stockes dans la base.
Les paramtres d'encodage et de locale doivent correspondre ceux de la base modle, except quand la base template0 est utilise comme modle. La raison en est que d'autres bases de donnes pourraient contenir des donnes qui ne correspondent pas
l'encodage indiqu, ou pourraient contenir des index dont l'ordre de tri est affect par LC_COLLATE et LC_CTYPE. Copier ces
donnes peut rsulter en une base de donnes qui est corrompue suivant les nouveaux paramtres. template0, par contre, ne
contient aucun index pouvant tre affect par ces paramtres.
L'option CONNECTION LIMIT n'est qu'approximativement contraignante ; si deux nouvelles sessions commencent sensiblement
en mme temps alors qu'un seul connecteur la base est disponible, il est possible que les deux chouent. De plus, les superutilisateurs ne sont pas soumis cette limite.

Exemples
Crer une nouvelle base de donnes :
CREATE DATABASE lusiadas;
Crer une base de donnes ventes possde par l'utilisateur app_ventes utilisant le tablespace espace_ventes comme espace par dfaut :
CREATE DATABASE ventes OWNER app_ventes TABLESPACE espace_ventes;
Crer une base de donnes musique qui supporte le jeu de caractres ISO-8859-1 :
CREATE DATABASE musique ENCODING 'LATIN1' TEMPLATE template0;
Dans cet exemple, la clause TEMPLATE template0 sera uniquement requise si l'encodage de template1 n'est pas ISO8859-1. Notez que modifier l'encodage pourrait aussi ncessiter de slectionner de nouveaux paramtres pour LC_COLLATE et
LC_CTYPE.

Compatibilit
Il n'existe pas d'instruction CREATE DATABASE dans le standard SQL. Les bases de donnes sont quivalentes aux catalogues,
dont la cration est dfinie par l'implantation.

Voir aussi
ALTER DATABASE(7), DROP DATABASE(7)

942

Nom
CREATE DOMAIN Dfinir un nouveau domaine

Synopsis
CREATE DOMAIN nom [AS] type_donnee
[ COLLATE collation ]
[ DEFAULT expression ]
[ contrainte [ ... ] ]
o contrainte est :
[ CONSTRAINT nom_contrainte ]
{ NOT NULL | NULL | CHECK (expression) }

Description
CREATE DOMAIN cre un nouveau domaine. Un domaine est essentiellement un type de donnes avec des contraintes optionnelles (restrictions sur l'ensemble de valeurs autorises). L'utilisateur qui dfinit un domaine devient son propritaire.
Si un nom de schma est donn (par exemple, CREATE DOMAIN monschema.mondomaine ...), alors le domaine est
cr dans le schma spcifi. Sinon, il est cr dans le schma courant. Le nom du domaine doit tre unique parmi les types et
domaines existant dans son schma.
Les domaines permettent d'extraire des contraintes communes plusieurs tables et de les regrouper en un seul emplacement, ce
qui en facilite la maintenance. Par exemple, plusieurs tables pourraient contenir des colonnes d'adresses email, toutes ncessitant
la mme contrainte de vrification (CHECK) permettant de vrifier que le contenu de la colonne est bien une adresse email. Dfinissez un domaine plutt que de configurer la contrainte individuellement sur chaque table.

Paramtres
nom
Le nom du domaine crer (ventuellement qualifi du nom du schma).
type_donnees
Le type de donnes sous-jacent au domaine. Il peut contenir des spcifications de tableau.
collation
Un collationement optionnel pour le domaine. Si aucun collationnement n'est spcifi, le collationnement utilis par dfaut
est celui du type de donnes. Le type doit tre collationnable si COLLATE est spcifi.
DEFAULT expression
La clause DEFAULT permet de dfinir une valeur par dfaut pour les colonnes d'un type de donnes du domaine. La valeur
est une expression quelconque sans variable (les sous-requtes ne sont pas autorises). Le type de donnes de l'expression
par dfaut doit correspondre celui du domaine. Si la valeur par dfaut n'est pas indique, alors il s'agit de la valeur NULL.
L'expression par dfaut est utilise dans toute opration d'insertion qui ne spcifie pas de valeur pour cette colonne. Si une
valeur par dfaut est dfinie sur une colonne particulire, elle surcharge toute valeur par dfaut du domaine. De mme, la
valeur par dfaut surcharge toute valeur par dfaut associe au type de donnes sous-jacent.
CONSTRAINT nom_contrainte
Un nom optionnel pour une contrainte. S'il n'est pas spcifi, le systme en engendre un.
NOT NULL
Les valeurs de ce domaine sont habituellement protges comme les valeurs NULL. Nanmoins, il est toujours possible
qu'un domaine avec cette contrainte prenne une valeur NULL s'il se voit affect un type de domaine qui est devenu NULL,
par exemple via une jointure LEFT OUTER JOIN ou une requte du type INSERT INTO tab (colonne_domaine) VALUES ((SELECT colonne_domaine FROM tab WHERE false)).
NULL
Les valeurs de ce domaine peuvent tre NULL. C'est la valeur par dfaut.
Cette clause a pour seul but la compatibilit avec les bases de donnes SQL non standard. Son utilisation est dcourage
dans les applications nouvelles.
CHECK (expression)
943

CREATE DOMAIN

Les clauses CHECK spcifient des contraintes d'intgrit ou des tests que les valeurs du domaine doivent satisfaire. Chaque
contrainte doit tre une expression produisant un rsultat boolen. VALUE est obligatoirement utilis pour se rfrer la valeur teste.
Actuellement, les expressions CHECK ne peuvent ni contenir de sous-requtes ni se rfrer des variables autres que VALUE.

Exemples
Crer le type de donnes code_postal_us, et l'utiliser dans la dfinition d'une table. Un test d'expression rationnelle est utilis pour
vrifier que la valeur ressemble un code postal US valide :
CREATE DOMAIN code_postal_us AS TEXT
CHECK(
VALUE ~ '^\d{5}$'
OR VALUE ~ '^\d{5}-\d{4}$'
);
CREATE TABLE courrier_us (
id_adresse SERIAL PRIMARY KEY,
rue1 TEXT NOT NULL,
rue2 TEXT,
rue3 TEXT,
ville TEXT NOT NULL,
code_postal code_postal_us NOT NULL
);

Compatibilit
La commande CREATE DOMAIN est conforme au standard SQL.

Voir aussi
ALTER DOMAIN(7), DROP DOMAIN(7)

944

Nom
CREATE EXTENSION installe une nouvelle extension

Synopsis
CREATE EXTENSION [ IF NOT EXISTS ] nom_extension
[ WITH ] [ SCHEMA nom_schma ]
[ VERSION version ]
[ FROM ancienne_version ]

Description
CREATE EXTENSION charge une nouvelle extension dans la base de donne courante. Il ne doit pas y avoir d'extension dj
charge portant le mme nom.
Charger une extension consiste essentiellement excuter le script de l'extension. Ce script va crer dans la plupart des cas de
nouveaux objets SQL comme des fonctions, des types de donnes, des oprateurs et des mthodes d'indexation. La commande
CREATE EXTENSION enregistre en supplment les identifiants de chacun des objets crs, permettant ainsi de les supprimer
lorsque la commande DROP EXTENSION est appele.
Le chargement d'une extension ncessite les mmes droits que ceux qui permettent la cration de ses objets. La plupart des extensions ncessitent ainsi des droits superutilisateur ou d'tre le propritaire de la base de donne. L'utilisateur qui lance la commande CREATE EXTENSION devient alors le propritaire de l'extension (une vrification ultrieure des droits permettra de
le confirmer) et le propritaire de chacun des objets cr par le script de l'extension.

Paramtres
IF NOT EXISTS
Permet de ne pas retourner d'erreur si une extension de mme nom existe dj. Un simple message d'avertissement est alors
rapport. noter que l'extension existante n'a potentiellement aucun lien avec l'extension qui aurait pu tre cre.
nom_extension
Le nom de l'extension installer. PostgreSQL crera alors l'extension en utilisant les instructions du fichier de contrle
SHAREDIR/extension/nom_extension.control .
nom_schma
Le nom du schma dans lequel installer les objets de l'extension, en supposant que l'extension permette de dplacer ses objets dans un autre schma. Le schma en question doit exister au pralable. Si ce nom n'est pas spcifi et que le fichier de
contrle de l'extension ne spcifie pas de schma, le schma par dfaut en cours sera utilis.
Rappelez-vous que l'extension en soit n'est pas considre comme tant dans un schma. Les extensions ont des noms non
qualifis qui doivent tre uniques au niveau de la base de donnes. Par contre, les objets appartenant l'extension peuvent
tre dans des schmas.
version
La version de l'extension installer. Il peut s'agir d'un identifiant autant que d'une chane de caractre. La version par dfaut
est celle spcifie dans le fichier de contrle de l'extension.
ancienne_version
L'option FROM ancienne_version doit tre spcifie si et seulement s'il s'agit de convertir un module ancienne gnration (qui est en fait une simple collection d'objets non empaquete) en extension. Cette option modifie le comportement de
la commande CREATE EXTENSION pour excuter un script d'installation alternatif qui incorpore les objets existant dans
l'extension, plutt que de crer de nouveaux objets. Il faut prendre garde ce que SCHEMA spcifie le schma qui contient
ces objets pr-existant.
La valeur utiliser pour le paramtre ancienne_version est dtermine par l'auteur de l'extension et peut varier s'il
existe plus d'une version du module ancienne gnration qui peut voluer en une extension. Concernant les modules additionnels fournis en standard avant PostgreSQL 9.1, il est ncessaire d'utiliser la valeur unpackaged pour le paramtre
ancienne_version pour les faire voluer en extension.

Notes
Avant d'utiliser la commande CREATE EXTENSION pour charger une extension dans une base de donnes, il est ncessaire
945

CREATE EXTENSION

d'installer les fichiers qui l'accompagnent. Les informations de Modules supplmentaires fournis permettent d'installer les extensions fournies avec PostgreSQL.
Les extensions disponibles l'installation sur le serveur peuvent tre identifies au moyen des vues systmes
pg_available_extensions et pg_available_extension_versions.
Pour obtenir des informations sur l'criture de nouvelles extensions, consultez Section 35.15, Empaqueter des objets dans une
extension .

Exemples
Installer l'extension hstore dans la base de donnes courante :
CREATE EXTENSION hstore;
Mettre jour le module pr-9.1 hstore sous la forme d'une extension :
CREATE EXTENSION hstore SCHEMA public FROM unpackaged;
Prenez garde bien spcifier le schma vers lequel vous souhaitez installer les objets de hstore.

Compatibilit
La commande CREATE EXTENSION est spcifique PostgreSQL.

Voir aussi
ALTER EXTENSION(7), DROP EXTENSION(7)

946

Nom
CREATE FOREIGN DATA WRAPPER dfinit un nouveau wrapper de donnes distantes

Synopsis
CREATE FOREIGN DATA WRAPPER nom
[ HANDLER fonction_handler | NO HANDLER ]
[ VALIDATOR fonction_validation | NO VALIDATOR ]
[ OPTIONS ( option 'valeur' [, ... ] ) ]

Description
CREATE FOREIGN DATA WRAPPER cre un nouveau wrapper de donnes distantes. L'utilisateur qui dfinit un wrapper
de donnes distantes devient son propritaire.
Le nom du wrapper de donnes distantes doit tre unique dans la base de donnes.
Seuls les super-utilisateurs peuvent crer des wrappers de donnes distantes.

Paramtres
nom
Le nom du wrapper de donnes distantes crer.
HANDLER fonction_handler
fonction_handler est le nom d'une fonction enregistre prcdemment qui sera appele pour rcuprer les fonctions
d'excution pour les tables distantes. La fonction de gestion ne prend pas d'arguments et son code retour doit tre
fdw_handler.
Il est possible de crer un wrapper de donnes distantes sans fonction de gestion mais les tables distantes utilisant un tel
wrapper peuvent seulement tre dclares mais pas utilises.
VALIDATOR fonction_validation
fonction_validation est le nom d'une fonction dj enregistre qui sera appele pour vrifier les options gnriques
passes au wrapper de donnes distantes, ainsi que les options fournies au serveur distant et aux correspondances
d'utilisateurs (user mappings) utilisant le wrapper de donnes distantes. Si aucune fonction de validation n'est spcifie ou si
NO VALIDATOR est spcifi, alors les options ne seront pas vrifies au moment de la cration. (Il est possible que les
wrappers de donnes distantes ignorent ou rejettent des spcifications d'options invalides l'excution, en fonction de
l'implmentation) La fonction de validation doit prendre deux arguments : l'un du type text[], qui contiendra le tableau
d'options, tel qu'il est stock dans les catalogues systmes, et l'autre de type oid, qui sera l'OID du catalogue systme contenant les options. Le type de retour est inconnu ; la fonction doit rapporter les options invalides grce la fonction ereport(ERROR).
OPTIONS ( option 'valeur' [, ... ] )
Cette clause spcifie les options pour le nouveau wrapper de donnes distantes. Les noms et valeurs d'options autoriss sont
spcifiques chaque wrapper de donnes distantes. Ils sont valids par la fonction de validation du wrapper de donnes distantes. Les noms des options doivent tre uniques.

Notes
Pour le moment, la fonctionnalit de wrapper de donnes distantes est rudimentaire. Il n'y a pas de support pour mettre jour
une table distante et l'optimisation des requtes est basique (et principalement laisse au wrapper).
Actuellement, une fonction de validation de wrapper de donnes distantes est disponible : postgresql_fdw_validator,
qui accepte les options correspondant aux paramtres de connexion de libpq.

Exemples
Crer un wrapper de donnes distantes bidon :
CREATE FOREIGN DATA WRAPPER bidon;

947

CREATE FOREIGN DATA WRAPPER

Crer un wrapper de donnes distantes file avec la fonction de validation file_fdw_validator :


CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator;
Crer un wrapper de donnes distantes monwrapper avec des options :
CREATE FOREIGN DATA WRAPPER monwrapper
OPTIONS (debug 'true');

Compatibilit
CREATE FOREIGN DATA WRAPPER est conforme la norme ISO/IEC 9075-9 (SQL/MED), l'exception des clauses
HANDLER et VALIDATOR qui sont des extensions, et des clauses LIBRARY et LANGUAGE qui ne sont pas implmentes dans
PostgreSQL.
Notez, cependant, que la fonctionnalit SQL/MED n'est pas encore conforme dans son ensemble.

Voir aussi
ALTER FOREIGN DATA WRAPPER(7), DROP FOREIGN DATA WRAPPER(7), CREATE SERVER(7), CREATE USER
MAPPING(7)

948

Nom
CREATE FOREIGN TABLE cre une nouvelle table distante

Synopsis
CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [
{ column_name data_type [ NULL | NOT NULL ] }
[, ... ]
] )
SERVER server_name
[ OPTIONS ( option 'value' [, ... ] ) ]

Description
La commande CREATE FOREIGN TABLE cre une nouvelle table distante dans la base de donnes courante. La table distante appartient l'utilisateur qui excute cette commande.
Si un nom de schema est spcifi (par exemple, CREATE FOREIGN TABLE monschema.matable ...), alors la table
sera cre dans le schma spcifi. Dans les autres cas, elle sera cre dans le schma courant. Le nom de la table distante doit
tre diffrent du nom des autres tables distantes, tables, squences, index ou vues du mme schma.
La commande CREATE FOREIGN TABLE cre aussi automatiquement un type de donne qui reprsente le type composite
correspondant une ligne de la table distante. En consquence, une table distante ne peut pas avoir le mme nom qu'un type de
donne existant dans le mme schma.

Paramtres
IF NOT EXISTS
Permet de ne pas retourner d'erreur si une table distante de mme nom existe dj. Une simple notice est alors rapporte.
noter que la table distante existante n'a potentiellement aucun lien avec la table distante qui aurait pu tre cre.
table_name
Le nom de la table distante crer. Il est aussi possible de spcifier le schma qui contient cette table.
column_name
Le nom de la colonne crer dans cette nouvelle table distante.
data_type
Le type de donne de la colonne. Cela peut inclure des spcificateurs de tableaux. Pour plus d'information sur les types de
donnes supports par PostgreSQL, se rfrer Chapitre 8, Types de donnes.
NOT NULL
Interdiction des valeurs NULL dans la colonne.
NULL
Les valeurs NULL sont autorises pour la colonne. Il s'agit du comportement par dfaut.
Cette clause n'est fournie que pour des raisons de compatibilit avec les bases de donnes SQL non standard. Son utilisation
n'est pas encourage dans les nouvelles applications.
server_name
Le nom d'un serveur existant pour la table distante.
OPTIONS ( option 'value' [, ...] )
Options qui peuvent tre associs la nouvelle table distante. Les noms des options autorises et leurs valeurs sont spcifiques chaque wrapper de donnes distantes et sont valides en utilisant la fonction de validation du wrapper de donnes
distantes. Le nom de chaque option doit tre unique.

Exemples
Crer une table distante films avec le serveur film_server :

949

CREATE FOREIGN TABLE

CREATE FOREIGN TABLE films (


code
char(5) NOT NULL,
title
varchar(40) NOT NULL,
did
integer NOT NULL,
date_prod
date,
kind
varchar(10),
len
interval hour to minute
)
SERVER film_server;

Compatibilit
La commande CREATE FOREIGN TABLE est conforme au standard SQL. Toutefois, tout comme la commande CREATE
TABLE, l'usage de la contrainte NULL et des tables distantes sans colonnes sont autoriss.

Voir aussi
ALTER FOREIGN TABLE(7), DROP FOREIGN TABLE(7), CREATE TABLE(7), CREATE SERVER(7)

950

Nom
CREATE FUNCTION Dfinir une nouvelle fonction

Synopsis
CREATE [ OR REPLACE ] FUNCTION
nom ( [ [ modearg ] [ nomarg ] typearg [ { DEFAULT | = } expression_par_defaut ]
[, ...] ] ) ] )
[ RETURNS type_ret
| RETURNS TABLE ( nom_colonne type_colonne [, ...] ) ]
{ LANGUAGE nom_lang
| WINDOW
| IMMUTABLE | STABLE | VOLATILE
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
| [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
| COST cout_execution
| ROWS nb_lignes_resultat
| SET parametre { TO value | = value | FROM CURRENT }
| AS 'definition'
| AS 'fichier_obj', 'symbole_lien'
} ...
[ WITH ( attribut [, ...] ) ]

Description
CREATE FUNCTION dfinit une nouvelle fonction. CREATE OR REPLACE FUNCTION cre une nouvelle fonction ou
la remplace si elle existe dj. Pour pouvoir crer une fonction, l'utilisateur doit avoir le droit USAGE sur le langage associ.
Si un nom de schma est prcis, la fonction est cre dans le schma indiqu. Sinon, elle est cre dans le schma courant. Le
nom de la nouvelle fonction ne peut pas correspondre celui d'une fonction existant avec les mmes types d'arguments en entre
dans le mme schma. Toutefois, les fonctions de types d'arguments diffrents peuvent partager le mme nom (ceci est appel
surcharge).
Pour remplacer la dfinition actuelle d'une fonction existante, CREATE OR REPLACE FUNCTION est utilis. Il n'est pas
possible de changer le nom ou les types d'argument d'une fonction de cette faon (cela cre une nouvelle fonction distincte). De
mme, CREATE OR REPLACE FUNCTION ne permet pas de modifier le type retour d'une fonction existante. Pour cela, il
est ncessaire de supprimer et de recrer la fonction. (Lors de l'utilisation de paramtres OUT, cela signifie que le type d'un paramtre OUT ne peut tre modifi que par la suppression de la fonction.)
Quand CREATE OR REPLACE FUNCTION est utilis pour remplacer une fonction existante, le propritaire et les droits de
la fonction ne changent pas. Toutes les autres proprits de la fonction se voient affectes les valeurs spcifies dans la commande ou implicites pour les autres. Vous devez tre le propritaire de la fonction pour la remplacer ou tre un membre du rle
propritaire de la fonction.
En cas de suppression et de recraction d'une fonction, la nouvelle fonction n'est pas la mme entit que l'ancienne ; il faut supprimer les rgles, vues, dclencheurs, etc. qui rfrencent l'ancienne fonction. CREATE OR REPLACE FUNCTION permet
de modifier la dfinition d'une fonction sans casser les objets qui s'y rfrent. De plus, ALTER FUNCTION peut tre utilis
pour modifier la plupart des proprits supplmentaires d'une fonction existante.
L'utilisateur qui cre la fonction en devient le propritaire.

Paramtres
nom
Le nom de la fonction crer (ventuellement qualifi du nom du schma).
modearg
Le mode d'un argument : IN, OUT, INOUT ou VARIADIC. En cas d'omission, la valeur par dfaut est IN. Seuls des arguments OUT peuvent suivre un argument VARIADIC. Par ailleurs, des arguments OUT et INOUT ne peuvent pas tre utiliss
en mme temps que la notation RETURNS TABLE.
nomarg
Le nom d'un argument. Quelques langages (incluant PL/pgSQL, mais pas SQL) permettent d'utiliser ce nom dans le corps
de la fonction. Pour les autres langages, le nom d'un argument en entre est purement documentaire en ce qui concerne la
fonction elle-mme. Mais vous pouvez utiliser les noms d'arguments en entre lors de l'appel d'une fonction pour amliorer
951

CREATE FUNCTION

la lisibilit (voir Section 4.3, Fonctions appelantes ). Dans tous les cas, le nom d'un argument en sortie a une utilit car il
dfinit le nom de la colonne dans la ligne rsultat. (En cas d'omission du nom d'un argument en sortie, le systme choisit un
nom de colonne par dfaut.)
argtype
Le(s) type(s) de donnes des arguments de la fonction (ventuellement qualifi du nom du schma), s'il y en a. Les types des
arguments peuvent tre basiques, composites ou de domaines, ou faire rfrence au type d'une colonne.
En fonction du langage, il est possible d'indiquer des pseudotypes , tel que cstring. Les pseudotypes indiquent que le type
d'argument rel est soit non compltement spcifi, soit en dehors de l'ensemble des types de donnes ordinaires du SQL.
Il est fait rfrence au type d'une colonne par nom_table.nomcolonne%TYPE. Cette fonctionnalit peut servir rendre
une fonction indpendante des modifications de la dfinition d'une table.
expression_par_defaut
Une expression utiliser en tant que valeur par dfaut si le paramtre n'est pas spcifi. L'expression doit pouvoir tre coercible dans le type d'argument du paramtre. Seuls les paramtres d'entre (dont les INOUT) peuvent avoir une valeur par dfaut. Tous les paramtres d'entre suivant un paramtre avec une valeur par dfaut doivent aussi avoir une valeur par dfaut.
type_ret
Le type de donnes en retour (ventuellement qualifi du nom du schma). Le type de retour peut tre un type basique, composite ou de domaine, ou faire rfrence au type d'une colonne existante. En fonction du langage, il est possible d'indiquer un
pseudotype , tel que cstring. Si la fonction ne doit pas renvoyer de valeur, on indique void comme type de retour.
Quand il y a des paramtres OUT ou INOUT, la clause RETURNS peut tre omise. Si elle est prsente, elle doit correspondre
au type de rsultat impos par les paramtres de sortie : RECORD s'il y en a plusieurs, ou le type du seul paramtre en sortie.
Le modificateur SETOF indique que la fonction retourne un ensemble d'lments plutt qu'un seul.
Il est fait rfrence au type d'une colonne par nom_table.nomcolonne%TYPE.
nom_colonne
Le nom d'une colonne de sortie dans la syntaxe RETURNS TABLE. C'est une autre faon de dclarer un paramtre OUT
nomm, la diffrence prs que RETURNS TABLE implique aussi RETURNS SETOF.
type_colonne
Le type de donnes d'une colonne de sortie dans la syntaxe RETURNS TABLE.
nom_lang
Le nom du langage d'criture de la fonction. Peut tre SQL, C, internal ou le nom d'un langage procdural utilisateur.
Pour des raisons de compatibilit descendante, le nom peut tre crit entre guillemets simples.
WINDOW
WINDOW indique que la fonction est une fonction window plutt qu'une fonction simple. Ceci n'est l'heure actuelle utilisable
que pour les fonctions crites en C. L'attribut WINDOW ne peut pas tre chang lors du remplacement d'une dfinition de fonction existante.
IMMUTABLE, STABLE, VOLATILE
Ces attributs informent l'optimiseur de requtes sur le comportement de la fonction. Un seul choix est possible. En son absence, VOLATILE est utilis.
IMMUTABLE indique que la fonction ne peut pas modifier la base de donnes et qu' arguments constants, la fonction renvoie
toujours le mme rsultat ; c'est--dire qu'elle n'effectue pas de recherches dans la base de donnes, ou alors qu'elle utilise des
informations non directement prsentes dans la liste d'arguments. Si cette option est prcise, tout appel de la fonction avec
des arguments constants peut tre immdiatement remplac par la valeur de la fonction.
STABLE indique que la fonction ne peut pas modifier la base de donnes et qu' l'intrieur d'un seul parcours de la table, arguments constants, la fonction retourne le mme rsultat, mais celui-ci varie en fonction des instructions SQL. Cette option
est approprie pour les fonctions dont les rsultats dpendent des recherches en base, des variables de paramtres (tel que la
zone horaire courante), etc. (Ce mode est inappropri pour les triggers AFTER qui souhaitent voir les lignes modifies par la
commande en cours.) La famille de fonctions current_timestamp est qualifie de stable car les valeurs de ces fonctions
ne changent pas l'intrieur d'une transaction.
VOLATILE indique que la valeur de la fonction peut changer mme au cours d'un seul parcours de table. Aucune optimisation ne peut donc tre ralise. Relativement peu de fonctions de bases de donnes sont volatiles dans ce sens ; quelques
exemples sont random(), currval(), timeofday(). Toute fonction qui a des effets de bord doit tre classe volatile,
mme si son rsultat est assez prvisible. Cela afin d'viter l'optimisation des appels ; setval() en est un exemple.
Pour des dtails complmentaires, voir Section 35.6, Catgories de volatilit des fonctions .
CALLED ON NULL INPUT, RETURNS NULL ON NULL INPUT, STRICT
952

CREATE FUNCTION

CALLED ON NULL INPUT (la valeur par dfaut) indique que la fonction est appele normalement si certains de ses arguments sont NULL. C'est alors de la responsabilit de l'auteur de la fonction de grer les valeurs NULL.
RETURNS NULL ON NULL INPUT ou STRICT indiquent que la fonction renvoie toujours NULL si l'un de ses arguments
est NULL. Lorsque ce paramtre est utilis et qu'un des arguments est NULL, la fonction n'est pas excute, mais un rsultat
NULL est automatiquement retourn.
[EXTERNAL] SECURITY INVOKER, [EXTERNAL] SECURITY DEFINER
SECURITY INVOKER indique que la fonction est excute avec les droits de l'utilisateur qui l'appelle. C'est la valeur par dfaut. SECURITY DEFINER spcifie que la fonction est excute avec les droits de l'utilisateur qui l'a cr.
Le mot cl EXTERNAL est autoris pour la conformit SQL mais il est optionnel car, contrairement SQL, cette fonctionnalit s'applique toutes les fonctions, pas seulement celles externes.
cout_execution
Un nombre positif donnant le cot estim pour l'excution de la fonction en unit de cpu_operator_cost. Si la fonction renvoie
plusieurs lignes, il s'agit d'un cot par ligne renvoye. Si le cot n'est pas spcifi, une unit est suppose pour les fonctions en
langage C et les fonctions internes. Ce cot est de 100 units pour les fonctions dans tout autre langage. Des valeurs plus importantes feront que le planificateur tentera d'viter l'valuation de la fonction aussi souvent que possible.
nb_lignes_resultat
Un nombre positif donnant le nombre estim de lignes que la fonction renvoie, information utile au planificateur. Ceci est
seulement autoris pour les fonctions qui renvoient plusieurs lignes (fonctions SRF). La valeur par dfaut est de 1000 lignes.
parametre, valeur
La clause SET fait que le paramtre de configuration indique est initialise avec la valeur prcise au lancement de la fonction, puis restaure sa valeur d'origine lors de la sortie de la fonction. SET FROM CURRENT utilise la valeur actuelle de la
session comme valeur appliquer au lancement de la fonction.
Si une clause SET est attache une fonction, alors les effets de la commande SET LOCAL excute l'intrieur de la fonction pour la mme variable sont restreints la fonction : la valeur prcdente du paramtre de configuration est de nouveau
restaure en sortie de la fonction. Nanmoins, une commande SET ordinaire (c'est--dire sans LOCAL) surcharge la clause
SET, comme il le ferait pour une prcdente commande SET LOCAL : les effets d'une telle commande persisteront aprs la
sortie de la fonction sauf si la transaction en cours est annule.
Voir SET(7) et Chapitre 18, Configuration du serveur pour plus d'informations sur les paramtres et valeurs autoriss.
definition
Une constante de type chane dfinissant la fonction ; la signification dpend du langage. Cela peut tre un nom de fonction
interne, le chemin vers un fichier objet, une commande SQL ou du texte en langage procdural.
Il est souvent utile d'utiliser les guillemets dollar (voir Section 4.1.2.4, Constantes de chanes avec guillemet dollar ) pour
crire le code de la fonction, au lie des la syntaxe habituelle des guillemets. Sans les guillemets dollar, tout guillemet ou antislash dans la dfinition de la fonction doit tre chapp en les doublant.
fichier_obj, symbole_lien
Cette forme de clause AS est utilise pour les fonctions en langage C chargeables dynamiquement lorsque le nom de la fonction dans le code source C n'est pas le mme que celui de la fonction SQL. La chane fichier_obj est le nom du fichier
contenant l'objet chargeable dynamiquement et symbole_lien est le symbole de lien de la fonction, c'est--dire le nom de
la fonction dans le code source C. Si ce lien est omis, il est suppos tre le mme que le nom de la fonction SQL dfinie.
Lors d'appels rpts CREATE FUNCTION se rfrant au mme fichier objet, il est charg seulement une fois par session.
Pour dcharger et recharger le fichier (par exemple lors du dveloppement de la fonction), dmarrez une nouvelle session.
attribut
Faon historique d'indiquer des informations optionnelles concernant la fonction. Les attributs suivants peuvent apparatre
ici :
isStrict
quivalent STRICT ou RETURNS NULL ON NULL INPUT.
isCachable
isCachable est un quivalent obsolte de IMMUTABLE ; il est toujours accept pour des raisons de compatibilit ascendante.
Les noms d'attribut sont insensibles la casse.
La lecture de Section 35.3, Fonctions utilisateur fournit des informations supplmentaires sur l'criture de fonctions.

Overloading
953

CREATE FUNCTION

PostgreSQL autorise la surcharge des fonctions ; c'est--dire que le mme nom peut tre utilis pour des fonctions diffrentes si
tant est qu'elles aient des types d'arguments en entre distincts. Nanmoins, les noms C de toutes les fonctions doivent tre diffrents. Il est donc ncessaire de donner des noms diffrents aux fonctions C sucharges (on peut, par exemple, utiliser le type des
arguments dans le nom de la fonction).
Deux fonctions sont considres identiques si elles partagent le mme nom et les mmes types d'argument en entre, sans considration des paramtres OUT. Les dclarations suivantes sont, de fait, en conflit :
CREATE FUNCTION truc(int) ...
CREATE FUNCTION truc(int, out text) ...
Des fonctions ayant des listes de types d'arguments diffrents ne seront pas considres comme en conflit au moment de leur cration, mais si des valeurs par dfauts sont fournies, elles peuvent se retrouver en conflit au moment de l'invocation. Considrez par
exemple :
CREATE FUNCTION truc(int) ...
CREATE FUNCTION truc(int, int default 42) ...
Un appel truc(10) chouera cause de l'ambigut sur la fonction appeler.

Notes
La syntaxe SQL complte des types est autoris pour dclarer les arguments en entre et la valeur de sortie d'une fonction. Nanmoins, les modificateurs du type de la fonction (par exemple le champ prcision pour un numeric) sont ignors par CREATE
FUNCTION. Du coup, par exemple, CREATE FUNCTION foo (varchar(10)) ... est identique CREATE FUNCTION foo (varchar) ....
Lors du remplacement d'une fonction existante avec CREATE OR REPLACE FUNCTION, il existe des restrictions sur le
changement des noms de paramtres. Vous ne pouvez pas modifier le nom de paramtre en entre dj affect mais vous pouvez
ajouter des noms aux paramtres qui n'en avaient pas. S'il y a plus d'un paramtre en sortie, vous ne pouvez pas changer les noms
des paramtres en sortie car cela changera les noms de colonne du type composite anonyme qui dcrit le rsultat de la fonction.
Ces restrictions sont l pour assurer que les appels suivants la fonction ne s'arrtent pas de fonctionner lorsqu'elle est remplace.

Exemples
Quelques exemples triviaux pour bien dbuter sont prsents ci-aprs. Pour plus d'informations et d'exemples, voir Section 35.3,
Fonctions utilisateur .
CREATE FUNCTION add(integer, integer) RETURNS integer
AS 'select $1 + $2;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
Incrmenter un entier, en utilisant le nom de l'argument, dans PL/pgSQL :
CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
BEGIN
RETURN i + 1;
END;
$$ LANGUAGE plpgsql;
Renvoyer un enregistrement contenant plusieurs paramtres en sortie :
CREATE FUNCTION dup(in int, out f1 int, out f2 text)
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
La mme chose, en plus verbeux, avec un type composite nomm explicitement :
CREATE TYPE dup_result AS (f1 int, f2 text);
CREATE FUNCTION dup(int) RETURNS dup_result
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
954

CREATE FUNCTION

Une autre faon de renvoyer plusieurs colonnes est d'utiliser une fonction TABLE :
CREATE FUNCTION dup(int) RETURNS TABLE(f1 int, f2 text)
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
Toutefois, une fonction TABLE est diffrente des exemples prcdents parce qu'elle retourne en fait un ensemble
d'enregistrements, pas juste un enregistrement.

crire des fonctions SECURITY DEFINER en toute scurit


Parce qu'une fonction SECURITY DEFINER est excute avec les droits de l'utilisateur qui l'a cr, une certaine attention est ncessaire pour s'assurer que la fonction ne peut pas tre utilise de faon maline. Pour des raisons de scurit, search_path doit tre
configur pour exclure les schmas modifiables par des utilisateurs indignes de confiance. Cela empche des utilisateurs malveillants de crer des objets qui masquent les objets utiliss par la fonction. Dans ce sens, le schma des tables temporaires est particulirement important car il est le premier schma parcouru et qu'il est normalement modifiable par tous les utilisateurs. Une solution consiste forcer le parcours de ce schma en dernier lieu. Pour cela, on crit pg_temp comme dernire entre de
search_path. La fonction suivante illustre une utilisation sre :
CREATE FUNCTION verifie_motdepasse(unom TEXT, motpasse TEXT)
RETURNS BOOLEAN AS $$
DECLARE ok BOOLEAN;
BEGIN
-- Effectuer le travail scuris de la fonction.
SELECT (motdepasse = $2) INTO ok
FROM
motsdepasse
WHERE
nomutilisateur = $1;
RETURN ok;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER
-- Configure un search_path scurise : les schmas de confiance, puis 'pg_temp'.
SET search_path = admin, pg_temp;
Avant PostgreSQL 8.3, l'option SET n'tait pas disponible, donc les anciennes fonctions pouvaient contenir un code assez complexe pour sauvegarder, initialiser puis restaurer un paramtre comme search_path. L'option SET est plus simple utiliser
dans ce but.
Un autre point garder en mmoire est que, par dfaut, le droit d'excution est donn PUBLIC pour les fonctions nouvellement
cres (voir GRANT(7) pour plus d'informations). Frquemment, vous souhaiterez restreindre l'utilisation d'une fonction security definer seulement quelques utilisateurs. Pour cela, vous devez rvoquer les droits PUBLIC puis donner le droit d'excution
aux utilisateurs slectionns. Pour viter que la nouvelle fonction soit accessible tous pendant un court moment, crez-la et initialisez les droits dans une mme transaction. Par exemple :
BEGIN;
CREATE FUNCTION verifie_motdepasse(unom TEXT, motpasse TEXT) ... SECURITY DEFINER;
REVOKE ALL ON FUNCTION verifie_motdepasse(unom TEXT, motpasse TEXT) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION verifie_motdepasse(unom TEXT, motpasse TEXT) TO admins;
COMMIT;

Compatibilit
Une commande CREATE FUNCTION est dfinie en SQL:1999 et ultrieur. La version PostgreSQL est similaire mais pas entirement compatible. Les attributs ne sont pas portables, pas plus que les diffrents langages disponibles.
Pour des raisons de compatibilit avec d'autres systmes de bases de donnes, modearg peut tre crit avant ou aprs nomarg.
Mais seule la premire faon est compatible avec le standard.
Le standard SQL ne dfinit pas de paramtres par dfaut. La syntaxe avec le mot cl DEFAULT provient d'Oracle, et elle est assez
proche de l'esprit du standard : SQL/PSQL l'utilise pour les valeurs par dfaut de variables. La syntaxe avec = est utilise dans TSQL et Firebird.
955

CREATE FUNCTION

Voir aussi
ALTER FUNCTION(7), DROP FUNCTION(7), GRANT(7), LOAD(7), REVOKE(7), createlang(1)

956

Nom
CREATE GROUP Dfinir un nouveau rle de base de donnes

Synopsis
CREATE GROUP nom [ [ WITH ] option [ ... ] ]
o option peut tre :
|
|
|
|
|
|
|
|
|
|
|
|
|

SUPERUSER | NOSUPERUSER
CREATEDB | NOCREATEDB
CREATEROLE | NOCREATEROLE
CREATEUSER | NOCREATEUSER
INHERIT | NOINHERIT
LOGIN | NOLOGIN
[ ENCRYPTED | UNENCRYPTED ] PASSWORD 'motdepasse'
VALID UNTIL 'dateheure'
IN ROLE nom_role [, ...]
IN GROUP nom_role [, ...]
ROLE nom_role [, ...]
ADMIN nom_role [, ...]
USER nom_role [, ...]
SYSID uid

Description
CREATE GROUP est dsormais un alias de CREATE ROLE(7).

Compatibilit
Il n'existe pas d'instruction CREATE GROUP dans le standard SQL.

Voir aussi
CREATE ROLE(7)

957

Nom
CREATE INDEX Dfinir un nouvel index

Synopsis
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ nom ] ON table [ USING mthode ]
( { colonne | ( expression ) } [ COLLATE collation ] [ classeop ] [ ASC | DESC ]
[ NULLS { FIRST | LAST } ] [, ...] )
[ WITH ( parametre_stockage = valeur [, ... ] ) ]
[ TABLESPACE espacelogique ]
[ WHERE prdicat ]

Description
CREATE INDEX construit un index sur le (ou les) colonne(s) spcifie(s) de la table spcifie. Les index sont principalement
utiliss pour amliorer les performances de la base de donnes (bien qu'une utilisation inapproprie puisse produire l'effet inverse).
Les champs cl pour l'index sont spcifis l'aide de noms des colonnes ou par des expressions crites entre parenthses. Plusieurs champs peuvent tre spcifis si la mthode d'indexation supporte les index multi-colonnes.
Un champ d'index peut tre une expression calcule partir des valeurs d'une ou plusieurs colonnes de la ligne de table. Cette
fonctionnalit peut tre utilise pour obtenir un accs rapide des donnes obtenues par transformation des donnes basiques.
Par exemple, un index calcul sur upper(col) autorise la clause WHERE upper(col) = 'JIM' utiliser un index.
PostgreSQL fournit les mthodes d'indexation B-tree (NDT : arbres balancs), hash (NDT : hachage), GiST (NDT : arbres de
recherche gnraliss) et GIN. Il est possible, bien que compliqu, de dfinir des mthodes d'indexation utilisateur.
Lorsque la clause WHERE est prsente, un index partiel est cr. Un index partiel est un index ne contenant des entres que pour
une portion d'une table, habituellement la portion sur laquelle l'indexation est la plus utile. Par exemple, si une table contient des
ordres facturs et d'autres qui ne le sont pas, et que les ordres non facturs n'occupent qu'une petite fraction du total de la table,
qui plus est frquemment utilise, les performances sont amliores par la cration d'un index sur cette portion. Une autre application possible est l'utilisation de la clause WHERE en combinaison avec UNIQUE pour assurer l'unicit sur un sous-ensemble
d'une table. Voir Section 11.8, Index partiels pour plus de renseignements.
L'expression utilise dans la clause WHERE peut ne faire rfrence qu' des colonnes de la table sous-jacente, mais elle peut utiliser toutes les colonnes, pas uniquement celles indexes. Actuellement, les sous-requtes et les expressions d'agrgats sont aussi
interdites dans la clause WHERE. Les mmes restrictions s'appliquent aux champs d'index qui sont des expressions.
Toutes les fonctions et oprateurs utiliss dans la dfinition d'index doivent tre immutable (NDT : immuable), c'est--dire
que leur rsultat ne doit dpendre que de leurs arguments et jamais d'une influence externe (telle que le contenu d'une autre table
ou l'heure). Cette restriction permet de s'assurer que le comportement de l'index est strictement dfini. Pour utiliser une fonction
utilisateur dans une expression d'index ou dans une clause WHERE, cette fonction doit tre marque immutable lors de sa cration.

Paramtres
UNIQUE
Le systme vrifie la prsence de valeurs dupliques dans la table la cration de l'index (si des donnes existent dj) et
chaque fois qu'une donne est ajoute. Les tentatives d'insertion ou de mises jour qui rsultent en des entres dupliques
engendrent une erreur.
CONCURRENTLY
Quand cette option est utilise, PostgreSQL construira l'index sans prendre de verrous qui bloquent les insertions, mises
jour, suppression en parallle sur cette table ; la construction d'un index standard verrouille les critures (mais pas les lectures) sur la table jusqu' la fin de la construction. Il est ncessaire d'avoir quelques connaissances avant d'utiliser cette option -- voir la section intitule Construire des index en parallle .
nom
Le nom de l'index crer. Aucun nom de schma ne peut tre inclus ici ; l'index est toujours cr dans le mme schma que
sa table parent. Si le nom est omis, PostgreSQL choisit un nom convenable bas sur le nom de la table parent et celui des
colonnes indexes.
table
Le nom de la table indexer (ventuellement qualifi du nom du schma).
958

CREATE INDEX

mthode
Le nom de la mthode utiliser pour l'index. Les choix sont btree, hash, gist et gin. La mthode par dfaut est btree.
colonne
Le nom d'une colonne de la table.
expression
Une expression base sur une ou plusieurs colonnes de la table. L'expression doit habituellement tre crite entre parenthses,
comme la syntaxe le prcise. Nanmoins, les parenthses peuvent tre omises si l'expression a la forme d'un appel de fonction.
collation
Le nom du collationnement utiliser pour l'index. Par dfaut, l'index utilise le collationnement dclar pour la colonne indexer ou le collationnement rsultant de l'expression indexer. Les index avec des collationnements spcifiques peuvent tre
utiles pour les requtes qui impliquent des expressions utilisant des collationnements spcifiques.
classeop
Le nom d'une classe d'oprateur. Voir plus bas pour les dtails.
ASC
Spcifie un ordre de tri ascendant (valeur par dfaut).
DESC
Spcifie un ordre de tri descendant.
NULLS FIRST
Spcifie que les valeurs NULL sont prsentes avant les valeurs non NULL. Ceci est la valeur par dfaut quand DESC est indiqu.
NULLS LAST
Spcifie que les valeurs NULL sont prsentes aprs les valeurs non NULL. Ceci est la valeur par dfaut quand ASC est indiqu.
paramtre_stockage
Le nom d'un paramtre de stockage spcifique la mthode d'indexage. Voir la section intitule Paramtres de stockage des
index pour les dtails.
espacelogique
Le tablespace dans lequel crer l'index. S'il n'est pas prcis, default_tablespace est consult, sauf si la table est temporaire auquel cas temp_tablespaces est utilis.
prdicat
L'expression de la contrainte pour un index partiel.

Paramtres de stockage des index


La clause WITH optionnelle spcifie des paramtres de stockage pour l'index. Chaque mthode d'indexage peut avoir son propre
ensemble de paramtres de stockage. Les mthodes d'indexage B-tree, hash et GiST acceptent toutes un seul paramtre :
FILLFACTOR
Le facteur de remplissage pour un index est un pourcentage qui dtermine quel point les pages d'index seront remplies par la
mthode d'indexage. Pour les B-tree, les pages enfants sont remplies jusqu' ce pourcentage lors de la construction initiale de
l'index, et aussi lors de l'extension de l'index sur la droite (ajoutant les valeurs de cl les plus importantes). Si les pages deviennent ensuite totalement remplies, elles seront partages, amenant une dgradation graduelle de l'efficacit de l'index. Les
arbres B-tree utilisent un facteur de remplissage de 90% par dfaut mais toute valeur entire comprise entre 10 et 100 peut
tre choisie. Si la table est statique, alors un facteur de 100 est meilleur pour minimiser la taille physique de l'index. Pour les
tables mises jour rgulirement, un facteur de remplissage plus petit est meilleur pour minimiser le besoin de pages divises.
Les autres mthodes d'indexage utilisent un facteur de remplissage de faon diffrente mais en gros analogue ; le facteur de
remplissage varie suivant les mthodes.
Les index GIN acceptent un paramtre supplmentaire :
FASTUPDATE
Ce paramtre rgit l'utilisation de la technique de mise jour rapide dcrite dans Section 54.3.1, Technique GIN de mise
jour rapide . C'est un paramtre boolen : ON active la mise jour rapide, OFF la dsactive. (Les autres faons d'crire ON et
OFF sont autorises, comme dcrit dans Section 18.1, Paramtres de configuration .) La valeur par dfaut est ON.

959

CREATE INDEX

Note
Dsactiver FASTUPDATE via ALTER INDEX empche les insertions futures d'aller dans la liste d'entres
d'index traiter, mais ne nettoie pas les entres prcdentes de cette liste. Vous voudrez peut tre ensuite excuter un VACUUM sur la table, afin de garantir que la liste traiter soit vide.

Construire des index en parallle


Crer un index peut interfrer avec les oprations normales d'une base de donnes. Habituellement, PostgreSQL verrouille la
table indexer pour la protger des critures et construit l'index complet avec un seul parcours de la table. Les autres transactions
peuvent toujours lire la table mais s'ils essaient d'insrer, mettre jour, supprimer des lignes dans la table, elles seront bloques
jusqu' la fin de la construction de l'index. Ceci peut avoir un effet srieux si le systme est une base en production. Les trs
grosses tables peuvent demander plusieurs heures pour tre indexes. Mme pour les petites tables, une construction d'index peut
bloquer les processus qui voudraient crire dans la table pendant des priodes longues sur un systme de production.
PostgreSQL supporte la construction des index sans verrouillage des critures. Cette mthode est appele en prcisant l'option
CONCURRENTLY de CREATE INDEX. Quand cette option est utilise, PostgreSQL doit raliser deux parcours de table et, en
plus, il doit attendre que toutes les transactions existantes qui peuvent utiliser cet index se terminent. Du coup, cette mthode requiert plus de temps qu'une construction standard de l'index et est bien plus longue se terminer. Nanmoins, comme cela autorise
la poursuite des oprations pendant la construction de l'index, cette mthode est utile pour ajouter de nouveaux index dans un environnement en production. Bien sr, la charge CPU et I/O supplmentaire impose par la cration de l'index peut ralentir les
autres oprations.
Dans la construction en parallle d'un index, l'index est enregistr dans les catalogues systmes dans une transaction, puis les deux
parcours de table interviennent dans deux transactions supplmentaires. Toute transaction active au dbut du second parcours de la
table peut bloquer la cration concurrente de l'index jusqu' sa fin, y compris pour les transactions qui rfrencent seulement la
table aprs que le deuxime parcours de table commence. La cration parallle d'index attend en srie que chaque ancienne transaction se termine en utilisant la mthode souligne dans la section Section 45.56, pg_locks .
Si un problme survient lors du parcours de la table, comme une violation d'unicit dans un index unique, la commande CREATE
INDEX chouera mais laissera derrire un index invalide . Cet index sera ignor par les requtes car il pourrait tre incomplet ;
nanmoins il consommera quand mme du temps lors des mises jour de l'index. La commande \d de psql rapportera cet index
comme INVALID :
postgres=# \d tab
Table "public.tab"
Column | Type
| Modifiers
--------+---------+----------col
| integer |
Indexes:
"idx" btree (col) INVALID
La mthode de rcupration recommande dans de tels cas est de supprimer l'index et de tenter de nouveau un CREATE INDEX
CONCURRENTLY. (Une autre possibilit est de reconstruire l'index avec REINDEX. Nanmoins, comme REINDEX ne supporte pas la construction d'index en parallle, cette option ne semble pas trs attirante.)
Lors de la construction d'un index unique en parallle, la contrainte d'unicit est dj place pour les autres transactions quand le
deuxime parcours de table commence. Cela signifie que des violations de contraintes pourraient tre rapportes dans les autres
requtes avant que l'index ne soit disponible, voire mme dans des cas o la construction de l'index va chouer. De plus, si un
chec survient dans le deuxime parcours, l'index invalide continue forcer la contrainte d'unicit.
Les constructions en parallle d'index avec expression et d'index partiels sont supportes. Les erreurs survenant pendant
l'valuation de ces expressions pourraient causer un comportement similaire celui dcrit ci-dessus pour les violations de
contraintes d'unicit.
Les constructions d'index standards permettent d'autres construction d'index en parallle sur la mme table mais seul une construction d'index en parallle peut survenir sur une table un mme moment. Dans les deux cas, aucun autre type de modification de
schma n'est autoris sur la table. Une autre diffrence est qu'une commande CREATE INDEX normale peut tre ralise
l'intrieur d'un bloc de transactions mais CREATE INDEX CONCURRENTLY ne le peut pas.

Notes
Chapitre 11, Index prsente des informations sur le moment o les index peuvent tre utiliss, quand ils ne le sont pas et dans
quelles situations particulires ils peuvent tre utiles.
Actuellement, seules les mthodes d'indexation B-tree, GiST et GIN supportent les index multi-colonnes. Jusqu' 32 champs
960

CREATE INDEX

peuvent tre spcifis par dfaut. (Cette limite peut tre modifie la compilation de PostgreSQL.) Seul B-tree supporte actuellement les index uniques.
Une classe d'oprateur peut tre spcifie pour chaque colonne d'un index. La classe d'oprateur identifie les oprateurs utiliser
par l'index pour cette colonne. Par exemple, un index B-tree sur des entiers cods sur quatre octets utilise la classe int4_ops,
qui contient des fonctions de comparaison pour les entiers sur quatre octets. En pratique, la classe d'oprateur par dfaut pour le
type de donnes de la colonne est gnralement suffisant. Les classes d'oprateur trouvent leur intrt principal dans l'existence,
pour certains types de donnes, de plusieurs ordonnancements significatifs.
Soit l'exemple d'un type de donnes nombre complexe qui doit tre class par sa valeur absolue ou par sa partie relle. Cela
peut tre ralis par la dfinition de deux classes d'oprateur pour le type de donnes, puis par la slection de la classe approprie
lors de la cration d'un index.
De plus amples informations sur les classes d'oprateurs sont disponibles dans Section 11.9, Classes et familles d'oprateurs et
dans Section 35.14, Interfacer des extensions d'index .
Pour les mthodes d'indexage qui supportent les parcours ordonns (actuellement seulement pour les B-tree), les clauses optionnelles ASC, DESC, NULLS FIRST et/ou NULLS LAST peuvent tre spcifies pour modifier l'ordre de tri normal de l'index.
Comme un index ordonn peut tre parcouru en avant et en arrire, il n'est habituellement pas utile de crer un index DESC sur
une colonne -- ce tri est dj disponible avec un index standard. L'intrt de ces options se rvle avec les index multi-colonnes.
Ils peuvent tre crs pour correspondre un tri particulier demand par une requte, comme SELECT ... ORDER BY x
ASC, y DESC. Les options NULLS sont utiles si vous avez besoin de supporter le comportement nulls sort low , plutt que le
nulls sort high par dfaut, dans les requtes qui dpendent des index pour viter l'tape du tri.
Pour la plupart des mthodes d'indexation, la vitesse de cration d'un index est dpendante du paramtre maintenance_work_mem.
Une plus grande valeur rduit le temps ncessaire la cration d'index, tant qu'elle ne dpasse pas la quantit de mmoire vraiment disponible, afin d'viter que la machine ne doive paginer. Pour les index de type hash, la valeur de effective_cache_size est
aussi importante pour le temps de cration de l'index : PostgreSQL utilisera une des deux mthodes de cration d'index hash
disponibles selon que la taille estime de l'index crer est suprieure ou infrieure effective_cache_size. Pour obtenir
les meilleurs rsultats, assurez-vous que ce paramtre est aussi positionn quelque chose qui reflte la quantit de mmoire disponible, et soyez attentif ce que la somme de maintenance_work_mem et effective_cache_size soit infrieure la
quantit de mmoire disponible de la machine pour PostgreSQL (en prenant en compte les autres programmes en cours
d'excution sur la machine).
DROP INDEX(7) est utilis pour supprimer un index.
Les versions prcdentes de PostgreSQL ont aussi une mthode d'index R-tree. Cette mthode a t supprime car elle n'a pas
d'avantages par rapport la mthode GiST. Si USING rtree est indiqu, CREATE INDEX l'interprtera comme USING
gist pour simplifier la conversions des anciennes bases GiST.

Exemples
Crer un index B-tree sur la colonne titre dans la table films :
CREATE UNIQUE INDEX title_idx ON films (title);
Pour crer un index sur l'expression lower(titre), permettant une recherche efficace quelque soit la casse :
CREATE INDEX ON films ((lower(titre)));
(dans cet exemple, nous avons choisi d'omettre le nom de l'index, donc le systme choisira un nom, typiquement
films_lower_idx.)
Pour crer un index avec un collationnement spcifique :
CREATE INDEX title_idx_german ON films (title COLLATE "de_DE");

Attention
Les oprations sur les index hash ne sont pas enregistres dans les journaux de transactions. Du coup, les index
hash doivent tre reconstruit avec REINDEX aprs un arrt brutal de la base de donnes si des modifications n'ont
pas t crites. De plus, les modifications dans les index hash ne sont pas rpliques avec la rplication Warm
Standby aprs la sauvegarde de base initiale, donc ces index donneront de mauvaises rponses aux requtes qui les
utilisent. Pour ces raisons, l'utilisation des index hash est actuellement dconseille.
Pour crer un index avec un ordre de tri des valeurs NULL diffrent du standard :
961

CREATE INDEX

CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST);


Pour crer un index avec un facteur de remplissage diffrent :
CREATE UNIQUE INDEX idx_titre ON films (titre) WITH (fillfactor = 70);
Pour crer un index GIN avec les mises jour rapides dsactives :
CREATE INDEX gin_idx ON documents_table USING gin (locations) WITH (fastupdate = off);
Crer un index sur la colonne code de la table films et donner l'index l'emplacement du tablespace espaceindex :
CREATE INDEX code_idx ON films (code) TABLESPACE espaceindex;
Pour crer un index GiST sur un attribut point, de faon ce que nous puissions utiliser rapidement les oprateurs box sur le rsultat de la fonction de conversion :
CREATE INDEX pointloc
ON points USING gist (box(location,location));
SELECT * FROM points
WHERE box(location,location) && '(0,0),(1,1)'::box;
Pour crer un index sans verrouiller les critures dans la table :
CREATE INDEX CONCURRENTLY index_quentite_ventes ON table_ventes (quantit);

Compatibilit
CREATE INDEX est une extension du langage PostgreSQL. Les index n'existent pas dans le standard SQL.

Voir aussi
ALTER INDEX(7), DROP INDEX(7)

962

Nom
CREATE LANGUAGE Dfinir un nouveau langage procdural

Synopsis
CREATE [ OR REPLACE ] [ PROCEDURAL ] LANGUAGE nom
CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE nom
HANDLER gestionnaire_appel [ VALIDATOR fonction_validation ]

Description
CREATE LANGUAGE enregistre un nouveau langage procdural une base de donnes PostgreSQL. En consquence, les
fonctions et les procdures de dclencheurs peuvent tre dfinies dans ce nouveau langage.

Note
partir de PostgreSQL 9.1, la plupart des langages procduraux ont t tranforms en extensions , et
doivent du coup tre installs avec CREATE EXTENSION(7), et non pas avec CREATE LANGUAGE.
L'utilisation directe de CREATE LANGUAGE devrait maintenant tre rserve aux scripts d'installation
d'extension. Si vous avez un langage nu dans votre base de donnes, peut-tre comme rsultat d'une mise
jour, vous pouvez le convertir en extension en utilisant CREATE EXTENSION nom_langage FROM unpackaged.
CREATE LANGUAGE associe en fait le nom du langage un ou des fonctions de gestion qui sont responsable de l'excution
des fonctions crites dans le langage. Chapitre 38, Langages de procdures offre de plus amples informations sur les gestionnaires de fonctions.
La commande CREATE LANGUAGE existe sous deux formes. Dans la premire, l'utilisateur ne fournit que le nom du langage dsir et le serveur PostgreSQL consulte le catalogue systme pg_pltemplate pour dterminer les paramtres adquats.
Dans la seconde, l'utilisateur fournit les paramtres du langage avec son nom. Cette forme peut tre utilise pour crer un langage non dfini dans pg_pltemplate. Cette approche est cependant obsolte.
Si le serveur trouve une entre dans le catalogue pg_pltemplate pour le nom donn, il utilise les donnes du catalogue quand
bien mme la commande incluerait les paramtres du langage. Ce comportement simplifie le chargement des anciens fichiers de
sauvegarde ; ceux-ci prsentent le risque de contenir des informations caduques sur les fonctions de support du langage.
Habituellement, l'utilisateur doit tre un superutilisateur PostgreSQL pour enregistrer un nouveau langage. Nanmoins, le propritaire d'une base de donnes peut enregistrer un nouveau langage dans sa base si le langage est list dans le catalogue
pg_pltemplate et est marqu comme autoris tre cr par les propritaires de base (tmpldbacreate true). La valeur par
dfaut est que les langages de confiance peuvent tre crs par les propritaires de base de donnes, mais cela peut tre modifi
par les superutilisateurs en ajustant le contenu de pg_pltemplate. Le crateur d'un langage devient son propritaire et peut ensuite le supprimer, le renommer ou le donner un autre propritaire.
CREATE OR REPLACE LANGUAGE crera un nouveau langage ou remplacera une dfinition existante. Si le langage
existe dj, ces paramtres sont mis jour suivant les valeurs indiques ou prises de pg_pltemplate mais le propritaire et les
droits du langage ne sont pas modifis et toutes fonctions existantes cres dans le langage sont supposes tre toujours valides.
En plus des droits ncessaires pour crer un langage, un utilisateur doit tre superutilisateur ou propritaire du langage existant.
Le cas REPLACE a pour but principal d'tre utilis pour s'assurer que le langage existe. Si le langage a une entre pg_pltemplate
alors REPLACE ne modifiera rien sur la dfinition existante, sauf dans le cas inhabituel o l'entre pg_pltemplate a t modifie
depuis que le langage a t cr.

Paramtres
TRUSTED
TRUSTED indique que le langage ne donne pas accs aux donnes auquel l'utilisateur n'a pas normalement accs. Si ce mot
cl est omis l'enregistrement du langage, seuls les superutilisateurs peuvent utiliser ce langage pour crer de nouvelles
fonctions.
PROCEDURAL
Sans objet.
nom
Le nom du nouveau langage procdural, insensible la casse. Il ne peut y avoir deux langages portant le mme nom au sein
963

CREATE LANGUAGE

de la base de donnes.
Pour des raisons de compatibilit descendante, le nom doit tre entour de guillemets simples.
HANDLER gestionnaire_appel
gestionnaire_appel est le nom d'une fonction prcdemment enregistre. C'est elle qui est appele pour excuter les
fonctions du langage procdural. Le gestionnaire d'appels d'un langage procdural doit tre crit dans un langage compil, tel
que le C, avec la convention d'appel version 1 et enregistr dans PostgreSQL comme une fonction ne prenant aucun argument et retournant le type language_handler, type servant essentiellement identifier la fonction comme gestionnaire
d'appels.
INLINE gestionnaire_en_ligne
gestionnaire_en_ligne est le nom d'une fonction dj enregistre qui sera appele pour excuter un bloc de code anonyme (voir la commande DO(7)) dans ce langage. Si aucune fonction gestionnaire_en_ligne n'est indique, le langage ne supporte pas les blocs de code anonymes. La fonction de gestion doit prendre un argument du type internal, qui sera
la reprsentation interne de la commande DO, et il renverra le type void. La valeur de retour du gestionnaire est ignore.
VALIDATOR fonction_validation
fonction_validation est le nom d'une fonction prcdemment enregistre. C'est elle qui est appele pour valider toute
nouvelle fonction crite dans ce langage. Si aucune fonction de validation n'est spcifie, alors toute nouvelle fonction n'est
pas vrifie sa cration. La fonction de validation prend obligatoirement un argument de type oid, OID de la fonction
crer, et renvoie par convention void.
Une fonction de validation contrle gnralement le corps de la fonction pour s'assurer de sa justesse syntaxique mais peut
galement vrifier d'autres proprits de la fonction (l'incapacit du langage grer certains types d'argument, par exemple).
Le signalement d'erreur se fait l'aide de la fonction ereport(). La valeur de retour de la fonction est ignore.
L'option TRUSTED et le(s) nom(s) de la fonction de support sont ignors s'il existe une entre dans la table pg_pltemplate pour le
nom du langage spcifi.

Notes
Le programme createlang(1) est un simple enrobage de la commande CREATE LANGUAGE. Il facilite l'installation des langages procduraux partir de la ligne de commande du shell.
DROP LANGUAGE(7), ou mieux, le programme droplang(1) sont utiliss pour supprimer des langages procduraux.
Le catalogue systme pg_language (voir Section 45.27, pg_language ) contient des informations sur les langages installs.
De plus, createlang dispose d'une option pour lister ces langages.
Pour crer des fonctions dans un langage procdural, l'utilisateur doit possder le droit USAGE pour ce langage. Par dfaut,
USAGE est donn PUBLIC (c'est--dire tout le monde) pour les langages de confiance. Ce droit peut tre rvoqu si ncessaire.
Les langages procduraux sont installes par base. Nanmoins, un langage peut tre install dans la base de donnes template1,
ce qui le rend automatiquement disponible dans toutes les bases de donnes cres par la suite.
Le gestionnaire d'appels, le gestionnaire en ligne (s'il y en a un) et la fonction de validation (s'il y en a une) doivent exister pralablement si le serveur ne possde pas d'entre pour ce langage dans pg_pltemplate. Dans le cas contraire, les fonctions n'ont pas besoin de pr-exister ; elles sont automatiquement dfinies si elles ne sont pas prsentes dans la base de donnes. (Cela peut amener
CREATE LANGUAGE chouer si la bibliothque partage implmentant le langage n'est pas disponible dans l'installation.)
Dans les versions de PostgreSQL antrieures 7.3, il tait ncessaire de dclarer des fonctions de gestion renvoyant le type
opaque, plutt que language_handler. Pour accepter le chargement d'anciens fichiers de sauvegarde, CREATE LANGUAGE accepte toute fonction retournant le type opaque mais affiche un message d'avertissement et modifie le type de retour de la fonction
en language_handler.

Exemples
Tout langage procdural standard sera prfrentiellement cr ainsi :
CREATE LANGUAGE plperl;
Pour un langage inconnu du catalogue pg_pltemplate, une squence comme celle-ci est ncessaire :
CREATE FUNCTION plsample_call_handler() RETURNS language_handler
AS '$libdir/plsample'
LANGUAGE C;
CREATE LANGUAGE plsample
HANDLER plsample_call_handler;
964

CREATE LANGUAGE

Compatibilit
CREATE LANGUAGE est un extension de PostgreSQL.

Voir aussi
ALTER LANGUAGE(7), CREATE FUNCTION(7), DROP LANGUAGE(7), GRANT(7), REVOKE(7), createlang(1), droplang(1)

965

Nom
CREATE OPERATOR Dfinir un nouvel oprateur

Synopsis
CREATE OPERATOR nom (
PROCEDURE = nom_fonction
[, LEFTARG = type_gauche ]
[, RIGHTARG = type_droit ]
[, COMMUTATOR = op_com ]
[, NEGATOR = op_neg ]
[, RESTRICT = proc_res ]
[, JOIN = proc_join ]
[, HASHES ] [, MERGES ]
)

Description
CREATE OPERATOR dfinit un nouvel oprateur, nom. L'utilisateur qui dfinit un oprateur en devient propritaire. Si un
nom de schma est donn, l'oprateur est cr dans le schma spcifi. Sinon, il est cr dans le schma courant.
Le nom de l'oprateur est une squence d'au plus NAMEDATALEN-1 (63 par dfaut) caractres parmi la liste suivante :
+-*/<>=~!@#%^&|`?
Il existe quelques restrictions dans le choix du nom :

-- et /* ne peuvent pas apparatre dans le nom d'un oprateur car ils sont pris pour le dbut d'un commentaire.

Un nom d'oprateur multicaractres ne peut pas finir avec + ou - sauf si le nom contient l'un, au moins, de ces caractres :
~!@#%^&|`?
Par exemple, @- est un nom d'oprateur autoris mais *- n'en est pas un. Cette restriction permet PostgreSQL
d'analyser les commandes compatibles SQL sans ncessiter d'espaces entre les lexmes.

L'utilisation de => comme nom d'oprateur est dconseille. Il pourrait tre compltement interdit dans une prochaine version.

L'oprateur != est remplac par <> la saisie, ces deux noms sont donc toujours quivalents.
Au moins un des deux LEFTARG et RIGHTARG doit tre dfini. Pour les oprateurs binaires, les deux doivent l'tre. Pour les
oprateurs unaires droits, seul LEFTARG doit l'tre, RIGHTARG pour les oprateurs unaires gauches.
La procdure nom_fonction doit avoir t prcdemment dfinie par CREATE FUNCTION et doit accepter le bon nombre
d'arguments (un ou deux) des types indiqus.
Les autres clauses spcifient des clauses optionnelles d'optimisation d'oprateur. Leur signification est dtaille dans Section 35.13, Informations sur l'optimisation d'un oprateur .

Paramtres
nom
Le nom de l'oprateur dfinir. Voir ci-dessus pour les caractres autoriss. Le nom peut tre qualifi du nom du schma,
par exemple CREATE OPERATOR monschema.+ (...). Dans le cas contraire, il est cr dans le schma courant.
Deux oprateurs dans le mme schma peuvent avoir le mme nom s'ils oprent sur des types de donnes diffrents. On
parle alors de surchargement.
nom_fonction
La fonction utilise pour implanter cet oprateur.
type_gauche
Le type de donnes de l'oprande gauche de l'oprateur, s'il existe. Cette option est omise pour un oprateur unaire gauche.
type_droit
Le type de donnes de l'oprande droit de l'oprateur, s'il existe. Cette option est omise pour un oprateur unaire droit.
966

CREATE OPERATOR

op_com
Le commutateur de cet oprateur.
op_neg
La ngation de cet oprateur.
proc_res
La fonction d'estimation de la slectivit de restriction pour cet oprateur.
proc_join
La fonction d'estimation de la slectivit de jointure pour cet oprateur.
HASHES
L'oprateur peut supporter une jointure de hachage.
MERGES
L'oprateur peut supporter une jointure de fusion.
La syntaxe OPERATOR() est utilise pour prciser un nom d'oprateur qualifi d'un schma dans op_com ou dans les autres arguments optionnels. Par exemple :
COMMUTATOR = OPERATOR(mon_schema.===) ,

Notes
Section 35.12, Oprateurs dfinis par l'utilisateur fournit de plus amples informations.
Il n'est pas possible de spcifier la prcdence lexicale d'un oprateur dans CREATE OPERATOR car le comportement de prcdence de l'analyseur n'est pas modifiable. Voir Section 4.1.6, Prcdence d'oprateurs pour des dtails sur la gestion de la
prcdence.
Les options obsoltes, SORT1, SORT2, LTCMP et GTCMP taient utilises auparavant pour spcifier les noms des oprateurs de
tris associs avec un oprateur joignable par fusion (mergejoinable). Ceci n'est plus ncessaire car l'information sur les oprateurs associs est disponible en cherchant les familles d'oprateur B-tree. Si une des ces options est fournie, elle est ignore mais
configure implicitement MERGES true.
DROP OPERATOR(7) est utilis pour supprimer les oprateurs utilisateur, ALTER OPERATOR(7) pour les modifier.

Exemples
La commande suivante dfinit un nouvel oprateur, area-equality , pour le type de donnes box :
CREATE OPERATOR === (
LEFTARG = box,
RIGHTARG = box,
PROCEDURE = area_equal_procedure,
COMMUTATOR = ===,
NEGATOR = !==,
RESTRICT = area_restriction_procedure,
JOIN = area_join_procedure,
HASHES, MERGES
);

Compatibilit
CREATE OPERATOR est une extension PostgreSQL. Il n'existe pas d'oprateurs utilisateur dans le standard SQL.

Voir aussi
ALTER OPERATOR(7), CREATE OPERATOR CLASS(7), DROP OPERATOR(7)

967

Nom
CREATE OPERATOR CLASS Dfinir une nouvelle classe d'oprateur

Synopsis
CREATE OPERATOR CLASS nom [ DEFAULT ] FOR TYPE type_donnee
USING methode_indexage [ FAMILY nom_famille ] AS
{ OPERATOR numero_strategie nom_operateur [ ( type_op, type_op ) ] [ FOR SEARCH |
FOR ORDER BY nom_famille_tri ]
| FUNCTION numero_support [ ( type_op [ , type_op ] ) ] nom_fonction (
type_argument [, ...] )
| STORAGE type_stockage
} [, ... ]

Description
CREATE OPERATOR CLASS cre une nouvelle classe d'oprateur. Une classe d'oprateur dfinit la faon dont un type de
donnes particulier peut tre utilis avec un index. La classe d'oprateur spcifie le rle particulier ou la stratgie que jouent
certains oprateurs pour ce type de donnes et cette mthode d'indexation. La classe d'oprateur spcifie aussi les procdures de
support utiliser par la mthode d'indexation quand la classe d'oprateur est slectionne pour une colonne d'index. Tous les
oprateurs et fonctions utiliss par une classe d'oprateur doivent tre dfinis avant la cration de la classe d'oprateur.
Si un nom de schma est donn, la classe d'oprateur est cre dans le schma spcifi. Sinon, elle est cre dans le schma courant. Deux classes d'oprateur ne peuvent avoir le mme nom que s'ils concernent des mthodes d'indexation diffrentes.
L'utilisateur qui dfinit une classe d'oprateur en devient propritaire. Actuellement, le crateur doit tre superutilisateur. Cette
restriction existe parce qu'une dfinition errone d'une classe d'oprateur peut gner le serveur, voire causer un arrt brutal de
celui-ci.
Actuellement, CREATE OPERATOR CLASS ne vrifie pas si la dfinition de la classe d'oprateur inclut tous les oprateurs
et fonctions requis par la mthode d'indexation. Il ne verifie pas non plus si les oprateurs et les fonctions forment un ensemble
cohrent. Il est de la responsabilit de l'utilisateur de dfinir une classe d'oprateur valide.
Les classes d'oprateur en relation peuvent tre groupes dans des familles d'oprateurs. Pour ajouter une nouvelle classe
d'oprateur une famille existante, indiquez l'option FAMILY dans CREATE OPERATOR CLASS. Sans cette option, la nouvelle classe est place dans une famille de mme nom (crant la famille si elle n'existe pas).
Section 35.14, Interfacer des extensions d'index fournit de plus amples informations.

Paramtres
nom
Le nom (ventuellement qualifi du nom du schm) de la classe d'oprateur crer.
DEFAULT
La classe d'oprateur est celle par dfaut pour son type de donnes. Il ne peut y avoir qu'une classe d'oprateur par dfaut
pour un type de donnes et une mthode d'indexation particuliers.
type_donnes
Le type de donnes de la colonne auquel s'applique cette classe d'oprateur.
mthode_index
Le nom de la mthode d'indexation laquelle s'applique la classe d'oprateur.
nom_famille
Le nom d'une famille d'oprateur existante pour lui ajouter cette classe d'oprateur. Si non spcifi, une famille du mme
nom que l'oprateur est utilise (la crant si elle n'existe pas dj).
numro_stratgie
Le numro de stratgie de la mthode d'indexation pour un oprateur associ la classe d'oprateur.
nom_oprateur
Le nom (ventuellement qualifi du nom du schma) d'un oprateur associ la classe d'oprateur.
op_type
Dans une clause OPERATOR, le(s) type(s) de donnes de l'oprande d'un oprateur ou NONE pour signifier un oprateur
968

CREATE OPERATOR CLASS

unaire (droite ou gauche). Les types de donnes de l'oprande peuvent tre omis dans le cas o ils sont identiques au type de
donnes de la classe d'oprateur.
Dans une clause FUNCTION, le (ou les) types de donnes en oprande, support par la fonction, si diffrent du type de donnes en entre de la fonction (pour les index B-tree et hash) ou le type de donnes de la classe (pour les index GIN et GiST).
Ces valeurs par dfaut sont toujours correctes, donc il n'est pas ncessaire de prciser type_op dans une clause FUNCTION
de la commande CREATE OPERATOR CLASS, mais l'option est fournie pour des raisons de cohrence avec la syntaxe de
ALTER OPERATOR FAMILY.
nom_famille_tri
Le nom (ventuellement qualifi du nom du schma) d'une famille d'oprateur btree qui dcrit l'ordre de tri associ un
oprateur de tri.
Si ni FOR SEARCH ni FOR ORDER BY ne sont spcifis, FOR SEARCH est la valeur par dfaut.
numro_support
Le numro de procdure support de la mthode d'indexation pour une fonction associe la classe d'oprateur.
nom_fonction
Le nom (ventuellement qualifi du nom du schma) d'une fonction procdure support pour la mthode d'indexation de la
classe d'oprateur.
types_argument
Le(s) type(s) de donnes des paramtres de la fonction.
type_stockage
Le type de donnes rellement stock dans l'index. C'est normalement le mme que le type de donnes de la colonne mais certaines mthodes d'indexage (GIN et GiST actuellement) autorisent un type diffrent. La clause STORAGE doit tre omise sauf
si la mthode d'indexation autorise un type diffrent.
L'ordre des clauses OPERATOR, FUNCTION et STORAGE n'a aucune importance.

Notes
Comme toute la partie d'indexage ne vrifie pas les droits d'accs aux fonctions avant de les utiliser, inclure une fonction ou un
oprateur dans une classe d'oprateur the index machinery does not check access permissions on functions before using them, including a function or operator in an operator class is quivalent donner les droits d'excution PUBLIC sur celle-ci. Ce n'est pas
un problme habituellement pour les types de fonctions utiles dans une classe d'oprateur.
Les oprateurs ne doivent pas tre dfinis par des fonctions SQL. Une fonction SQL peut tre intgre dans la requte appelante,
ce qui empche l'optimiseur de faire la correspondance avec un index.
Avant PostgreSQL 8.4, la clause OPERATOR pouvait inclure l'option RECHECK. Cela n'est plus support car le fait qu'un index
soit perte est maintenant dtermin l'excution. Ceci permet une gestion plus efficace des cas o l'oprateur pourrait ou non
tre perte.

Exemples
La commande issue de l'exemple suivant dfinit une classe d'oprateur d'indexation GiST pour le type de donnes _int4 (tableau
de int4). Voir le module intarray pour l'exemple complet.
CREATE OPERATOR CLASS gist__int_ops
DEFAULT FOR TYPE _int4 USING gist AS
OPERATOR
3
&&,
OPERATOR
6
= (anyarray, anyarray),
OPERATOR
7
@>,
OPERATOR
8
<@,
OPERATOR
20
@@ (_int4, query_int),
FUNCTION
1
g_int_consistent (internal, _int4, int, oid, internal),
FUNCTION
2
g_int_union (internal, internal),
FUNCTION
3
g_int_compress (internal),
FUNCTION
4
g_int_decompress (internal),
FUNCTION
5
g_int_penalty (internal, internal, internal),
FUNCTION
6
g_int_picksplit (internal, internal),
FUNCTION
7
g_int_same (_int4, _int4, internal);

Compatibilit
CREATE OPERATOR CLASS est une extension PostgreSQL. Il n'existe pas d'instruction CREATE OPERATOR CLASS
969

CREATE OPERATOR CLASS

dans le standard SQL.

Voir aussi
ALTER OPERATOR CLASS(7), DROP OPERATOR CLASS(7), CREATE OPERATOR FAMILY(7), ALTER OPERATOR
FAMILY(7)

970

Nom
CREATE OPERATOR FAMILY dfinir une nouvelle famille d'oprateur

Synopsis
CREATE OPERATOR FAMILY nom USING methode_indexage

Description
CREATE OPERATOR FAMILY cre une nouvelle famille d'oprateurs. Une famille d'oprateurs dfinit une collection de
classes d'oprateur en relation et peut-tre quelques oprateurs et fonctions de support supplmentaires compatibles avec ces
classes d'oprateurs mais non essentiels au bon fonctionnement des index individuels. (Les oprateurs et fonctions essentiels aux
index doivent tre groups avec la classe d'oprateur adquate, plutt qu'tre des membres lches dans la famille d'oprateur.
Typiquement, les oprateurs sur un seul type de donnes peuvent tre lches dans une famille d'oprateur contenant des classes
d'oprateur pour les deux types de donnes.)
La nouvelle famille d'oprateur est initialement vide. Elle sera remplie en excutant par la suite des commandes CREATE
OPERATOR CLASS pour ajouter les classes d'oprateurs contenues et, en option, des commandes ALTER OPERATOR
FAMILY pour ajouter des oprateurs et leur fonctions de support correspondantes en tant que membres lches .
Si un nom de schma est prcise, la famille d'oprateur est cre dans le schma en question. Sinon elle est cre dans le schma en cours. Deux familles d'oprateurs du mme schma ne peuvent avoir le mme nom que s'ils sont des mthodes d'indexage
diffrentes.
L'utilisateur qui dfinit une famille d'oprateur devient son propritaire. Actuellement, l'utilisateur qui cre doit tre un superutilisateur. (Cette restriction est ncessaire car une dfinition errone d'une famille d'oprateur pourrait gner le serveur, voire
mme l'arrter brutalement.)
Voir Section 35.14, Interfacer des extensions d'index pour plus d'informations.

Paramtres
nom
Le nom de la famille d'oprateur (pouvant tre qualifi du schma).
methode_indexage
Le nom de la mthode d'indexage utilise par cette famille d'oprateur.

Compatibilit
CREATE OPERATOR FAMILY est un extension PostgreSQL. Il n'existe pas d'instruction CREATE OPERATOR FAMILY dans le standard SQL.

Voir aussi
ALTER OPERATOR FAMILY(7), DROP OPERATOR FAMILY(7), CREATE OPERATOR CLASS(7), ALTER OPERATOR CLASS(7), DROP OPERATOR CLASS(7)

971

Nom
CREATE ROLE Dfinir un nouveau rle de base de donnes

Synopsis
CREATE ROLE nom [ [ WITH ] option [ ... ] ]
o option peut tre :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

SUPERUSER | NOSUPERUSER
CREATEDB | NOCREATEDB
CREATEROLE | NOCREATEROLE
CREATEUSER | NOCREATEUSER
INHERIT | NOINHERIT
LOGIN | NOLOGIN
REPLICATION | NOREPLICATION
CONNECTION LIMIT limite_connexion
[ ENCRYPTED | UNENCRYPTED ] PASSWORD 'motdepasse'
VALID UNTIL 'heuredate'
IN ROLE nom_role [, ...]
IN GROUP nom_role [, ...]
ROLE nom_role [, ...]
ADMIN nom_role [, ...]
USER nom_role [, ...]
SYSID uid

Description
CREATE ROLE ajoute un nouveau rle dans une grappe (cluster) de bases de donnes PostgreSQL. Un rle est une entit
qui peut possder des objets de la base de donnes et avoir des droits sur la base. Il peut tre considr comme un utilisateur ,
un groupe ou les deux suivant la faon dont il est utilis. Chapitre 20, Rles de la base de donnes et Chapitre 19, Authentification du client donnent de plus amples informations sur la gestion des utilisateurs et l'authentification. Il est ncessaire de
possder le droit CREATEROLE ou d'tre superutilisateur pour utiliser cette commande.
Les rles sont dfinis au niveau de la grappe de bases de donnes, et sont donc valides dans toutes les bases de la grappe.

Paramtres
nom
Le nom du nouveau rle.
SUPERUSER, NOSUPERUSER
Ces clauses dfinissent si le nouveau rle est un superutilisateur et peut ainsi outrepasser les droits d'accs la base de
donnes. Le statut de superutilisateur est dangereux et ne doit tre utilis que lorsque cela est rellement ncessaire. Seul un
superutilisateur peut crer un superutilisateur. NOSUPERUSER est la valeur par dfaut.
CREATEDB, NOCREATEDB
Ces clauses prcisent le droit de cration de bases de donnes. Si CREATEDB est spcifi, l'autorisation est donne au rle,
NOCREATEDB produit l'effet inverse. NOCREATEDB est la valeur par dfaut.
CREATEROLE, NOCREATEROLE
Ces clauses prcisent le droit de cration de nouveaux rles (c'est--dire d'excuter CREATE ROLE). Un rle qui possde
le droit CREATEROLE peut aussi modifier ou supprimer d'autres rles. NOCREATEROLE est la valeur par dfaut.
CREATEUSER, NOCREATEUSER
Ces clauses, obsoltes mais toujours acceptes, sont quivalentes SUPERUSER et NOSUPERUSER. Elles ne sont pas quivalentes CREATEROLE.
INHERIT, NOINHERIT
Ces clauses prcisent si un rle hrite des droits d'un rle dont il est membre. Un rle qui possde l'attribut INHERIT
peut automatiquement utiliser tout privilge dtenu par un rle dont il est membre direct ou indirect. Sans INHERIT,
l'appartenance un autre rle lui confre uniquement la possibilit d'utiliser SET ROLE pour acqurir les droits de l'autre
rle ils ne sont disponibles qu'aprs cela. INHERIT est la valeur par dfaut.
LOGIN, NOLOGIN
972

CREATE ROLE

Ces clauses prcisent si un rle est autoris se connecter, c'est--dire si le rle peut tre donn comme nom pour
l'autorisation initiale de session la connexion du client. Un rle ayant l'attribut LOGIN peut tre vu comme un utilisateur.
Les rles qui ne disposent pas de cet attribut sont utiles pour grer les privilges de la base de donnes mais ne sont pas des
utilisateurs au sens habituel du mot. NOLOGIN est la valeur par dfaut, sauf lorsque CREATE ROLE est appel travers la
commande CREATE USER.
REPLICATION, NOREPLICATION
Ces clauses dterminent si un rle peut initier une rplication en flux ou placer le systme en mode sauvegarde ou l'en sortir.
Un rle ayant l'attribut REPLICATION est un rle trs privilgi et ne devrait tre utilis que pour la rplication. NOREPLICATION est la valeur par dfaut sauf pour les superutilisateurs.
CONNECTION LIMIT limiteconnexion
Le nombre maximum de connexions concurrentes possibles pour le rle, s'il possde le droit de connexion. -1 (valeur par dfaut) signifie qu'il n'y a pas de limite.
PASSWORD motdepasse
Le mot de passe du rle. Il n'est utile que pour les rles ayant l'attribut LOGIN, mais il est possible d'en dfinir un pour les
rles qui ne l'ont pas. Cette option peut tre omise si l'authentification par mot de passe n'est pas envisage. Si aucun mot de
passe n'est spcifi, le mot de passe sera NULL et l'authentification par mot de passe chouera toujours pour cet utilisateur.
Un mot de passe NULL peut aussi tre indiqu explicitement avec PASSWORD NULL.
ENCRYPTED, UNENCRYPTED
Ces mots cls contrlent le chiffrement du mot de passe stock dans les catalogues systme. En l'absence de prcision, le
comportement par dfaut est dtermin par le paramtre de configuration password_encryption. Si le mot de passe prsent
est dj une chane chiffre avec MD5, il est stock ainsi, quelque soit le mot-cl spcifi, ENCRYPTED ou UNENCRYPTED
(le systme ne peut pas dchiffrer la chane dj chiffre). Cela permet de recharger des mots de passe chiffrs lors
d'oprations de sauvegarde/restauration.
D'anciens clients peuvent ne pas disposer du support pour le mcanisme d'authentification MD5, ncessaire pour travailler
avec les mots de passe stocks chiffrs.
VALID UNTIL 'dateheure'
Cette clause configure la date et l'heure de fin de validit du mot de passe. Sans prcision, le mot de passe est indfiniment
valide.
IN ROLE nom_role
Cette clause liste les rles dont le nouveau rle est membre. Il n'existe pas d'option pour ajouter le nouveau rle en tant
qu'administrateur ; cela se fait l'aide d'une commande GRANT spare.
IN GROUP nom_role
IN GROUP est un quivalent obsolte de IN ROLE.
ROLE nom_role
Cette clause liste les rles membres du nouveau rle. Le nouveau rle devient ainsi un groupe .
ADMIN nom_role
Cette clause est quivalente la clause ROLE, la diffrence que les rles nomms sont ajouts au nouveau rle avec l'option
WITH ADMIN OPTION. Cela leur confre le droit de promouvoir d'autres rles l'appartenance celui-ci.
USER nom_role
USER est un quivalent osbolte de ROLE.
SYSID uid
La clause SYSID est ignore, mais toujours accepte pour des raisons de compatibilit.

Notes
ALTER ROLE(7) est utilis pour modifier les attributs d'un rle, et DROP ROLE(7) pour supprimer un rle. Tous les attributs positionns par CREATE ROLE peuvent tre modifis par la suite l'aide de commandes ALTER ROLE.
Il est prfrable d'utiliser GRANT(7) et REVOKE(7) pour ajouter et supprimer des membres de rles utiliss comme groupes.
La clause VALID UNTIL dfinit les date et heure d'expiration du mot de passe uniquement, pas du rle. En particulier, les date et
heure d'expiration ne sont pas vrifies lors de connexions l'aide de mthodes d'authentification qui n'utilisent pas les mots de
passe.
L'attribut INHERIT gouverne l'hritage des droits confrables (c'est--dire les droits d'accs aux objets de la base de donnes et
les appartenances aux rles). Il ne s'applique pas aux attributs de rle spciaux configurs par CREATE ROLE et ALTER
ROLE. Par exemple, tre membre d'un rle disposant du droit CREATEDB ne confre pas automatiquement le droit de cration de
973

CREATE ROLE

bases de donnes, mme avec INHERIT positionn ; il est ncessaire d'acqurir ce rle via SET ROLE(7) avant de crer une base
de donnes.
L'attribut INHERIT est la valeur par dfaut pour des raisons de compatibilit descendante : dans les prcdentes versions de PostgreSQL, les utilisateurs avaient toujours accs tous les droits des groupes dont ils taient membres. Toutefois, NOINHERIT
est plus respectueux de la smantique spcifie dans le standard SQL.
Le privilge CREATEROLE impose quelques prcautions. Il n'y a pas de concept d'hritage des droits pour un tel rle. Cela signifie qu'un rle qui ne possde pas un droit spcifique, mais est autoris crer d'autres rles, peut aisment crer un rle possdant
des droits diffrents des siens (sauf en ce qui concerne la cration des rles superutilisateur). Par exemple, si le rle user a le
droit CREATEROLE mais pas le droit CREATEDB, il peut toujours crer un rle possdant le droit CREATEDB. Il est de ce fait important de considrer les rles possdant le privilge CREATEROLE comme des superutilisateurs en puissance.
PostgreSQL inclut un programme, createuser(1) qui possde les mmes fonctionnalits que CREATE ROLE (en fait, il appelle
cette commande) et peut tre lanc partir du shell.
L'option CONNECTION LIMIT n'est vrifie qu'approximativement. Si deux nouvelles sessions sont lances peu prs simultanment alors qu'il ne reste qu'un seul emplacement de connexion disponible pour le rle, il est possible que les deux chouent.
De plus, la limite n'est jamais vrifie pour les superutilisateurs.
Faites attention lorsque vous donnez un mot de passe non chiffr avec cette commande. Le mot de passe sera transmis en clair au
serveur. Ce dernier pourrait tre tracer dans l'historique des commandes du client ou dans les traces du serveur. Nanmoins, la
commande createuser(1) transmet le mot de passe chiffr. De plus, psql(1) contient une commande \password que vous pouvez
utiliser pour modifier en toute scurit votre mot de passe.

Exemples
Crer un rle qui peut se connecter mais sans lui donner de mot de passe :
CREATE ROLE jonathan LOGIN;
Crer un rle avec un mot de passe :
CREATE USER davide WITH PASSWORD 'jw8s0F4';
(CREATE USER est identique CREATE ROLE mais implique LOGIN.)
Crer un rle avec un mot de passe valide jusqu' fin 2006. Une seconde aprs le passage 2007, le mot de passe n'est plus valide.
CREATE ROLE miriam WITH LOGIN PASSWORD 'jw8s0F4' VALID UNTIL '2007-01-01';
Crer un rle qui peut crer des bases de donnes et grer des rles :
CREATE ROLE admin WITH CREATEDB CREATEROLE;

Compatibilit
L'instruction CREATE ROLE est dfinie dans le standard SQL. Ce dernier n'impose que la syntaxe
CREATE ROLE nom [ WITH ADMIN nom_role ]
La possibilit d'avoir plusieurs administrateurs initiaux et toutes les autres options de CREATE ROLE sont des extensions PostgreSQL.
Le standard SQL dfinit les concepts d'utilisateurs et de rles mais les considre comme des concepts distincts et laisse la spcification des commandes de dfinition des utilisateurs l'implantation de chaque base de donnes. PostgreSQL a pris le parti
d'unifier les utilisateurs et les rles au sein d'une mme entit. Ainsi, les rles ont plus d'attributs optionnels que dans le standard.
Le comportement spcifi par le standard SQL peut tre approch en donnant aux utilisateurs l'attribut NOINHERIT et aux rles
l'attribut INHERIT.

Voir aussi
SET ROLE(7), ALTER ROLE(7), DROP ROLE(7), GRANT(7), REVOKE(7), createuser(1)

974

Nom
CREATE RULE Dfinir une nouvelle rgle de rcriture

Synopsis
CREATE [ OR REPLACE ] RULE nom AS ON vnement
TO table [ WHERE condition ]
DO [ ALSO | INSTEAD ] { NOTHING | commande | ( commande ; commande ... ) }

Description
CREATE RULE dfinit une nouvelle rgle sur une table ou une vue. CREATE OR REPLACE RULE cre une nouvelle
rgle ou remplace la rgle si elle existe dj.
Le systme de rgles de PostgreSQL autorise la dfinition d'actions alternatives sur les insertions, mises jour ou suppressions dans les tables. Pour rsumer, une rgle impose des commandes supplmentaires lors de l'excution d'une instruction sur
une table donne. Une rgle INSTEAD, au contraire, permet de remplacer une commande par une autre, voire d'empcher sa
ralisation. Ce sont galement les rgles qui sont utilises pour implanter les vues.
Une rgle est un mcanisme de transformation de commandes, une macro . La transformation intervient avant l'excution de
la commande. Pour obtenir une opration qui s'excute indpendamment pour chaque ligne physique, il faut utiliser des dclencheurs. On trouvera plus d'informations sur le systme des rgles dans Chapitre 37, Systme de rgles.
l'heure actuelle, les rgles ON SELECT doivent tre des rgles INSTEAD inconditionnelles. Chacune de leurs actions ne peut
tre constitue que d'une simple commande SELECT. Ainsi, une rgle ON SELECT a pour rsultat la transformation effective
d'une table en une vue dont le contenu visible est compos des lignes retournes par la commande SELECT de la rgle ; ce ne
sont pas les lignes stockes dans la table (s'il y en a) qui sont retournes. Le cration d'une vue l'aide de la commande
CREATE VIEW est toujours prfrable la cration d'une table relle associe une rgle ON SELECT.
On peut donner l'illusion d'une vue actualisable ( updatable view ) par la dfinition de rgles ON INSERT, ON UPDATE et
ON DELETE (ou tout sous-ensemble de celles-ci) pour remplacer les actions de mises jour de la vue par des mises jours des
tables adquates. Si vous voulez supporter INSERT RETURNING, alors assurez-vous de placer une clause RETURNING adquate chacune de ces rgles. Autrement, une vue actualisable peut tre implmente en utilisant des triggers INSTEAD OF
(voir CREATE TRIGGER(7)).
Il y a quelques chausse-trappes viter lors de l'utilisation de rgles conditionnelles pour la mise jour de vues : chaque action
autorise sur la vue doit correspondre une rgle INSTEAD inconditionnelle. Si la rgle est conditionnelle ou n'est pas une rgle
INSTEAD, alors le systme rejette toute tentative de mise jour, ceci afin d'viter toute action sur la table virtuelle de la vue.
Pour grer tous les cas utiles l'aide de rgles conditionnelles, il convient d'ajouter une rgle inconditionnelle DO INSTEAD
NOTHING afin de prciser au systme qu'il ne recevra jamais de demande de mise jour d'une table virtuelle. La clause INSTEAD des rgles conditionnelles peut alors tre supprime ;dans les cas o ces rgles s'appliquent, l'action INSTEAD NOTHING est utilise. (Nanmoins, cette mthode ne fonctionne pas actuellement avec les requtes RETURNING.)

Paramtres
nom
Le nom de la rgle crer. Elle doit tre distincte du nom de toute autre rgle sur la mme table. Les rgles multiples sur la
mme table et le mme type d'vnement sont appliques dans l'ordre alphabtique des noms.
vnement
SELECT, INSERT, UPDATE ou DELETE.
table
Le nom (ventuellement qualifi du nom du schma) de la table ou de la vue sur laquelle s'applique la rgle.
condition
Toute expression SQL conditionnelle (renvoyant un type boolean). L'expression de la condition ne peut pas faire rfrence
une table autre que NEW ou OLD ni contenir de fonction d'agrgat.
INSTEAD
Les commandes sont excutes la place de la commande originale.
ALSO
Les commandes sont excutes en plus de la commande originale.
975

CREATE RULE

En l'absence de ALSO et de INSTEAD, ALSO est utilis par dfaut.


commande
Commande(s) ralisant l'action de la rgle. Les commandes valides sont SELECT, INSERT, UPDATE, DELETE ou NOTIFY.
l'intrieur d'une condition ou d'une commande, les noms des tables spciales NEW et OLD peuvent tre utiliss pour faire
rfrence aux valeurs de la table rfrence. NEW peut tre utilis dans les rgles ON INSERT et ON UPDATE pour faire rfrence la nouvelle ligne lors d'une insertion ou la nouvelle valeur de la ligne lors d'une mise jour. OLD est utilis dans les
rgles ON UPDATE et ON DELETE pour rfrencer la ligne existant avant modification ou suppression.

Notes
Vous devez tre le propritaire de la table crer ou sur laquelle vous ajoutez des rgles.
Dans une rgle pour l'action INSERT, UPDATE ou DELETE sur une vue, vous pouvez ajouter une clause RETURNING qui met
les colonnes de la vue. Cette clause sera utilise pour calculer les sorties si la rgle est dclenche respectivement par une commande INSERT RETURNING, UPDATE RETURNINGou DELETE RETURNING. Quand la rgle est dclenche par une
commande sans clause RETURNING, la clause RETURNING de la rgle est ignore. L'implmentation actuelle autorise seulement
des rgles INSTEAD sans condition pour contenir RETURNING ; de plus, il peut y avoir au plus une clause RETURNING parmi
toutes les rgles pour le mme vnement. (Ceci nous assure qu'il y a seulement une clause RETURNING candidate utilise pour
calculer les rsultats.) Les requtes RETURNING sur la vue seront rejetes s'il n'existe pas de clause RETURNING dans une des
rgles disponibles.
Une attention particulire doit tre porte aux rgles circulaires. Ainsi dans l'exemple suivant, bien que chacune des deux dfinitions de rgles soit accepte par PostgreSQL, la commande SELECT produira une erreur cause de l'expansion rcursive de la
rgle :
CREATE RULE "_RETURN" AS
ON SELECT TO t1
DO INSTEAD
SELECT * FROM t2;
CREATE RULE "_RETURN" AS
ON SELECT TO t2
DO INSTEAD
SELECT * FROM t1;
SELECT * FROM t1;
Actuellement, si l'action d'une rgle contient une commande NOTIFY, cette commande est excute sans condition, c'est--dire
que NOTIFY est dclench mme si la rgle ne s'applique aucune ligne. Par exemple, dans :
CREATE RULE notify_me AS ON UPDATE TO matable DO ALSO NOTIFY matable;
UPDATE matable SET name = 'foo' WHERE id = 42;
un vnement NOTIFY est lanc durant un UPDATE, qu'il y ait ou non des lignes satisfaisant la condition id = 42. Cette restriction pourrait tre corrige dans les prochaines versions.

Compatibilit
CREATE RULE est une extension PostgreSQL, tout comme l'est le systme complet de rcriture de requtes.

976

Nom
CREATE SCHEMA Dfinir un nouveau schma

Synopsis
CREATE SCHEMA nom_schma [ AUTHORIZATION nom_utilisateur ] [ lment_schma [ ... ] ]
CREATE SCHEMA AUTHORIZATION nom_utilisateur [ lment_schma [ ... ] ]

Description
CREATE SCHEMA cre un nouveau schma dans la base de donnes. Le nom du schma doit tre unique au sein de la base
de donnes.
Un schma est essentiellement un espace de noms : il contient des objets nomms (tables, types de donnes, fonctions et oprateurs) dont les noms peuvent tre identiques ceux d'objets d'autres schmas. Les objets nomms sont accessibles en prfixant
leur nom de celui du schma (on dit alors que le nom est qualifi du nom du schma), ou par la configuration d'un chemin de
recherche incluant le(s) schma(s) dsir(s). Une commande CREATE qui spcifie un objet non qualifi cre l'objet dans le
schma courant (le premier dans le chemin de recherche, obtenu par la fonction current_schema).
CREATE SCHEMA peut ventuellement inclure des sous-commandes de cration d'objets dans le nouveau schma. Les souscommandes sont traites la faon de commandes spares lances aprs la cration du schma. La diffrence rside dans
l'utilisation de la clause AUTHORIZATION. Dans ce cas, l'utilisateur est propritaire de tous les objets crs.

Paramtres
nom_schma
Le nom du schma crer. S'il est oubli, le paramtre nomutilisateur est utilis comme nom de schma. Le nom ne
peut pas dbuter par pg_, ces noms tant rservs aux schmas du systme.
nom_utilisateur
Le nom de l'utilisateur qui appartient le schma. Par dfaut, il s'agit de l'utilisateur qui excute la commande. Pour crer
un schma dont le propritaire est un autre rle, vous devez tre un membre direct ou indirect de ce rle, ou tre un superutilisateur.
lment_schma
Une instruction SQL qui dfinit un objet crer dans le schma. ce jour, seules CREATE TABLE, CREATE VIEW,
CREATE SEQUENCE, CREATE TRIGGER et GRANT peuvent tre utilises dans la commande CREATE SCHEMA. Les autres types d'objets sont crs dans des commandes spares aprs la cration du schma.

Notes
Pour crer un schma, l'utilisateur doit avoir le droit CREATE sur la base de donnes. (Les superutilisateurs contournent cette
vrification.)

Exemples
Crer un schma :
CREATE SCHEMA mon_schema;
Crer un schma pour l'utilisateur joe, schma nomm joe :
CREATE SCHEMA AUTHORIZATION joe;
Crer un schma et lui ajouter une table et une vue :
CREATE SCHEMA hollywood
CREATE TABLE films (titre text, sortie date, recompenses text[])
CREATE VIEW gagnants AS
SELECT titre, sortie FROM films WHERE recompenses IS NOT NULL;
Les sous-commandes ne sont pas termines par un point-virgule.
La mme chose, autre criture :
977

CREATE SCHEMA

CREATE SCHEMA hollywood;


CREATE TABLE hollywood.films (titre text, sortie date, recompenses text[]);
CREATE VIEW hollywood.gagnants AS
SELECT titre, sortie FROM hollywood.films WHERE recompenses IS NOT NULL;

Compatibilit
Le standard SQL autorise une clause DEFAULT CHARACTER SET dans CREATE SCHEMA, et des types de sous-commandes
en plus grand nombre que ceux supports actuellement par PostgreSQL.
Le standard SQL n'impose pas d'ordre d'apparition des sous-commandes dans CREATE SCHEMA. L'implantation actuelle de
PostgreSQL ne gre pas tous les cas de rfrences futures dans les sous-commandes. Il peut s'avrer ncessaire de rordonner
les sous-commandes pour viter ces rfrences.
Dans le standard SQL, le propritaire d'un schma est galement propritaire de tous les objets qui s'y trouvent. PostgreSQL
permet un schma de contenir des objets qui n'appartiennent pas son propritaire. Cela n'est possible que si le propritaire du
schma transmet le privilge CREATE sur son schma ou si un superutilisateur choisir d'y crer des objets.

Voir aussi
ALTER SCHEMA(7), DROP SCHEMA(7)

978

Nom
CREATE SEQUENCE Dfinir un nouveau gnrateur de squence

Synopsis
CREATE [ TEMPORARY | TEMP ] SEQUENCE nom [ INCREMENT [ BY ] incrment ]
[ MINVALUE valeurmin | NO MINVALUE ]
[ MAXVALUE valeurmax | NO MAXVALUE ]
[ START [ WITH ] dbut ]
[ CACHE cache ]
[ [ NO ] CYCLE ]
[ OWNED BY { table.colonne | NONE } ]

Description
CREATE SEQUENCE cre un nouveau gnrateur de squence de nombres. Cela implique la cration et l'initialisation d'une
nouvelle table une seule ligne nomme nom. Le gnrateur appartient l'utilisateur qui excute la commande.
Si un nom de schma est donn, la squence est cre dans le schma spcifi. Sinon, elle est cre dans le schma courant. Les
squences temporaires existent dans un schma spcial, il n'est donc pas utile de prciser un nom de schma lors de la cration
d'une squence temporaire. Le nom de la squence doit tre distinct du nom de toute autre squence, table, index, vue ou table
distante du schma.
Aprs la cration d'une squence, les fonctions nextval, currval et setval sont utilises pour agir sur la squence. Ces
fonctions sont documentes dans Section 9.15, Fonctions de manipulation de squences .
Bien qu'il ne soit pas possible de mettre jour une squence en accdant directement la table, une requte telle que :
SELECT * FROM nom;
peut tre utilise pour examiner les paramtres et l'tat courant d'une squence. En particulier, le champ last_value affiche
la dernire valeur alloue par une session. (Cette valeur peut tre rendue obsolte l'affichage par des appels effectifs de nextval dans des sessions concurrentes.)

Paramtres
TEMPORARY ou TEMP
Si ce paramtre est spcifi, l'objet squence n'est cr que pour la session en cours et est automatiquement supprim lors de
la sortie de session. Les squences permanentes portant le mme nom ne sont pas visibles (dans cette session) tant que la squence temporaire existe, sauf tre rfrences par les noms qualifis du schma.
nom
Le nom (ventuellement qualifi du nom du schma) de la squence crer.
incrment
La clause optionnelle INCREMENT BY incrment prcise la valeur ajouter la valeur courante de la squence pour
crer une nouvelle valeur. Une valeur positive cre une squence ascendante, une valeur ngative une squence descendante. 1 est la valeur par dfaut.
valeurmin, NO MINVALUE
La clause optionnelle MINVALUE valeurmin dtermine la valeur minimale de la squence. Si cette clause n'est pas
fournie ou si NO MINVALUE est spcifi, alors les valeurs par dfaut sont utilises. Ces valeurs sont, respectivement, 1 et 263-1 pour les squences ascendantes et descendantes.
valeurmax, NO MAXVALUE
La clause optionnelle MAXVALUE valeurmax dtermine la valeur maximale de la squence. Si cette clause n'est pas
fournie ou si NO MAXVALUE est specifi, alors les valeurs par dfaut sont utilises. Ces valeurs sont, respectivement, 263-1
et -1 pour les squences ascendantes et descendantes.
dbut
La clause optionnelle START WITH dbut permet la squence de dmarrer n'importe o. La valeur de dbut par dfaut est valeurmin pour les squences ascendantes et valeurmax pour les squences descendantes.
cache
La clause optionnelle CACHE cache spcifie le nombre de numros de squence prallouer et stocker en mmoire pour
un accs plus rapide. 1 est la valeur minimale (une seule valeur est engendre la fois, soit pas de cache) et la valeur par d979

CREATE SEQUENCE

faut.
CYCLE, NO CYCLE
L'option CYCLE autorise la squence recommencer au dbut lorsque valeurmax ou valeurmin sont atteintes, respectivement, par une squence ascendante ou descendante. Si la limite est atteinte, le prochain nombre engendr est respectivement valeurmin ou valeurmax.
Si NO CYCLE est spcifi, tout appel nextval alors que la squence a atteint la valeur maximale (dans le cas d'une squence ascendante) ou la valeur minimale (dans l'autre cas) retourne une erreur. En l'absence de prcision, NO CYCLE est la
valeur par dfaut.
OWNED BY table.colonne, OWNED BY NONE
L'option OWNED BY permet d'associer la squence une colonne de table spcifique. De cette faon, la squence sera automatiquement supprime si la colonne (ou la table entire) est supprime. La table indique doit avoir le mme propritaire et
tre dans le mme schma que la squence. OWNED BY NONE, valeur par dfaut, indique qu'il n'y a pas d'association.

Notes
DROP SEQUENCE est utilis pour supprimer une squence.
Les squences sont fondes sur l'arithmtique bigint, leur chelle ne peut donc pas excder l'chelle d'un entier sur huit octets
(-9223372036854775808 9223372036854775807). Sur certaines vieilles plateformes, il peut ne pas y avoir de support compilateur pour les entiers cods sur huit octets. Dans ce cas les squences utilisent l'arithmtique des entiers traditionnels (type integer)
(de -2147483648 +2147483647).
Des rsultats inattendus peuvent tre obtenus dans le cas d'un paramtrage de cache suprieur un pour une squence utilise
concurrentiellement par plusieurs sessions. Chaque session alloue et cache des valeurs de squences successives lors d'un accs
la squence et augmente en consquence la valeur de last_value. Les cache-1 appels suivants de nextval au cours de la
session session retourne simplement les valeurs pralloues sans toucher la squence. De ce fait, tout nombre allou mais non
utilis au cours d'une session est perdu la fin de la session, crant ainsi des trous dans la squence.
De plus, bien qu'il soit garanti que des sessions diffrentes engendrent des valeurs de squence distinctes, si l'on considre toutes
les sessions, les valeurs peuvent ne pas tre engendres squentiellement. Par exemple, avec un paramtrage du cache 10, la
session A peut rserver les valeurs 1..10 et rcuprer nextval=1 ; la session B peut alors rserver les valeurs 11..20 et rcuprer
nextval=11 avant que la session A n'ait engendr nextval=2. De ce fait, un paramtrage de cache un permet d'assumer
que les valeurs retournes par nextval sont engendres squentiellement ; avec un cache suprieur, on ne peut qu'assumer que
les valeurs retournes par nextval sont tous distinctes, non qu'elles sont rellement engendres squentiellement. De plus,
last_value reflte la dernire valeur rserve pour toutes les sessions, que nextval ait ou non retourn cette valeur.
D'autre part, setval excut sur une telle squence n'est pas pris en compte par les autres sessions avant qu'elle n'aient utilis
toutes les valeurs pralloues et caches.

Exemples
Crer une squence ascendante appele serie, dmarrant 101 :
CREATE SEQUENCE serie START 101;
Slectionner le prochain numro de cette squence :
SELECT nextval('serie');
nextval
--------101
Rcuprer le prochain numro d'une squence :
SELECT nextval('serial');
nextval
--------102
Utiliser cette squence dans une commande INSERT :
INSERT INTO distributors VALUES (nextval('serie'), 'nothing');
980

CREATE SEQUENCE

Mettre jour la valeur de la squence aprs un COPY FROM :


BEGIN;
COPY distributeurs FROM 'fichier_entrees';
SELECT setval('serie', max(id)) FROM distributeurs;
END;

Compatibilit
CREATE SEQUENCE est conforme au standard SQL, exception faites des remarques suivantes :

L'expression standard AS <type donne> n'est pas supporte.

Obtenir la prochaine valeur se fait en utilisant la fonction nextval() au lieu de l'expression standard NEXT VALUE FOR.

La clause OWNED BY est une extension PostgreSQL.

Voir aussi
ALTER SEQUENCE(7), DROP SEQUENCE(7)

981

Nom
CREATE SERVER Dfinir un nouveau serveur distant

Synopsis
CREATE SERVER nom_serveur [ TYPE 'type_serveur' ] [ VERSION 'version_serveur' ]
FOREIGN DATA WRAPPER nom_fdw
[ OPTIONS ( option 'valeur' [, ... ] ) ]

Description
CREATE SERVER dfinit un nouveau serveur de donnes distantes. L'utilisateur qui dfinit le serveur devient son propritaire.
Un serveur distant englobe typiquement des informations de connexion qu'un wrapper de donnes distantes utilise pour accder
une ressource externe de donnes. Des informations de connexions supplmentaires spcifiques l'utilisateur pourraient tre
fournies par l'intermdiaire des correspondances d'utilisateur.
Le nom du serveur doit tre unique dans la base de donnes.
La cration d'un serveur ncessite d'avoir le droit USAGE sur le wrapper de donnes distant qui est utilis.

Paramtres
nom_serveur
Nom du serveur de donnes distant qui sera cr.
type_serveur
Type de serveur (optionnel).
version_serveur
Version du serveur (optionnel).
nom_fdw
Nom du wrapper de donnes distantes qui gre le serveur.
OPTIONS ( option 'valeur' [, ... ] )
Cette clause spcifie les options pour le serveur. Typiquement, les options dfinissent les dtails de connexion au serveur,
mais les noms et valeurs relles dpendent du wrapper de donnes distantes du serveur.

Notes
Lors de l'utilisation du module dblink (voir dblink), le nom du serveur distant peut tre utilis comme argument de la fonction
dblink_connect(3) pour indiquer les paramtres de connexion. Voir aussi ici pour plus d'exemples. Il est ncessaire de disposer
du droit USAGE sur le serveur distant pour tre capable de l'utiliser de cette faon.

Exemples
Crer un serveur truc qui utilise le wrapper de donnes distantes inclus default :
CREATE SERVER truc FOREIGN DATA WRAPPER "default";
Crer un serveur monserveur qui utilise le wrapper de donnes distantes pgsql :
CREATE SERVER monserveur FOREIGN DATA WRAPPER pgsql OPTIONS (host 'truc', dbname
'trucdb', port '5432');

Compatibilit
CREATE SERVER est conforme ISO/IEC 9075-9 (SQL/MED).

982

CREATE SERVER

Voir aussi
ALTER SERVER(7), DROP SERVER(7), CREATE FOREIGN DATA WRAPPER(7), CREATE USER MAPPING(7)

983

Nom
CREATE TABLE Dfinir une nouvelle table

Synopsis
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ]
nom_table ( [
{ nom_colonne type_donnees [ COLLATE collation ] [ contrainte_colonne [ ... ] ]
| contrainte_table
| LIKE table_parent [ option_like ... ] }
[, ... ]
] )
[ INHERITS ( table_parent [, ... ] ) ]
[ WITH ( parametre_stockage [= valeur] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace ]
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE nom_table
OF nom_type [ (
{ nom_colonne WITH OPTIONS [ contrainte_colonne [ ... ] ]
| contrainte_table }
[, ... ]
) ]
[ WITH ( parametre_stockage [= valeur] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace ]
o contrainte_colonne
peut tre :
[ CONSTRAINT nom_contrainte ]
{ NOT NULL | NULL |
CHECK ( expression ) |
DEFAULT expression_par_dfaut |
UNIQUE parametres_index |
PRIMARY KEY parametres_index |
EXCLUDE [ USING methode_index ] ( lment_exclude WITH oprateur [, ... ] )
paramtres_index [ WHERE ( prdicat ) ] |
REFERENCES table_reference [ ( colonne_reference ) ] [ MATCH FULL
| MATCH PARTIAL | MATCH SIMPLE ]
[ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
et option_like peut
valoir :
{ INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS |
ALL }
et contrainte_table :
[ CONSTRAINT nom_contrainte ]
{ UNIQUE ( nom_colonne [, ... ] ) parametres_index |
PRIMARY KEY ( nom_colonne [, ... ] ) parametres_index |
CHECK ( expression ) |
FOREIGN KEY ( nom_colonne [, ...
] ) REFERENCES table_reference [ (
colonne_reference [, ... ] ) ]
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE
action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
Les paramtres_index dans les
contraintes UNIQUE, PRIMARY KEY et
EXCLUDE sont :
[ WITH ( paramtre_stockage [= valeur] [, ... ] ) ]
984

CREATE TABLE

[ USING INDEX TABLESPACE tablespace ]


exclude_element dans une
contrainte EXCLUDE peut valoir :
{ column | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]

Description
CREATE TABLE cre une nouvelle table initialement vide dans la base de donnes courante. La table appartient l'utilisateur
qui excute cette commande.
Si un nom de schma est donn (par exemple, CREATE TABLE monschema.matable ...), alors la table est cre dans le
schma spcifi. Dans le cas contraire, elle est cre dans le schma courant. Les tables temporaires existent dans un schma spcial, il n'est donc pas ncessaire de fournir un nom de schma lors de la cration d'une table temporaire. Le nom de la table doit
tre distinct du nom des autres tables, squences, index, vues ou tables distantes dans le mme schma.
CREATE TABLE cre aussi automatiquement un type de donnes qui reprsente le type compos correspondant une ligne de
la table. Ainsi, les tables doivent avoir un nom distinct de tout type de donnes du mme schma.
Les clauses de contrainte optionnelles prcisent les contraintes (ou tests) que les nouvelles lignes ou les lignes mises jour doivent
satisfaire pour qu'une opration d'insertion ou de mise jour russisse. Une contrainte est un objet SQL qui aide dfinir
l'ensemble des valeurs valides de diffrentes faons.
Il existe deux faons de dfinir des contraintes : celles de table et celles de colonnes. Une contrainte de colonne fait partie de la dfinition de la colonne. Une dfinition de contrainte de tables n'est pas lie une colonne particulire et peut englober plusieurs colonnes. Chaque contrainte de colonne peut tre crite comme une contrainte de table ; une contrainte de colonne n'est qu'un outil
de notation utilis lorsque la contrainte n'affecte qu'une colonne.

Paramtres
TEMPORARY ou TEMP
La table est temporaire. Les tables temporaires sont automatiquement supprimes la fin d'une session ou, optionnellement,
la fin de la transaction en cours (voir ON COMMIT ci-dessous). Les tables permanentes qui portent le mme nom ne sont
pas visibles dans la session courante tant que la table temporaire existe sauf s'il y est fait rfrence par leur nom qualifi du
schma. Tous les index crs sur une table temporaire sont automatiquement temporaires.
Le dmon autovacuum ne peut pas accder et, du coup, ne peut pas excuter un VACUUM ou un ANALYZE sur les tables
temporaires. Pour cette raison, les oprations VACUUM et ANALYZE doivent tre traites via des commandes SQL de session. Par exemple, si une table temporaire doit tre utilise dans des requtes complexes, il est raisonnable d'excuter ANALYZE sur la table temporaire aprs qu'elle ait t peuple.
On peut ventuellement crire GLOBAL ou LOCAL avant TEMPORARY ou TEMP. Cela ne fait pas de diffrence dans PostgreSQL (cf. la section intitule Compatibilit ).
UNLOGGED
Si spcifi, la table est cre en tant que table non trace. Les donnes crites dans ce type de table ne sont pas crites dans les
journaux de transactions (voir Chapitre 29, Fiabilit et journaux de transaction), ce qui les rend considrablement plus rapides
que les tables ordinaires. Nanmoins, elles ne sont pas sres en cas d'arrt brutal : une table non trace est automatiquement
vide aprs un arrt brutal. Le contenu d'une table non trace n'est pas rpliqu vers les serveurs en attente. Tout index cr
sur une table non trace est aussi automatiquement non trac ; nanmoins, les index GiST non tracs ne sont pas encore supports. Ils ne peuvent donc pas tre ajouts une table non trace.
IF NOT EXISTS
N'affiche pas d'erreur si une relation de mme nom existe dj. Un message de niveau notice est retourn dans ce cas. Notez
qu'il n'existe aucune garantie que la relation existante ressemble celle qui devait tre cre..
nom_table
Le nom (ventuellement qualifi du nom du schma) de la table crer.
OF nom_type
Cre une table type, qui prend sa structure partir du type composite spcifi (son nom peut tre qualifi du schma). Une
table type est lie son type ; par exemple, la table sera supprime si le type est supprim (avec DROP TYPE ... CASCADE).
Quand une table type est cre, les types de donnes des colonnes sont dtermins par le type composite sous-jacent et ne
sont pas indiqus par la commande CREATE TABLE. Mais la commande CREATE TABLE peut ajouter des valeurs par dfaut et des contraintes la table. Elle peut aussi indiquer des paramtres de stockage.
985

CREATE TABLE

nom_colonne
Le nom d'une colonne de la nouvelle table.
type_donnes
Le type de donnes de la colonne. Cela peut inclure des spcificateurs de tableaux. Pour plus d'informations sur les types de
donnes supports par PostgreSQL, on se rfrera Chapitre 8, Types de donnes.
COLLATE collation
La clause COLLATE affecte un collationnement une colonne (qui doit tre d'un type de donnes collationnable). Sans information, le collationnement par dfaut du type de donnes de la colonne est utilis.
INHERITS ( table_parent [, ... ])
La clause optionnelle INHERITS indique une liste de tables dont les colonnes sont automatiquement hrites par la nouvelle
table.
L'utilisation d'INHERITS cre une relation persistante entre la nouvelle table enfant et sa table parent. Les modifications de
schma du(des) parent(s) se propagent normalement aux enfants et, par dfaut, les donnes de la table enfant sont incluses
dans les parcours de(s) parent(s).
Si un mme nom de colonne existe dans plusieurs tables parentes, une erreur est rapporte, moins que les types de donnes
des colonnes ne correspondent dans toutes les tables parentes. S'il n'y a pas de conflit, alors les colonnes dupliques sont assembles pour former une seule colonne dans la nouvelle table. Si la liste des noms de colonnes de la nouvelle table contient
un nom de colonne hrit, le type de donnes doit correspondre celui des colonnes hrites et les dfinitions des colonnes
sont fusionnes. Si la nouvelle table spcifie explicitement une valeur par dfaut pour la colonne, cette valeur surcharge toute
valeur par dfaut hrite. Dans le cas contraire, les parents qui spcifient une valeur par dfaut doivent tous spcifier la mme,
sans quoi une erreur est rapporte.
Les contraintes CHECK sont fusionnes, dans les grandes lignes, de la mme faon que les colonnes : si des tables parentes
multiples et/ou la nouvelle dfinition de table contient des contraintes CHECK de mme nom, ces contraintes doivent toutes
avoir la mme expression de vrification, ou une erreur sera retourne. Les contraintes qui ont le mme nom et la mme expression seront fusionnes en une seule. Notez qu'une contrainte CHECK non nomme dans la nouvelle table ne sera jamais
fusionne puisqu'un nom unique lui sera toujours affect.
Les paramtres STORAGE de la colonne sont aussi copis des tables parents.
LIKE table_parent [ option_like ... ]
La clause LIKE spcifie une table partir de laquelle la nouvelle table copie automatiquement tous les noms de colonnes,
leur types de donnes et les contraintes non NULL.
Contrairement INHERITS, la nouvelle table et la table originale sont compltement dcouples la fin de la cration. Les
modifications sur la table originale ne sont pas appliques la nouvelle table et les donnes de la nouvelle table sont pas
prises en compte lors du parcours de l'ancienne table.
Les expressions par dfaut des dfinitions de colonnes ne seront copies que si INCLUDING DEFAULTS est spcifi. Le
comportement par dfaut les exclut, ce qui conduit des valeurs par dfaut NULL pour les colonnes copies de la nouvelle
table.
Les contraintes NOT NULL sont toujours copies sur la nouvelle table. Les contraintes CHECK seront seulement copies si
INCLUDING CONSTRAINTS est indiqu ; les autres types de contraintes ne sont jamais copies. De plus, aucune distinction
n'est faite entre les contraintes de colonnes et les contraintes de tables -- quand les contraintes sont demandes, toutes les
contraintes de vrification sont copies.
Tout index sur la table originale ne sera pas cr sur la nouvelle table sauf si la clause INCLUDING INDEXES est prcise.
Des paramtres STORAGE pour les dfinitions de la colonne copie seront seulement copis si INCLUDING STORAGE est
spcifi. Le comportement par dfaut est d'exclure des paramtres STORAGE, rsultant dans les colonnes copies dans la nouvelle table ayant des paramtres par dfaut spcifiques par type. Pour plus d'informations sur STORAGE, voir Section 55.2,
TOAST .
Les commentaires pour les colonnes, contraintes et index copis seront seulement copis si INCLUDING COMMENTS est
spcifi. Le comportement par dfaut est d'exclure les commentaires, ce qui rsulte dans des colonnes et contraintes copies
dans la nouvelle table mais sans commentaire.
INCLUDING ALL est une forme abrge de INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING
INDEXES INCLUDING STORAGE INCLUDING COMMENTS.
Contrairement INHERITS, les colonnes et les contraintes copies par LIKE ne sont pas assembles avec des colonnes et
des contraintes nommes de faon similaire. Si le mme nom est indiqu explicitement ou dans une autre clause LIKE, une
erreur est rapporte.
986

CREATE TABLE

CONSTRAINT nom_contrainte
Le nom optionnel d'une contrainte de colonne ou de table. Si la contrainte est viole, le nom de la contrainte est prsente dans
les messages d'erreur. Donc les noms de contraintes comme col doit tre positive peut tre utiliss pour communiquer des informations utiles aux applications clients. (Des doubles guillemets sont ncessaires pour indiquer les noms des
contraintes qui contiennent des espaces.) Si un nom de contrainte n'est pas donn, le systme en cre un.
NOT NULL
Interdiction des valeurs NULL dans la colonne.
NULL
Les valeurs NULL sont autorises pour la colonne. Comportement par dfaut.
Cette clause n'est fournie que pour des raisons de compatibilit avec les bases de donnes SQL non standard. Son utilisation
n'est pas encourage dans les nouvelles applications.
CHECK ( expression )
La clause CHECK spcifie une expression de rsultat boolen que les nouvelles lignes ou celles mises jour doivent satisfaire
pour qu'une opration d'insertion ou de mise jour russisse. Les expressions de rsultat TRUE ou UNKNOWN russissent.
Si une des lignes de l'opration d'insertion ou de mise jour produit un rsultat FALSE, une exception est leve et la base de
donnes n'est pas modifie. Une contrainte de vrification sur une colonne ne fait rfrence qu' la valeur de la colonne tandis
qu'une contrainte sur la table fait rfrence plusieurs colonnes.
Actuellement, les expressions CHECK ne peuvent ni contenir des sous-requtes ni faire rfrence des variables autres que les
colonnes de la ligne courante.
DEFAULT expression_par_dfaut
La clause DEFAULT, apparaissant dans la dfinition d'une colonne, permet de lui affecter une valeur par dfaut. La valeur est
une expression libre de variable (les sous-requtes et rfrences croises aux autres colonnes de la table courante ne sont pas
autorises). Le type de donnes de l'expression par dfaut doit correspondre au type de donnes de la colonne.
L'expression par dfaut est utilise dans les oprations d'insertion qui ne spcifient pas de valeur pour la colonne. S'il n'y a pas
de valeur par dfaut pour une colonne, elle est NULL.
UNIQUE (contrainte de colonne), UNIQUE ( nom_colonne [, ... ] ) (contrainte de table)
La contrainte UNIQUE indique qu'un groupe d'une ou plusieurs colonnes d'une table ne peut contenir que des valeurs uniques.
Le comportement de la contrainte de table unique est le mme que celui des contraintes de colonnes avec la capacit supplmentaire de traiter plusieurs colonnes.
Pour une contrainte unique, les valeurs NULL ne sont pas considres comme gales.
Chaque contrainte unique de table doit nommer un ensemble de colonnes qui est diffrent de l'ensemble de colonnes nommes par toute autre contrainte unique ou de cl primaire dfinie pour la table. (Sinon elle ne ferait que lister la mme
contrainte deux fois.)
PRIMARY KEY (contrainte de colonne), PRIMARY KEY ( nom_colonne [, ... ] ) (contrainte de table)
La contrainte de cl primaire spcifie qu'une ou plusieurs colonnes d'une table ne peut contenir que des valeurs uniques (non
dupliques) et non NULL. Techniquement, une contrainte PRIMARY KEY est tout simplement une combinaison d'une
contrainte UNIQUE et d'une contrainte NOT NULL, mais l'identification d'un ensemble de colonnes en tant que cl primaire
fournit aussi une mtainformation sur le schma car la cl primaire indique que les autres tables peuvent se baser sur cet ensemble de colonnes comme d'un identifiant unique des lignes.
Seule une cl primaire peut tre spcifie pour une table, soit en tant que contrainte de colonne ou que contrainte de table.
La contrainte de cl primaire devrait nommer un ensemble de colonnes qui est diffrent des autres ensembles de colonnes
nommes par une contrainte unique dfinie pour la mme table.
EXCLUDE [ USING mthode_index ] ( lment_exclusion WITH oprateur [, ... ] ) paramtres_index [ WHERE ( prdicat ) ]
La clause EXCLUDE dfinit une contrainte d'exclusion qui garantit que si deux lignes sont compares sur la ou les colonnes
spcifies ou des expressions utilisant le ou les oprateurs spcifis, seulement certaines de ces comparaisons, mais pas
toutes, renverront TRUE. Si tous les oprateurs spcifis testent une galit, ceci est quivalent une contrainte UNIQUE bien
qu'une contrainte unique ordinaire sera plus rapide. Nanmoins, ces contraintes d'exclusion peuvent spcifier des contraintes
qui sont plus gnrales qu'une simple galit. Par exemple, vous pouvez spcifier qu'il n'y a pas deux lignes dans la table
contenant des cercles de surcharge (voir Section 8.8, Types gomtriques ) en utilisant l'oprateur &&.
Des contraintes d'exclusion sont implantes en utilisant un index, donc chaque oprateur prcis doit tre associ avec une
classe d'oprateurs approprie (voir Section 11.9, Classes et familles d'oprateurs ) pour la mthode d'accs par index,
nomme mthode_index. Les oprateurs doivent tre commutatifs. Chaque lment_exclusion peut spcifier en option une classe d'oprateur et/ou des options de tri ; ils sont dcrits compltement sous CREATE INDEX(7).
987

CREATE TABLE

La mthode d'accs doit supporter amgettuple (voir Chapitre 52, Dfinition de l'interface des mthodes d'accs aux
index) ; ds prsent, cela signifie que GIN ne peut pas tre utilis. Bien que cela soit autoris, il existe peu de raison pour
utiliser des index B-tree ou hash avec une contrainte d'exclusion parce que cela ne fait rien de mieux que ce que peut faire une
contrainte unique ordinaire. Donc, en pratique, la mthode d'accs sera toujours GiST.
Le prdicat vous permet de spcifier une contrainte d'exclusion sur un sous-ensemble de la table ; en interne, un index
partiel est cr. Notez que ces parenthses sont requis autour du prdicat.
REFERENCES table_reference [ ( colonne_reference ) ] [ MATCH matchtype ] [ ON DELETE
action ] [ ON UPDATE action ] (contrainte de colonne), FOREIGN KEY ( colonne [, ... ] ) REFERENCES table_reference [ ( colonne_reference [, ... ] ) ] [ MATCH matchtype ] [ ON DELETE action ] [ ON UPDATE action ] (contrainte de colonne)
Ces clauses spcifient une contrainte de cl trangre. Cela signifie qu'un groupe de colonnes de la nouvelle table ne peut
contenir que des valeurs correspondant celles des colonnes de rfrence de la table de rfrence. Si colonne_reference est omis, la cl primaire de la table_reference est utilise. Les colonnes rfrences doivent tre
celles d'une contrainte d'unicit ou de cl primaire, non dferrable, dans la table rfrence. Les contraintes de type cl trangre ne peuvent pas tre dfinies entre des tables temporaires et des tables permanentes.
Une valeur insre dans les colonnes de la nouvelle table est compare aux valeurs des colonnes de rfrence dans la table de
rfrence l'aide du type de concordance fourni. Il existe trois types de correspondance : MATCH FULL (NDT : correspondance totale), MATCH PARTIAL (NDT : correspondance partielle) et MATCH SIMPLE (NDT : correspondance simple), qui
est aussi la valeur par dfaut. MATCH FULL n'autorise une colonne d'une cl trangre composite tre NULL que si
l'ensemble des colonnes de la cl trangre sont NULL. MATCH SIMPLE autorise une colonne de cl trangre tre NULL
mme si les autres parties de la cl trangre ne sont pas nulles. MATCH PARTIAL n'est pas encore implant.
Lorsque les donnes des colonnes rfrences sont modifies, des actions sont ralises sur les donnes de la table rfrenant. La clause ON DELETE spcifie l'action raliser lorsqu'une ligne rfrence de la table de rfrence est supprime.
De la mme faon, la clause ON UPDATE spcifie l'action raliser lorsqu'une colonne rfrence est mise jour. Si la ligne
est mise jour sans que la valeur de la colonne rfrence ne soit modifie, aucune action n'est ralise. Les actions rfrentielles autres que la vrification NO ACTION ne peuvent pas tre diffres mme si la contrainte est dclare retardable. Les
actions suivantes sont possibles pour chaque clause :
NO ACTION
Une erreur est produite pour indiquer que la suppression ou la mise jour entrane une violation de la contrainte de cl trangre. Si la contrainte est diffre, cette erreur est produite au moment de la vrification, si toutefois il existe encore des lignes
de rfrence. C'est le comportement par dfaut.
RESTRICT
Une erreur est produite pour indiquer que la suppression ou la mise jour entrane une violation de la contrainte de cl trangre. Ce comportement est identique NO ACTION, si ce n'est que la vrification n'est pas dcalable dans le temps.
CASCADE
La mise jour ou la suppression de la ligne de rfrence est propage l'ensemble des lignes qui la rfrencent, qui sont, respectivement, mises jour ou supprimes.
SET NULL
La valeur de la colonne qui rfrence est positionne NULL.
SET DEFAULT
La valeur de la colonne qui rfrence est positionne celle par dfaut.
Si les colonnes rfrences sont modifies frquemment, il est conseill d'ajouter un index sur la colonne de cl trangre de
faon acclrer les actions rfrentielles associes la colonne de cl trangre.
DEFERRABLE, NOT DEFERRABLE
Ces clauses contrlent la possibilit de diffrer la contrainte. Une contrainte qui n'est pas dcalable dans le temps est vrifie
immdiatement aprs chaque commande. La vrification des contraintes dcalables est repousse la fin de la transaction (
l'aide de la commande SET CONSTRAINTS(7)). NOT DEFERRABLE est la valeur par dfaut. Actuellement, seules les
contraintes UNIQUE, PRIMARY KEY, EXCLUDE et REFERENCES (cl trangre) acceptent cette clause. Les
contraintesNOT NULL et CHECK ne sont pas dferrables.
INITIALLY IMMEDIATE, INITIALLY DEFERRED
Si une contrainte est dcalable dans le temps, cette clause prcise le moment de la vrification. Si la contrainte est INITIALLY IMMEDIATE, elle est vrifie aprs chaque instruction. Si la contrainte est INITIALLY DEFERRED, elle n'est vrifie
qu' la fin de la transaction. Le moment de vrification de la contrainte peut tre modifi avec la commande SET
CONSTRAINTS(7).
WITH ( paramtre_stockage [= valeur] [, ... ] )
988

CREATE TABLE

Cette clause spcifie les paramtres de stockage optionnels pour une table ou un index ; voir la section intitule Paramtres
de stockage pour plus d'informations. La clause WITH peut aussi inclure pour une table OIDS=TRUE (ou simplement
OIDS) pour indiquer que les lignes de la nouvelle table doivent se voir affecter des OID (identifiants d'objets) ou
OIDS=FALSE pour indiquer que les lignes ne doivent pas avoir d'OID. Si OIDS n'est pas indiqu, la valeur par dfaut dpend du paramtre de configuration default_with_oids. (Si la nouvelle table hrite d'une table qui a des OID,
alorsOIDS=TRUE est forc mme si la commande prcise OIDS=FALSE.)
Si OIDS=FALSE est indiqu ou implicite, la nouvelle table ne stocke pas les OID et aucun OID n'est affect pour une ligne
insre dans cette table. Ceci est gnralement bien considr car cela rduit la consommation des OID et retarde du coup le
retour zro du compteur sur 32 bits. Une fois que le compteur est revenu zro, les OID ne sont plus considrs uniques ce
qui les rend beaucoup moins utiles. De plus, exclure les OID d'une table rduit l'espace requis pour stocker la table sur le
disque de quatre octets par ligne (la plupart des machines), amliorant lgrement les performances.
Pour supprimer les OID d'une table une fois qu'elle est cre, utilisez ALTER TABLE(7).
WITH OIDS, WITHOUT OIDS
Ce sont les syntaxes obsoltes mais quivalentes, respectivement de WITH (OIDS) et WITH (OIDS=FALSE). Si vous
souhaitez indiquer la fois l'option OIDS et les paramtres de stockage, vous devez utiliser la syntaxe WITH ( ... ) ;
voir ci-dessus.
ON COMMIT
Le comportement des tables temporaires la fin d'un bloc de transactions est contrl l'aide de la clause ON COMMIT. Les
trois options sont :
PRESERVE ROWS
Aucune action n'est entreprise la fin des transactions. Comportement par dfaut.
DELETE ROWS
Toutes les lignes de la table temporaire sont dtruites la fin de chaque bloc de transactions. En fait, un TRUNCATE(7) automatique est ralis chaque validation.
DROP
La table temporaire est supprime la fin du bloc de transactions.
TABLESPACE tablespace
tablespace est le nom du tablespace dans lequel est cre la nouvelle table. S'il n'est pas spcifi, default_tablespace est
consult, sauf si la table est temporaire auquel cas temp_tablespaces est utilis.
USING INDEX TABLESPACE tablespace
Les index associs une contrainte UNIQUE, PRIMARY KEY, ou EXCLUDE sont crs dans le tablespace nomm tablespace. S'il n'est pas prcis, default_tablespace est consult, sauf si la table est temporaire auquel cas temp_tablespaces est
utilis.

Paramtres de stockage
La clause WITH spcifie des paramtres de stockage pour les tables ainsi que pour les index associs avec une contrainte
UNIQUE, PRIMARY KEY, ou EXCLUDE. Les paramtres de stockage des index sont documents dans CREATE INDEX(7). Les
paramtres de stockage actuellement disponibles pour les tables sont lists ci-dessous. Pour chaque paramtre, sauf contre-indication, il y a un paramtre additionnel, de mme nom mais prfix par toast., qui peut tre utilis pour contrler le le comportement de la table TOAST (stockage supplmentaire), si elle existe (voir Section 55.2, TOAST pour plus d'informations sur
TOAST). La table TOAST hrite ses valeurs autovacuum de sa table parente s'il n'y a pas de paramtre
toast.autovacuum_* positionn.
fillfactor (integer)
Le facteur de remplissage d'une table est un pourcentage entre 10 et 100. 100 (paquet complet) est la valeur par dfaut. Quand
un facteur de remplissage plus petit est indiqu, les oprations INSERT remplissent les pages de table d'au maximum ce
pourcentage ; l'espace restant sur chaque page est rserv la mise jour des lignes sur cette page. Cela donne UPDATE
une chance de placer la copie d'une ligne mise jour sur la mme page que l'original, ce qui est plus efficace que de la placer
sur une page diffrente. Pour une table dont les entres ne sont jamais mises jour, la valeur par dfaut est le meilleur choix,
mais pour des tables mises jour frquemment, des facteurs de remplissage plus petits sont mieux appropris. Ce paramtre
n'est pas disponible pour la table TOAST.
autovacuum_enabled, toast.autovacuum_enabled (boolean)
Active ou dsactive le processus d'autovacuum sur une table particulire. Si true, le processus d'autovacuum dmarrera une
opration VACUUM sur une table particulire quand le nombre d'enregistrements mis jour ou supprims dpassera autovacuum_vacuum_threshold plus autovacuum_vacuum_scale_factor multipli par le nombre
d'enregistrements estims actifs dans la relation. De faon similaire, il dmarrera une opration ANALYZE quand le nombre
989

CREATE TABLE

d'enregistrements insrs, mis jour ou supprims dpassera autovacuum_analyze_threshold plus autovacuum_analyze_scale_factor multipli par le nombre d'enregistrements estims actifs dans la relation. Si false, la
table ne sera pas traite par autovacuum, sauf pour prvenir le bouclage des identifiants de transaction. Voir Section 23.1.4,
viter les cycles des identifiants de transactions pour plus d'information sur la prvention de ce bouclage. Notez que cette
variable hrite sa valeur du paramtre autovacuum.
autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer)
Nombre minimum d'enregistrements mis jour ou supprims avant de dmarrer une opration VACUUM sur une table particulire.
autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (float4)
Coefficient multiplicateur pour reltuples (nombre estim d'enregistrements d'une relation) ajouter autovacuum_vacuum_threshold.
autovacuum_analyze_threshold (integer)
Nombre minimum d'enregistrements insrs, mis jour ou supprims avant de dmarrer une opration ANALYZE sur une
table particulire.
autovacuum_analyze_scale_factor (float4)
Coefficient multiplicateur pour reltuples (nombre estim d'enregistrements d'une relation) ajouter autovacuum_analyze_threshold.
autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (integer)
Paramtre autovacuum_vacuum_cost_delay personnalis.
autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer)
Paramtre autovacuum_vacuum_cost_limit personnalis.
autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer)
Paramtre vacuum_freeze_min_age personnalis. Notez que autovacuum rejettera les tentatives de positionner un autovacuum_freeze_min_age plus grand que le paramtre autovacuum_freeze_max_age la moiti de la plage systme
d'identifiants.
autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer)
Paramtre autovacuum_freeze_max_age personnalis. L'autovacuum rejettera les tentatives de positionner un autovacuum_freeze_max_age plus grand que le paramtre systme (il ne peut tre que plus petit). Mme si autovacuum_freeze_max_age peut tre positionn de trs petites valeurs, voire zro, c'est habituellement dconseill parce
que cela forcera des oprations VACUUM trs frquentes.
autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer)
Paramtre vacuum_freeze_table_age personnalis.

Notes
Utiliser les OID dans les nouvelles applications n'est pas recommand : dans la mesure du possible, un type SERIAL ou un autre
gnrateur de squence sera utilis comme cl primaire de la table. Nanmoins, si l'application utilise les OID pour identifier des
lignes spcifiques d'une table, il est recommand de crer une contrainte unique sur la colonne oid de cette table afin de s'assurer
que les OID de la table identifient les lignes de faon rellement unique mme si le compteur est rinitialis. Il n'est pas garanti
que les OID soient uniques sur l'ensemble des tables. Dans le cas o un identifiant unique sur l'ensemble de la base de donnes est
ncessaire, on utilise prfrentiellement une combinaison de tableoid et de l'OID de la ligne.

Astuce
L'utilisation de OIDS=FALSE est dconseille pour les tables dpourvues de cl primaire. En effet, sans OID ou
cl de donnes unique, il est difficile d'identifier des lignes spcifiques.
PostgreSQL cre automatiquement un index pour chaque contrainte d'unicit ou cl primaire afin d'assurer l'unicit. Il n'est
donc pas ncessaire de crer un index spcifiqueme pour les colonnes de cls primaires. Voir CREATE INDEX(7) pour plus
d'informations.
Les contraintes d'unicit et les cls primaires ne sont pas hrites dans l'implantation actuelle. Cela diminue la fonctionnalit des
combinaisons d'hritage et de contraintes d'unicit.
Une table ne peut pas avoir plus de 1600 colonnes (en pratique, la limite relle est habituellement plus basse du fait de contraintes
sur la longueur des lignes).

Exemples
990

CREATE TABLE

Crer une table films et une table distributeurs :


CREATE TABLE films (
code
char(5) CONSTRAINT premierecle PRIMARY KEY,
titre
varchar(40) NOT NULL,
did
integer NOT NULL,
date_prod
date,
genre
varchar(10),
duree
interval hour to minute
);
CREATE TABLE distributeurs (
did
integer PRIMARY KEY DEFAULT nextval('serial'),
nom
varchar(40) NOT NULL CHECK (nom <> '')
);
Crer une table contenant un tableau deux dimensions :
CREATE TABLE array_int (
vecteur int[][]
);
Dfinir une contrainte d'unicit pour la table films. Les contraintes d'unicit de table peuvent tre dfinies sur une ou plusieurs
colonnes de la table :
CREATE TABLE films (
code
char(5),
titre
varchar(40),
did
integer,
date_prod
date,
genre
varchar(10),
duree
interval hour to minute,
CONSTRAINT production UNIQUE(date_prod)
);
Dfinir une contrainte de vrification sur une colonne :
CREATE TABLE distributeurs (
did
integer CHECK (did > 100),
nom
varchar(40)
);
Dfinir une contrainte de vrification sur la table :
CREATE TABLE distributeurs (
did
integer,
nom
varchar(40)
CONSTRAINT con1 CHECK (did > 100 AND nom <> '')
);
Dfinir une contrainte de cl primaire sur la table films.
CREATE TABLE films (
code
char(5),
titre
varchar(40),
did
integer,
date_prod
date,
genre
varchar(10),
duree
interval hour to minute,
CONSTRAINT code_titre PRIMARY KEY(code,titre)
);
Dfinir une contrainte de cl primaire pour la table distributeurs. Les deux exemples suivants sont quivalents, le premier utilise la
syntaxe de contrainte de table, le second la syntaxe de contrainte de colonne :
CREATE TABLE distributeurs (
did
integer,
nom
varchar(40),
PRIMARY KEY(did)
);
991

CREATE TABLE

CREATE TABLE distributeurs (


did
integer PRIMARY KEY,
nom
varchar(40)
);
Affecter une valeur par dfaut la colonne nom, une valeur par dfaut la colonne did, engendre l'aide d'une squence, et une
valeur par dfaut la colonne modtime, quivalente au moment o la ligne est insre :
CREATE TABLE distributeurs (
name
varchar(40) DEFAULT 'Luso Films',
did
integer DEFAULT nextval('distributeurs_serial'),
modtime
timestamp DEFAULT current_timestamp
);
Dfinir deux contraintes de colonnes NOT NULL sur la table distributeurs, dont l'une est explicitement nomme :
CREATE TABLE distributeurs (
did
integer CONSTRAINT no_null NOT NULL,
nom
varchar(40) NOT NULL
);
Dfinir une contrainte d'unicit sur la colonne nom :
CREATE TABLE distributeurs (
did
integer,
nom
varchar(40) UNIQUE
);
La mme chose en utilisant une contrainte de table :
CREATE TABLE distributeurs (
did
integer,
nom
varchar(40),
UNIQUE(nom)
);
Crer la mme table en spcifiant un facteur de remplissage de 70% pour la table et les index uniques :
CREATE TABLE distributeurs (
did
integer,
nom
varchar(40),
UNIQUE(nom) WITH (fillfactor=70)
)
WITH (fillfactor=70);
Crer une table cercles avec une contrainte d'exclusion qui empche le croisement de deux cercles :
CREATE TABLE cercles (
c circle,
EXCLUDE USING gist (c WITH &&)
);
Crer une table cinemas dans le tablespace diskvol1 :
CREATE TABLE cinemas (
id serial,
nom text,
emplacement text
) TABLESPACE diskvol1;
Crer un type composite et une table type :
CREATE TYPE type_employe AS (nom text, salaire numeric);
CREATE TABLE employes OF type_employe (
PRIMARY KEY (nom),
992

CREATE TABLE

salaire WITH OPTIONS DEFAULT 1000


);

Compatibilit
La commande CREATE TABLE est conforme au standard SQL, aux exceptions indiques ci-dessous.

Tables temporaires
Bien que la syntaxe de CREATE TEMPORARY TABLE ressemble celle du SQL standard, l'effet n'est pas le mme. Dans le
standard, les tables temporaires sont dfinies une seule fois et existent automatiquement (vide de tout contenu au dmarrage) dans
toute session les utilisant. PostgreSQL, au contraire, impose chaque session de lancer une commande CREATE TEMPORARY
TABLE pour chaque table temporaire utilise. Cela permet des sessions diffrentes d'utiliser le mme nom de table temporaire
dans des buts diffrents (le standard contraint toutes les instances d'une table temporaire donne pointer sur la mme structure de
table).
Le comportement des tables temporaires tel que dfini par le standard est largement ignore. Le comportement de PostgreSQL
sur ce point est similaire celui de nombreuses autres bases de donnes SQL.
PostgreSQL ne respecte pas la distinction impose par le standard entre tables temporaires globales et locales. En effet, cette
distinction repose sur le concept de modules que PostgreSQL ne gre pas. Pour des raisons de compatibilit, PostgreSQL accepte nanmoins les mots-cls GLOBAL et LOCAL dans la dfinition d'une table temporaire, mais ils n'ont aucun effet.
La clause ON COMMIT sur les tables temporaires diffre quelque peu du standard SQL. Si la clause ON COMMIT est omise, SQL
spcifie ON COMMIT DELETE ROWS comme comportemant par dfaut. PostgreSQL utilise ON COMMIT PRESERVE
ROWS par dfaut. De plus, l'option ON COMMIT DROP n'existe pas en SQL.

Contraintes d'unicit non dferres


Quand une contrainte UNIQUE ou PRIMARY KEY est non dferrable, PostgreSQL vrifie l'unicit immdiatement aprs qu'une
ligne soit insre ou modifie. Le standard SQL indique que l'unicit doit tre force seulement la fin de l'instruction ; ceci fait
une diffrence quand, par exemple, une seule commande met jour plusieurs valeurs de cls. Pour obtenir un comportement compatible au standard, dclarez la contrainte comme DEFERRABLE mais non dferre (c'est--dire que INITIALLY IMMEDIATE).
Faites attention que cela peut tre beaucoup plus lent qu'une vrification d'unicit immdiate.

Contraintes de vrification de colonnes


Dans le standard, les contraintes de vrification CHECK de colonne ne peuvent faire rfrence qu' la colonne laquelle elles
s'appliquent ; seules les contraintes CHECK de table peuvent faire rfrence plusieurs colonnes. PostgreSQL n'impose pas cette
restriction ; les contraintes de vrifications de colonnes et de table ont un traitement identique.

EXCLUDE Constraint
Le type de contrainte EXCLUDE est une extension PostgreSQL.

Contrainte NULL
La contrainte NULL (en fait, une non-contrainte) est une extension PostgreSQL au standard SQL, incluse pour des raisons
de compatibilit avec d'autres systmes de bases de donnes (et par symtrie avec la contrainte NOT NULL). Comme c'est la valeur par dfaut de toute colonne, sa prsence est un simple bruit.

Hritage
L'hritage multiple via la clause INHERITS est une extension du langage PostgreSQL. SQL:1999 et les versions ultrieures dfinissent un hritage simple en utilisant une syntaxe et des smantiques diffrentes. L'hritage style SQL:1999 n'est pas encore
support par PostgreSQL.

Tables sans colonne


PostgreSQL autorise la cration de tables sans colonne (par exemple, CREATE TABLE foo();). C'est une extension du standard SQL, qui ne le permet pas. Les tables sans colonne ne sont pas trs utiles mais les interdire conduit un comportement
trange de ALTER TABLE DROP COLUMN. Il est donc plus sage d'ignorer simplement cette restriction.

WITH clause
La clause WITH est une extension PostgreSQL ; ni les paramtres de stockage ni les OID ne sont dans le standard.
993

CREATE TABLE

Tablespaces
Le concept PostgreSQL de tablespace n'est pas celui du standard. De ce fait, les clauses TABLESPACE et USING INDEX
TABLESPACE sont des extensions.

Tables types
Les tables types implmentent un sous-ensemble du standard SQL. Suivant le standard, une table type a des colonnes correspondant au type composite ainsi qu'une autre colonne qui est la colonne auto-rfrente . PostgreSQL ne supporte pas ces colonnes
auto-rfrentes explicitement mais le mme effet est disponible en utilisant la fonctionnalit OID.

Voir aussi
ALTER TABLE(7), DROP TABLE(7), CREATE TABLESPACE(7)

994

Nom
CREATE TABLE AS Dfinir une nouvelle table partir des rsultats d'une requte

Synopsis
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE nom_table
[ (nom_colonne [, ...] ) ]
[ WITH ( parametre_stockage [= valeur] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE espace_logique ]
AS requte
[ WITH [ NO ] DATA ]

Description
CREATE TABLE AS cre une table et y insre les donnes rcupres par une commande SELECT. Les colonnes de la table
ont les noms et les types de donnes associs aux colonnes en sortie du SELECT (les noms des colonnes peuvent toutefois tre
surchargs).
CREATE TABLE AS semble possder des similitudes avec la cration d'une vue mais est, en fait, assez diffrente : elle cre
une nouvelle table et n'value la requte qu'une seule fois, pour le chargement initial de la nouvelle table. Les modifications ultrieures de la table source ne sont pas prises en compte. Au contraire, une vue rvalue l'instruction SELECT de dfinition
chaque appel.

Paramtres
GLOBAL ou LOCAL
Ignor. Conserv pour la compatibilit (cf. CREATE TABLE(7)).
TEMPORARY ou TEMP
Si spcifi, la table est temporaire (cf. CREATE TABLE(7)).
UNLOGGED
Si spcifi, la table est cre comme une table non trace dans les journaux de transactions. Voir CREATE TABLE(7) pour
plus de dtails.
nom_table
Le nom de la table crer (ventuellement qualifi du nom du schma).
nom_colonne
Le nom d'une colonne dans la nouvelle table. Si les noms de colonnes ne sont pas prciss, ils sont issus des noms des colonnes en sortie de la requte. Les noms des colonnes ne peuvent pas tre prciss lorsque la table est cre partir d'une
commande EXECUTE.
WITH ( paramtre_stockage [= valeur] [, ... ] )
Cette clause indique les paramtres de stockage optionnels pour la nouvelle table ; voir la section intitule Paramtres de
stockage pour plus d'informations. La clause WITH peut aussi inclure OIDS=TRUE (ou simplement OIDS) pour indiquer
que les lignes de la nouvelle table doivent avoir des OID (identifiants d'objets) ou OIDS=FALSE pour indiquer le contraire.
Voir CREATE TABLE(7) pour plus d'informations.
WITH OIDS, WITHOUT OIDS
Ce sont les syntaxes obsoltes mais quivalentes, respectivement de WITH (OIDS) et WITH (OIDS=FALSE). Si vous
souhaitez indiquer la fois l'option OIDS et les paramtres de stockage, vous devez utiliser la syntaxe WITH ( ... ) ;
voir ci-dessus.
ON COMMIT
Le comportement des tables temporaires la fin d'un bloc de transaction est contrlable en utilisant ON COMMIT. Voici les
trois options :
PRESERVE ROWS
Aucune action spciale n'est effectue la fin de la transaction. C'est le comportement par dfaut.
DELETE ROWS
Toutes les lignes de la table temporaire seront supprimes la fin de chaque bloc de transaction. Habituellement, un TRUNCATE(7) automatique est effectu chaque COMMIT.
995

CREATE TABLE AS

DROP
La table temporaire sera supprime la fin du bloc de transaction en cours.
TABLESPACE espace_logique
L'espace_logique est le nom du tablespace dans lequel est cre la nouvelle table. S'il n'est pas indiqu, default_tablespace est consult, sauf si la table est temporaire auquel cas temp_tablespaces est utilis.
requte
Une commande SELECT(7), TABLE ou VALUES(7), voire une commande EXECUTE(7) qui excute un SELECT prpar,
TABLE ou une requte VALUES.
WITH [ NO ] DATA
Cette clause indique si les donnes produites par la requtes doivent tre copies dans la nouvelle table. Si non, seule la structure de la table est copie. La valeur par dfaut est de copier les donnes.

Notes
Cette commande est fonctionnellement quivalente SELECT INTO(7). Elle lui est cependant prfre car elle prsente moins de
risques de confusion avec les autres utilisations de la syntaxe SELECT INTO. De plus, CREATE TABLE AS offre plus de
fonctionnalits que SELECT INTO.
Avant PostgreSQL 8.0, CREATE TABLE AS incluait toujours les OIDs dans la table cre. partir de PostgresSQL 8.0, la
commande CREATE TABLE AS autorise l'utilisateur spcifier explicitement la prsence des OID. En l'absence de prcision, la
variable de configuration default_with_oids est utilise. partir de PostgreSQL 8.1, la valeur par dfaut de cette variable est
faux ; le comportement par dfaut n'est donc pas identique celui des versions prcdant la 8.0. Il est prfrable que les applications qui ncessitent des OID dans la table cre par CREATE TABLE AS indiquent explicitement WITH (OIDS) pour
s'assurer du comportement souhait.

Exemples
Crer une table films_recent contenant les entres rcentes de la table films :
CREATE TABLE films_recent AS
SELECT * FROM films WHERE date_prod >= '2006-01-01';
Pour copier une table compltement, la forme courte utilisant la clause TABLE peut aussi tre utilise :
CREATE TABLE films2 AS
TABLE films;
Crer une nouvelle table temporaire films_recents consistant des seules entres rcentes provenant de la table films en utilisant une instruction prpare. La nouvelle table a des OID et sera supprime la validation (COMMIT) :
PREPARE films_recents(date) AS
SELECT * FROM films WHERE date_prod > $1;
CREATE TEMP TABLE films_recents WITH (OIDS) ON COMMIT DROP AS
EXECUTE films_recents('2002-01-01');

Compatibilit
CREATE TABLE AS est conforme au standard SQL. The following are nonstandard extensions :

Le standard requiert des parenthses autour de la clause de la sous-requte ; elles sont optionnelles dans PostgreSQL.
Dans le standard, la clause WITH [ NO ] DATA est requise alors que PostgreSQL la rend optionnelle.
PostgreSQL gre les tables temporaires d'une faon bien diffrente de celle du standard ; voir CREATE TABLE(7) pour les
dtails.
La clause WITH est une extension PostgreSQL ; ni les paramtres de stockage ni les OID ne sont dans le standard.
Le concept PostgreSQL des tablespaces ne fait pas partie du standard. Du coup, la clause TABLESPACE est une extension.

Voir aussi
CREATE TABLE(7), EXECUTE(7), SELECT(7), SELECT INTO(7), VALUES(7)

996

Nom
CREATE TABLESPACE Dfinir un nouvel tablespace

Synopsis
CREATE TABLESPACE nom_tablespace
[ OWNER nom_utilisateur ]
LOCATION 'rpertoire'

Description
CREATE TABLESPACE enregistre un nouveau tablespace pour la grappe de bases de donnes. Le nom du tablespace doit
tre distinct du nom de tout autre tablespace de la grappe.
Un tablespace permet aux superutilisateurs de dfinir un nouvel emplacement sur le systme de fichiers pour le stockage des fichiers de donnes contenant des objets de la base (comme les tables et les index).
Un utilisateur disposant des droits appropris peut passer nom_tablespace comme paramtre de CREATE DATABASE,
CREATE TABLE, CREATE INDEX ou ADD CONSTRAINT pour que les fichiers de donnes de ces objets soient stocks
l'intrieur du tablespace spcifi.

Paramtres
nom_tablespace
Le nom du tablespace crer. Le nom ne peut pas commencer par pg_, de tels noms sont rservs pour les tablespaces systme.
nom_utilisateur
Le nom de l'utilisateur, propritaire du tablespace. En cas d'omission, il s'agit de l'utilisateur ayant excut la commande.
Seuls les superutilisateurs peuvent crer des tablespaces mais ils peuvent en donner la proprit des utilisateurs standard.
rpertoire
Le rpertoire qui sera utilis pour le tablespace. Le rpertoire doit tre vide et doit appartenir l'utilisateur systme PostgreSQL. Le rpertoire doit tre spcifi par un chemin absolu.

Notes
Les tablespaces ne sont supports que sur les systmes grant les liens symboliques.
CREATE TABLESPACE ne peut pas tre excut l'intrieur d'un bloc de transactions.

Exemples
Crer un tablespace espace_base sur /data/dbs :
CREATE TABLESPACE espace_base LOCATION '/data/dbs';
Crer un tablespace espace_index sur /data/indexes et en donner la proprit l'utilisatrice genevieve :
CREATE TABLESPACE espace_index OWNER genevieve LOCATION '/data/indexes';

Compatibilit
CREATE TABLESPACE est une extension PostgreSQL.

Voir aussi
CREATE DATABASE(7), CREATE TABLE(7), CREATE INDEX(7), DROP TABLESPACE(7), ALTER TABLESPACE(7)

997

Nom
CREATE TEXT SEARCH CONFIGURATION dfinir une nouvelle configuration de recherche plein texte

Synopsis
CREATE TEXT SEARCH CONFIGURATION nom (
PARSER = nom_analyseur |
COPY = config_source
)

Description
CREATE TEXT SEARCH CONFIGURATION cre une nouvelle configuration de recherche plein texte. Une configuration
indique l'analyseur qui peut diviser une chane en jetons, ainsi que les dictionnaires pouvant tre utiliss pour dterminer les jetons intressants rechercher.
Si seul l'analyseur est indiqu, la nouvelle configuration de recherche plein texte n'a initialement aucune relation entre les types
de jeton et les dictionnaires et, du coup, ignorera tous les mots. De nouveaux appels aux commandes ALTER TEXT SEARCH
CONFIGURATION doivent tre utiliss pour crer les correspondances et rendre la configuration rellement utile. Autrement,
une configuration de recherche plein texte peut tre copie.
Si un nom de schma est prcis, alors le modle de recherche plein texte est cr dans le schma indiqu. Sinon il est cr dans
le schma en cours.
L'utilisateur qui dfinit une configuration de recherche plein texte en devient son propritaire.
Voir Chapitre 12, Recherche plein texte pour plus d'informations.

Paramtres
nom
Le nom de la configuration de recherche plein texte (pouvant tre qualifi du schma).
parser_name
Le nom de l'analyseur de recherche plein texte utiliser pour cette configuration.
source_config
Le nom d'une configuration existante de recherche plein texte copier.

Notes
Les options PARSER et COPY sont mutuellement exclusives car, quand une configuration existante est copie, sa slection de
son analyseur est aussi copie.

Compatibilit
Il n'existe pas d'instruction CREATE TEXT SEARCH CONFIGURATION dans le standard SQL.

Voir aussi
ALTER TEXT SEARCH CONFIGURATION(7), DROP TEXT SEARCH CONFIGURATION(7)

998

Nom
CREATE TEXT SEARCH DICTIONARY dfinir un dictionnaire de recherche plein texte

Synopsis
CREATE TEXT SEARCH DICTIONARY nom (
TEMPLATE = modele
[, option = valeur [, ... ]]
)

Description
CREATE TEXT SEARCH DICTIONARY cre un nouveau dictionnaire de recherche plein texte. Un dictionnaire de recherche plein texte indique une faon de distinguer les mots intressants rechercher des mots inintressants. Un dictionnaire
dpend d'un modle de recherche plein texte qui spcifie les fonctions qui font rellement le travail. Typiquement, le dictionnaire fournit quelques options qui contrlent le comportement dtaill des fonctions du modle.
Si un nom de schma est prcis, alors le dictionnaire de recherche plein texte est cr dans le schma indiqu. Sinon il est cr
dans le schma en cours.
L'utilisateur qui dfinit un dictionnaire de recherche plein texte en devient son propritaire.
Voir Chapitre 12, Recherche plein texte pour plus d'informations.

Paramtres
nom
Le nom du dictionnaire de recherche plein texte (pouvant tre qualifi du schma).
modele
Le nom du modle de recherche plein texte qui dfinira le comportement basique de ce dictionnaire.
option
Le nom d'une option, spcifique au modle, configurer pour ce dictionnaire.
valeur
La valeur utiliser pour une option spcifique au modle. Si la valeur n'est pas un simple identifiant ou un nombre, elle doit
tre entre guillemets simples (mais vous pouvez toujours le faire si vous le souhaitez).
Les options peuvent apparatre dans n'importe quel ordre.

Exemples
La commande exemple suivante cre un dictionnaire bas sur Snowball avec une liste spcifique de mots d'arrt.
CREATE TEXT SEARCH DICTIONARY mon_dico_russe (
template = snowball,
language = russian,
stopwords = myrussian
);

Compatibilit
Il n'existe pas d'instructions CREATE TEXT SEARCH DICTIONARY dans le standard SQL.

Voir aussi
ALTER TEXT SEARCH DICTIONARY(7), DROP TEXT SEARCH DICTIONARY(7)

999

Nom
CREATE TEXT SEARCH PARSER dfinir un nouvel analyseur de recherche plein texte

Synopsis
CREATE TEXT SEARCH PARSER nom (
START = fonction_debut ,
GETTOKEN = function_gettoken ,
END = fonction_fin ,
LEXTYPES = fonction_lextypes
[, HEADLINE = fonction_headline ]
)

Description
CREATE TEXT SEARCH PARSER cre un nouvel analyseur de recherche plein texte. Un analyseur de recherche plein texte
dfinit une mthode pour diviser une chane en plusieurs jetons et pour assigner des types (catgories) aux jetons. Un analyseur
n'est pas particulirement utile en lui-mme mais doit tre limit dans une configuration de recherche plein texte avec certains
dictionnaires de recherche plein texte utiliser pour la recherche.
Si un nom de schma est prcis, alors le dictionnaire de recherche plein texte est cr dans le schma indiqu. Sinon il est cr
dans le schma en cours.
Vous devez tre un superutilisateur pour utiliser CREATE TEXT SEARCH PARSER. (Cette restriction est faite parce que la
dfinition d'un analyseur de recherche plein texte peut gner, voire arrter brutalement, le serveur.)
Voir Chapitre 12, Recherche plein texte pour plus d'informations.

Paramtres
name
Le nom d'un analyseur de recherche plein texte (pouvant tre qualifi du schma).
fonction_debut
Le nom d'une fonction de dmarrage pour l'analyseur.
fonction_gettoken
Le nom d'une fonction pour l'obtention du prochain jeton (get-next-token) pour l'analyseur.
fonction_fin
Le nom de la fonction d'arrt de l'analyseur.
fonction_lextypes
Le nom de la fonction lextypes pour l'analyseur (une fonction qui renvoie de l'information sur l'ensemble de types de jeton
qu'il produit).
fonction_headline
Le nom de la fonction headline pour l'analyseur (une fonction qui rsume un ensemble de jetons).
Les noms des fonctions peuvent se voir qualifier du nom du schma si ncessaire. Le type des arguments n'est pas indiqu car la
liste d'argument pour chaque type de fonction est prdtermin. Toutes les fonctions sont obligatoires sauf headline.
Les options peuvent apparatre dans n'importe quel ordre, pas seulement celui indiqu ci-dessus.

Compatibilit
Il n'existe pas d'instruction CREATE TEXT SEARCH PARSER dans le standard SQL.

Voir aussi
ALTER TEXT SEARCH PARSER(7), DROP TEXT SEARCH PARSER(7)

1000

Nom
CREATE TEXT SEARCH TEMPLATE dfinir un nouveau modle de recherche plein texte

Synopsis
CREATE TEXT SEARCH TEMPLATE nom (
[ INIT = fonction_init , ]
LEXIZE = fonction_lexize
)

Description
CREATE TEXT SEARCH TEMPLATE cre un nouveau modle de recherche plein texte. Les modles de recherche plein
texte dfinissent les fonctions qui implmentent les dictionnaires de recherche plein texte. Un modle n'est pas utile en lui-mme
mais doit tre instanci par un dictionnaire pour tre utilis. Le dictionnaire spcifie typiquement les paramtres donner aux
fonctions modle.
Si un nom de schma est prcis, alors le modle de recherche plein texte est cr dans le schma indiqu. Sinon il est cr dans
le schma en cours.
Vous devez tre un superutilisateur pour utiliser CREATE TEXT SEARCH TEMPLATE. Cette restriction est faite parce que
la dfinition d'un modle de recherche plein texte peut gner, voire arrter brutalement le serveur. La raison de la sparation des
modles et des dictionnaires est qu'un modle encapsule les aspects non srs de la dfinition d'un dictionnaire. Les paramtres qui peuvent tre dfinis lors de la mise en place d'un dictionnaire sont suffisamment srs pour tre utilis par des utilisateurs sans droits. Du coup, la cration d'un dictionnaire ne demande pas de droits particuliers.
Voir Chapitre 12, Recherche plein texte pour plus d'informations.

Paramtres
nom
Le nom du modle de recherche plein texte (pouvant tre qualifi du schma).
fonction_init
Le nom de la fonction d'initialisation du modle.
fonction_lexize
Le nom de la fonction lexize du modle.
Les noms des fonctions peuvent se voir qualifier du nom du schma si ncessaire. Le type des arguments n'est pas indiqu car la
liste d'argument pour chaque type de fonction est prdtermin. La fonction lexize est obligatoire mais la fonction init est optionnelle.
Les arguments peuvent apparatre dans n'importe quel ordre, pas seulement dans celui indiqu ci-dessus.

Compatibilit
Il n'existe pas d'instruction CREATE TEXT SEARCH TEMPLATE dans le standard SQL.

Voir aussi
ALTER TEXT SEARCH TEMPLATE(7), DROP TEXT SEARCH TEMPLATE(7)

1001

Nom
CREATE TRIGGER Dfinir un nouveau dclencheur

Synopsis
CREATE [ CONSTRAINT ] TRIGGER nom { BEFORE | AFTER | INSTEAD OF } { vnement [ OR
... ] }
ON table
[ FROM nom_table_referencee ]
[ NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } ]
[ FOR [ EACH ] { ROW | STATEMENT } ]
[ WHEN ( condition ) ]
EXECUTE PROCEDURE nom_fonction ( arguments )
o vnement fait partie de :
INSERT
UPDATE [ OF nom_colonne [, ... ] ]
DELETE
TRUNCATE

Description
CREATE TRIGGER cre un nouveau dclencheur. Le dclencheur est associ la table ou la vue spcifie et excute la
fonction nom_fonction lorsque certains vnements surviennent.
L'appel du dclencheur peut avoir lieu avant que l'opration ne soit tente sur une ligne (avant la vrification des contraintes et
la tentative d'INSERT, UPDATE ou DELETE) ou une fois que l'opration est termine (aprs la vrification des contraintes et
la fin de la commande INSERT, UPDATE ou DELETE) ; ou bien en remplacement de l'opration (dans le cas d'oprations
INSERT, UPDATE ou DELETE sur une vue). Si le dclencheur est lanc avant l'vnement ou en remplacement de
l'vnement, le dclencheur peut ignorer l'opration sur la ligne courante ou modifier la ligne en cours d'insertion (uniquement
pour les oprations INSERT et UPDATE). Si le dclencheur est activ aprs l'vnement, toute modification, dont celles effectues par les autres dclencheurs, est visible par le dclencheur.
Un dclencheur marqu FOR EACH ROW est appel pour chaque ligne que l'opration modifie. Par exemple, un DELETE affectant dix lignes entrane dix appels distincts de tout dclencheur ON DELETE sur la relation cible, une fois par ligne supprime. Au contraire, un dclencheur marqu FOR EACH STATEMENT ne s'excute qu'une fois pour une opration donne,
quelque soit le nombre de lignes modifies (en particulier, une opration qui ne modifie aucune ligne rsulte toujours en
l'excution des dclencheurs FOR EACH STATEMENT applicables).
Les dclencheurs dfinis en remplacement (INSTEAD OF) doivent obligatoirement tre marqus FOR EACH ROW, et ne
peuvent tre dfinis que sur des vues. Les dclencheurs BEFORE et AFTER portant sur des vues devront quant eux tre marqus FOR EACH STATEMENT.
Les dclencheurs peuvent galement tre dfinis pour l'vnement TRUNCATE, mais ne pourront, dans ce cas, qu'tre marqus
FOR EACH STATEMENT.
Le tableau suivant rcapitule quels types de dclencheurs peuvent tre utiliss sur les tables et les vues :
Dclenchement

vnement

Niveau ligne

Niveau instruction

BEFORE

INSERT/UPDATE/DELETE
TRUNCATE

--

Tables

AFTER

INSERT/UPDATE/DELETE

Tables

Tables et vues

TRUNCATE

--

Tables

INSERT/UPDATE/DELETE

Vues

--

TRUNCATE

--

--

INSTEAD OF

Tables

Tables et vues

De plus, les triggers peuvent tre dfinis pour tre dclenchs suite l'excution d'un TRUNCATE, mais seulement dans le cas
d'un trigger FOR EACH STATEMENT.
En outre, la dfinition d'un trigger peut spcifier une condition WHEN qui sera teste pour vrifier si le trigger doit rellement
tre dclench. Dans les triggers au niveau ligne, la condition WHEN peut examiner l'ancienne et/ou la nouvelle valeurs des co1002

CREATE TRIGGER

lonnes de la ligne. Les triggers au niveau instruction peuvent aussi avoir des conditions WHEN, bien que la fonctionnalit n'est pas
aussi utile pour elles car la condition ne peut pas faire rfrence aux valeurs de la table.
Si plusieurs dclencheurs du mme genre sont dfinis pour le mme vnement, ils sont dclenchs suivant l'ordre alphabtique de
leur nom.
Lorsque l'option CONSTRAINT est spcifie, cette commande cre un dclencheur contrainte. Ce nouvel objet est identique aux
dclencheurs normaux except le fait que le moment de dclenchement peut alors tre ajust via l'utilisation de SET
CONSTRAINTS(7). Les dclencheurs contraintes ne peuvent tre que de type AFTER ROW. Ils peuvent tre dclenchs soit la
fin de l'instruction causant l'vnement, soit la fin de la transaction ayant contenu l'instruction de dclenchement ; dans ce dernier cas, ils sont alors dfinis comme diffrs. L'excution d'un dclencheur diffr peut galement tre force en utilisant l'option
SET CONSTRAINTS. Le comportement attendu des dclencheurs contraintes est de gnrer une exception en cas de violation de
la contrainte qu'ils implmentent.
SELECT ne modifie aucune ligne ; la cration de dclencheurs sur SELECT n'est donc pas possible. Les rgles et vues sont plus
appropries dans ce cas.
Chapitre 36, Dclencheurs (triggers) prsente de plus amples informations sur les dclencheurs.

Paramtres
nom
Le nom du nouveau dclencheur. Il doit tre distinct du nom de tout autre dclencheur sur la table. Le nom ne peut pas tre
qualifi d'un nom de schma, le dclencheur hritant du schma de sa table. Pour un dclencheur contrainte, c'est galement le
nom utiliser lorsqu'il s'agira de modifier son comportement via la commande SET CONSTRAINTS.
BEFORE, AFTER, INSTEAD OF
Dtermine si la fonction est appele avant, aprs ou en remplacement de l'vnement. Un dclencheur contrainte ne peut tre
spcifi qu'AFTER.
vnement
Peut-tre INSERT, UPDATE ou DELETE ou TRUNCATE ; prcise l'vnement qui active le dclencheur. Plusieurs vnements peuvent tre prciss en les sparant par OR.
Pour les triggers se dclenchant suite un UPDATE, il est possible de spcifier une liste de colonnes utilisant cette syntaxe :
UPDATE OF nom_colonne_1 [, nom_colonne_2 ... ]
Le trigger se dclenchera seulement si au moins une des colonnes listes est mentionne comme cible de la commande UPDATE.
Les vnements INSTEAD OF UPDATE ne supportent pas de listes de colonnes.
table
Le nom (ventuellement qualifi du nom du schma) de la table ou de la vue laquelle est rattach le dclencheur.
nom_table_referencee
Le nom d'une autre table (possiblement qualifie par un nom de schma) rfrence par la contrainte. Cette option est utiliser pour les contraintes de cls trangres et n'est pas recommande pour d'autres types d'utilisation. Elle ne peut tre spcifie
que pour les dclencheurs contraintes.
DEFERRABLE, NOT DEFERRABLE, INITIALLY IMMEDIATE, INITIALLY DEFERRED
La spcification du moment de dclenchement par dfaut. Voir la partie CREATE TABLE(7) pour plus de dtails sur cette
option. Elle ne peut tre spcifie que pour les dclencheurs contraintes.
FOR EACH ROW, FOR EACH STATEMENT
Prcise si la procdure du dclencheur doit tre lance pour chaque ligne affecte par l'vnement ou simplement pour chaque
instruction SQL. FOR EACH STATEMENT est la valeur par dfaut. Constraint triggers can only be specified FOR EACH
ROW.
condition
Une expression boolenne qui dtermine si la fonction trigger sera rellement excute. Si WHEN est indiqu, la fonction sera
seulement appele si la condition renvoie true. Pour les triggers FOR EACH ROW, la condition WHEN peut faire rfrence aux valeurs des colonnes des ancienne et nouvelle lignes en utilisant la notation OLD.nom_colonne ou
NEW.nom_colonne, respectivement. Bien sr, le triggers sur INSERT ne peuvent pas faire rfrence OLD et ceux sur
DELETE ne peuvent pas faire rfrence NEW.
Les dclencheurs INSTEAD OF ne supportent pas de condition WHEN.

1003

CREATE TRIGGER

Actuellement, les expressions WHEN ne peuvent pas contenir de sous-requtes.


noter que pour les dclencheurs contraintes, l'valuation de la clause WHEN n'est pas diffre mais intervient immdiatement aprs que l'opration de mise jour de la ligne soit effectue. Si la condition n'est pas value vrai, alors le dclencheur n'est pas plac dans la file d'attente des excutions diffres.
nom_fonction
Une fonction utilisateur, dclare sans argument et renvoyant le type trigger, excute l'activation du dclencheur.
arguments
Une liste optionnelle d'arguments spars par des virgules fournir la fonction lors de l'activation du dclencheur. Les arguments sont des chanes littrales constantes. Il est possible d'crire ici de simples noms et des constantes numriques mais ils
sont tous convertis en chane. L'accs aux arguments du trigger depuis la fonction peut diffrer de l'accs aux arguments d'une
fonction standard ; la consultation des caractristiques d'implantation du langage de la fonction peut alors s'avrer utile.

Notes
Pour crer un dclencheur sur une table, l'utilisateur doit possder le droit TRIGGER sur la table. L'utilisateur doit aussi avoir le
droit EXECUTE sur la fonction trigger.
Utiliser DROP TRIGGER(7) pour supprimer un dclencheur.
Un trigger sur colonne spcifique (one defined using the UPDATE OF nom_colonne syntax) se dclenchera quand une des colonnes indiques est liste comme cible de la liste SET pour la commande UPDATE. Il est possible qu'une valeur de colonne
change mme si le trigger n'est pas dclench parceque les modifications au contenu de la ligne par les triggers BEFORE UPDATE ne sont pas pris en compte. De mme, une commande comme UPDATE ... SET x = x ... dclenchera le trigger
sur la colonne x, bien que la valeur de cette colonne ne change pas.
Dans un trigger BEFORE, la condition WHEN est value juste avant l'excution de la fonction, donc utiliser WHEN n'est pas matriellement diffrent de tester la mme condition au dbut de la fonction trigger. Notez en particulier que la ligne NEW vu par la
condition est sa valeur courante et possiblement modifie par des triggers prcdents. De plus, la condition WHEN d'un trigger BEFORE n'est pas autoris examiner les colonnes systme de la ligne NEW (comme l'oid), car elles n'auront pas encore t initialises.
Dans un trigger AFTER, la condition WHEN est value juste aprs la mise jour de la ligne et elle dtermine si un vnement doit
dclencher le trigger la fin de l'instruction. Donc, quand la condition WHEN d'un trigger AFTER ne renvoie pas true, il n'est pas
ncessaire de prparer un vnement ou de relire la ligne la fin de l'instruction. Cela peut apporter une amlioration significative
des performances dans les instructions qui modifient de nombreuses lignes, si le trigger a besoin d'tre dclencher pour quelques
lignes.
Dans les versions de PostgreSQL antrieures la 7.3, il tait ncessaire de dclarer un type opaque de retour pour les fonctions
dclencheur, plutt que trigger. Pour pouvoir charger d'anciens fichiers de sauvegarde, CREATE TRIGGER accepte qu'une
fonction dclare une valeur de retour de type opaque, mais il affiche un message d'avertissement et change le type de retour dclar en trigger.

Exemples
Excutez la fonction check_account_update quand une ligne de la table accounts est sur le point d'tre mise jour :
CREATE TRIGGER check_update
BEFORE UPDATE ON accounts
FOR EACH ROW
EXECUTE PROCEDURE check_account_update();
Idem, mais avec une excution de la fonction seulement si la colonne balance est spcifie comme cible de la commande UPDATE :
CREATE TRIGGER check_update
BEFORE UPDATE OF balance ON accounts
FOR EACH ROW
EXECUTE PROCEDURE check_account_update();
Cette forme excute la fonction seulement si la colonne balance a rellement chang de valeur :
CREATE TRIGGER check_update
BEFORE UPDATE ON accounts
1004

CREATE TRIGGER

FOR EACH ROW


WHEN (OLD.balance IS DISTINCT FROM NEW.balance)
EXECUTE PROCEDURE check_account_update();
Appelle une fonction pour tracer les mises jour de la table accounts, mais seulement si quelque chose a chang :
CREATE TRIGGER log_update
AFTER UPDATE ON accounts
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE log_account_update();
xecute la fonction view_insert_row pour chacune des lignes insrer dans la table sous-jacente la vue my_view :
CREATE TRIGGER view_insert
INSTEAD OF INSERT ON my_view
FOR EACH ROW
EXECUTE PROCEDURE view_insert_row();
Section 36.4, Un exemple complet de trigger contient un exemple complet d'une fonction trigger crit en C.

Compatibilit
L'instruction CREATE TRIGGER de PostgreSQL implante un sous-ensemble du standard SQL. Les fonctionnalits manquantes sont :

SQL permet de dfinir des alias pour les lignes old et new ou pour les tables utilise dans la dfinition des actions dclenches (c'est--dire CREATE TRIGGER ... ON nomtable REFERENCING OLD ROW AS unnom NEW ROW
AS unautrenom...). PostgreSQL autorise l'criture de procdures de dclencheurs dans tout langage l'utilisateur. De ce
fait, l'accs aux donnes est gr spcifiquement pour chaque langage.

PostgreSQL n'autorise comme action dclenche que l'excution d'une fonction utilisateur. Le standard SQL, en revanche,
autorise l'excution d'autres commandes SQL, telles que CREATE TABLE. Cette limitation de PostgreSQL peut tre facilement contourne par la cration d'une fonction utilisateur qui excute les commandes dsires.

Le standard SQL dfinit l'ordre de cration comme ordre de lancement des dclencheurs multiples. PostgreSQL utilise l'ordre
alphabtique de leur nom, jug plus pratique.
Le standard SQL prcise que les dclencheurs BEFORE DELETE sur des suppressions en cascade se dclenchent aprs la fin du
DELETE en cascade. PostgreSQL dfinit que BEFORE DELETE se dclenche toujours avant l'action de suppression, mme
lors d'une action en cascade. Cela semble plus cohrent. Il existe aussi un comportement non standard quand les triggers BEFORE
modifient les lignes ou empchent les mises jour causes par une action rfrente. Ceci peut amener des violations de
contraintes ou au stockage de donnes qui n'honorent pas la contrainte rfrentielle.
La capacit prciser plusieurs actions pour un seul dclencheur avec OR est une extension PostgreSQL.
La possibilit d'excuter un trigger suite une commande TRUNCATE est une extension PostgreSQL du standard SQL, tout
comme la possibilit de dfinir des dclencheurs de niveau instruction sur des vues.
CREATE CONSTRAINT TRIGGER est une extension spcifique PostgreSQL du standard SQL.

Voir aussi
CREATE FUNCTION(7), ALTER TRIGGER(7), DROP TRIGGER(7), SET CONSTRAINTS(7)

1005

Nom
CREATE TYPE Dfinir un nouveau type de donnes

Synopsis
CREATE TYPE nom AS
( nom_attribut type_donne [ COLLATE collation ] [, ... ] )
CREATE TYPE nom AS ENUM
( [ 'label' [, ... ] ] )
CREATE TYPE nom (
INPUT = fonction_entre,
OUTPUT = fonction_sortie
[ , RECEIVE = fonction_rception ]
[ , SEND = fonction_envoi ]
[ , TYPMOD_IN = type_modifier_input_function ]
[ , TYPMOD_OUT = type_modifier_output_function ]
[ , ANALYZE = fonction_analyse ]
[ , INTERNALLENGTH = { longueurinterne | VARIABLE } ]
[ , PASSEDBYVALUE ]
[ , ALIGNMENT = alignement ]
[ , STORAGE = stockage ]
[ , LIKE = type_like ]
[ , CATEGORY = catgorie ]
[ , PREFERRED = prfr ]
[ , DEFAULT = dfaut ]
[ , ELEMENT = lment ]
[ , DELIMITER = dlimiteur ]
[ , COLLATABLE = collatable ]
)
CREATE TYPE nom

Description
CREATE TYPE enregistre un nouveau type de donnes utilisable dans la base courante. L'utilisateur qui dfinit un type en devient le propritaire.
Si un nom de schma est prcis, le type est cr dans ce schma. Sinon, il est cr dans le schma courant. Le nom du type doit
tre distinct du nom de tout type ou domaine existant dans le mme schma. Les tables possdent des types de donnes associs.
Il est donc ncessaire que le nom du type soit galement distinct du nom de toute table existant dans le mme schma.

Types composites
La premire forme de CREATE TYPE cre un type composite. Le type composite est dfini par une liste de noms d'attributs et
de types de donnes. Un collationnement d'attribute peut aussi tre spcifi si son type de donnes est collationnable. Un type
composite est essentiellement le mme que le type ligne (NDT : row type en anglais) d'une table, mais l'utilisation de CREATE
TYPE permet d'viter la cration d'une table relle quand seule la dfinition d'un type est voulue. Un type composite autonome
est utile, par exemple, comme type d'argument ou de retour d'une fonction.

Types numrs
La seconde forme de CREATE TYPE cre un type numr (enum), comme dcrit dans Section 8.7, Types numration .
Les types enum prennent une liste de un plusieurs labels entre guillemets, chacun devant faire moins de NAMEDATALEN octets (64 dans une installation PostgreSQL standard).

Types de base
La troisime forme de CREATE TYPE cre un nouveau type de base (type scalaire). Pour crer un nouveau type de base, il
faut tre superutilisateur. (Cette restriction est impose parce qu'une dfinition de type errone pourrait embrouiller voire arrter
brutalement le serveur.)
L'ordre des paramtres, dont la plupart sont optionnels, n'a aucune d'importance. Avant de dfinir le type, il est ncessaire de dfinir au moins deux fonctions ( l'aide de la commande CREATE FUNCTION). Les fonctions de support fonc1006

CREATE TYPE

tion_entre et fonction_sortie sont obligatoires. Les fonctions fonction_rception, fonction_envoi,


type_modifier_input_function, type_modifier_output_function et fonction_analyse sont optionnelles. Gnralement, ces fonctions sont codes en C ou dans un autre langage de bas niveau.
La fonction_entre convertit la reprsentation textuelle externe du type en reprsentation interne utilise par les oprateurs
et fonctions dfinis pour le type. La fonction_sortie ralise la transformation inverse. La fonction entre peut tre dclare
avec un argument de type cstring ou trois arguments de types cstring, oid, integer. Le premier argument est le texte en entre sous
la forme d'une chane C, le second argument est l'OID du type (sauf dans le cas des types tableau o il s'agit de l'OID du type de
l'lment) et le troisime est le typmod de la colonne destination, s'il est connu (-1 sinon). La fonction entre doit renvoyer une
valeur du nouveau type de donnes. Habituellement, une fonction d'entre devrait tre dclare comme STRICT si ce n'est pas le
cas, elle sera appele avec un premier paramtre NULL la lecture d'une valeur NULL en entre. La fonction doit toujours envoyer NULL dans ce cas, sauf si une erreur est rapporte. (Ce cas a pour but de supporter les fonctions d'entre des domaines qui
ont besoin de rejeter les entres NULL.) La fonction sortie doit prendre un argument du nouveau type de donnes, et retourner le
type cstring. Les fonctions sortie ne sont pas appeles pour des valeurs NULL.
La fonction_rception, optionnelle, convertit la reprsentation binaire externe du type en reprsentation interne. Si cette
fonction n'est pas fournie, le type n'accepte pas d'entre binaire. La reprsentation binaire est choisie de telle sorte que sa conversion en forme interne soit peu coteuse, tout en restant portable. (Par exemple, les types de donnes standard entiers utilisent
l'ordre rseau des octets comme reprsentation binaire externe alors que la reprsentation interne est dans l'ordre natif des octets de
la machine.) La fonction de rception ralise les vrifications adquates pour s'assurer que la valeur est valide. Elle peut tre dclare avec un argument de type internal ou trois arguments de types internal, integer et oid. Le premier argument est un pointeur
vers un tampon StringInfo qui contient la chane d'octets reue ; les arguments optionnels sont les mmes que pour la fonction entre de type texte. La fonction de rception retourne une valeur du type de donnes. Habituellement, une fonction de rception devrait tre dclare comme STRICT si ce n'est pas le cas, elle sera appele avec un premier paramtre NULL la lecture d'une valeur NULL en entre. La fonction doit toujours envoyer NULL dans ce cas, sauf si une erreur est rapporte. (Ce cas a pour but de
supporter les fonctions de rception des domaines qui ont besoin de rejeter les entres NULL.) De faon similaire, la fonction_envoi, optionnelle, convertit la reprsentation interne en reprsentation binaire externe. Si cette fonction n'est pas fournie,
le type n'accepte pas de sortie binaire. La fonction d'envoi doit tre dclare avec un argument du nouveau type de donnes et retourner le type bytea. Les fonctions rception ne sont pas appeles pour des valeurs NULL.
ce moment-l, vous pouvez vous demander comment les fonctions d'entre et de sortie peuvent tre dclares avoir un rsultat
ou un argument du nouveau type alors qu'elles sont crer avant que le nouveau type ne soit cr. La rponse est que le type sera
tout d'abord dfini en tant que type squelette (shell type), une bauche de type sans proprit part un nom et un propritaire. Ceci
se fait en excutant la commande CREATE TYPE nom sans paramtres supplmentaires. Ensuite, les fonctions d'entre/sortie
peuvent tre dfinies en rfrenant le squelette. Enfin, le CREATE TYPE avec une dfinition complte remplace le squelette
avec une dfinition complte et valide du type, aprs quoi le nouveau type peut tre utilis normalement.
Les fonctions optionnelles type_modifier_input_function et type_modifier_output_function sont ncessaires si le type supporte des modificateurs, c'est--dire des contraintes optionnelles attaches une dclaration de type comme
char(5) ou numeric(30,2). PostgreSQL autorise les types dfinis par l'utilisateur prendre une ou plusieurs constantes
ou identifiants comme modifieurs ; nanmoins, cette information doit tre capable d'tre englobe dans une seule valeur entire
positive pour son stockage dans les catalogues systme. type_modifier_input_function se voit fourni le modifieur dclar de la forme d'un tableau de cstring. Il doit vrifier la validit des valeurs et renvoyer une erreur si elles sont invalides. Dans
le cas contraire, il renvoie une valeur entire postivequi sera stocke dans la colonne typmod . Les modifieurs de type seront rejets si le type n'a pas de type_modifier_input_function. type_modifier_output_function convertit la valeur
typmod integer en une forme correcte pour l'affichage. Il doit renvoyer une valeur de type cstring qui est la chane exacte ajouter
au nom du type ; par exemple la fonction de numeric pourrait renvoyer (30,2). Il est permis d'omettre le
type_modifier_output_function, auquel cas le format d'affichage par dfaut est simplement la valeur typmod stocke
entre parenthses.
La fonction_analyse, optionnelle, calcule des statistiques spcifiques au type de donnes pour les colonnes de ce type. Par
dfaut, ANALYZE tente de rcuprer des statistiques l'aide des oprateurs d' galit et d' infriorit du type, s'il existe une
classe d'oprateur B-tree par dfaut pour le type. Ce comportement est inadapt aux types non-scalaires ; il peut tre surcharg
l'aide d'une fonction d'analyse personnalise. La fonction d'analyse doit tre dclare avec un seul argument de type internal et un
rsultat de type boolean. L'API dtaille des fonctions d'analyses est prsente dans src/include/commands/vacuum.h.
Alors que les dtails de la reprsentation interne du nouveau type ne sont connus que des fonctions d'entres/sorties et des fonctions utilisateurs d'interaction avec le type, plusieurs proprits de la reprsentation interne doivent tre dclares PostgreSQL.
La premire est longueurinterne. Les types de donnes basiques peuvent tre de longueur fixe (dans ce cas, longueurinterne est un entier positif) ou de longueur variable (indique par le positionnement de longueurinterne VARIABLE ; en
interne, cela est reprsent en initialisant typlen -1). La reprsentation interne de tous les types de longueur variable doit commencer par un entier de quatre octets indiquant la longueur totale de cette valeur.
Le drapeau optionnel PASSEDBYVALUE indique que les valeurs de ce type de donnes sont passes par valeur plutt que par rfrence. Les types dont la reprsentation interne est plus grande que la taille du type Datum (quatre octets sur la plupart des machines, huit sur quelques-unes) ne doivent pas tre passs par valeur.
1007

CREATE TYPE

Le paramtre alignement spcifie l'alignement de stockage requis pour le type de donnes. Les valeurs permises sont des alignements sur 1, 2, 4 ou 8 octets. Les types de longueurs variables ont un alignement d'au moins quatre octets car leur premier
composant est ncessairement un int4.
Le paramtre stockage permet de choisir une stratgie de stockage pour les types de donnes de longueur variable. (Seul
plain est autoris pour les types de longueur fixe.) plain indique des donnes stockes en ligne et non compresses. Dans le
cas d'extended le systme essaie tout d'abord de compresser une valeur longue et dplace la valeur hors de la ligne de la table
principale si elle est toujours trop longue. external permet la valeur d'tre dplace hors de la table principale mais le systme ne tente pas de la compresser. main autorise la compression mais ne dplace la valeur hors de la table principale qu'en dernier recours. (Ils seront dplacs s'il n'est pas possible de placer la ligne dans la table principale, mais sont prfrentiellement
conservs dans la table principale, contrairement aux lments extended et external.)
Le paramtre type_like fournit une mthode alternative pour spcifier les proprits de reprsentation de base d'un type de
donnes : les copier depuis un type existant. Les valeurs de longueurinterne, passedbyvalue, alignement et stockage sont copies du type indiqu. (C'est possible, mais habituellement non souhait, d'craser certaines de ces valeurs en les
spcifiant en mme temps que la clause LIKE.) Spcifier la reprsentation de cette faon est particulirement pratique quand
l'implmentation de bas niveau du nouveau type emprunte celle d'un type existant d'une faon ou d'une autre.
Les paramtres catgorie et prfr peuvent tre utiliss pour aider contrler la conversion implicite applique en cas
d'ambigut. Chaque type de donnes appartient une catgorie identifie par un seul caractre ASCII, et chaque type est
prfr ou pas de sa catgorie. L'analyseur prfrera convertir vers des types prfrs (mais seulement partir d'autres types
dans la mme catgorie) quand cette rgle peut servir rsoudre des fonctions ou oprateurs surchargs. Pour plus de dtails, voir
Chapitre 10, Conversion de types. Pour les types qui n'ont pas de conversion implicite de ou vers d'autres types, on peut se contenter de laisser ces paramtres aux valeurs par dfaut. Par contre, pour un groupe de types lis entre eux qui ont des conversions implicites, il est souvent pratique de les marquer tous comme faisant partie d'une mme catgorie, et de choisir un ou deux des types
les plus gnraux comme tant les types prfrs de la catgorie. Le paramtre catgorie est particulirement utile quand
on ajoute un type dfini par l'utilisateur un type interne, comme un type numrique ou chane. Toutefois, c'est aussi tout fait
possible de crer des catgories de types entirement nouvelles. Choisissez un caractre ASCII autre qu'une lettre en majuscule
pour donner un nom une catgorie de ce genre.
Une valeur par dfaut peut tre spcifie dans le cas o l'utilisateur souhaite que cette valeur soit diffrente de NULL pour les colonnes de ce type. La valeur par dfaut est prcise l'aide du mot cl DEFAULT. (Une telle valeur par dfaut peut tre surcharge
par une clause DEFAULT explicite attache une colonne particulire.)
Pour indiquer qu'un type est un tableau, le type des lments du tableau est prcis par le mot cl ELEMENT. Par exemple, pour
dfinir un tableau d'entiers de quatre octets (int4), ELEMENT = int4 est utilis. Plus de dtails sur les types tableau apparaissent ci-dessous.
Pour prciser le dlimiteur de valeurs utilis dans la reprsentation externe des tableaux de ce type, dlimiteur peut tre positionn un caractre particulier. Le dlimiteur par dfaut est la virgule (,). Le dlimiteur est associ avec le type lment de tableau, pas avec le type tableau.
Si le paramtre boolen optionnel collatable vaut true, les dfinitions et expressions de colonnes du type peuvent embarquer
une information de collationnement via la clause COLLATE. C'est aux implmentations des fonctions du type de faire bon usage
de cette information. Cela n'arrive pas automatiquement en marquant le type collationnable.

Types tableau
chaque fois qu'un type dfini par un utilisateur est cr, PostgreSQL cre automatiquement un type tableau associ dont le
nom est compos partir du type de base prfix d'un tiret bas et tronqu si ncessaire pour que le nom gnr fasse moins de NAMEDATALEN octets. (Si le nom gnr est en conflit avec un autre nom, le traitement est rpt jusqu' ce qu'un nom sans
conflit soit trouv.) Ce type tableau cr implicitement est de longueur variable et utilise les fonctions d'entre et sortie array_in et array_out. Le type tableau trace tout changement dans du type de base pour le propritaire et le schma. Il est aussi
supprim quand le type de base l'est.
Pourquoi existe-t-il une option ELEMENT si le systme fabrique automatiquement le bon type tableau ? La seule utilit d'ELEMENT est la cration d'un type de longueur fixe reprsent en interne par un tableau d'lments identiques auxquels on souhaite accder directement par leurs indices (en plus de toute autre opration effectue sur le type dans sa globalit). Par exemple, le type
point est reprsent par deux nombres virgule flottante, qui sont accessibles par point[0] et point[1]. Cette fonctionnalit
n'est possible qu'avec les types de longueur fixe dont la forme interne est strictement une squence de champs de longueur fixe.
Un type de longueur variable est accessible par ses indices si sa reprsentation interne gnralise est celle utilise par array_in
et array_out. Pour des raisons historiques (c'est--dire pour de mauvaises raisons, mais il est trop tard pour changer) les indices
des tableaux de types de longueur fixe commencent zro et non un comme c'est le cas pour les tableaux de longueur variable.

Paramtres
1008

CREATE TYPE

nom
Le nom (ventuellement qualifi du nom du schma) du type crer.
nom_attribut
Le nom d'un attribut (colonne) du type composite.
type_donnes
Le nom d'un type de donnes existant utilis comme colonne du type composite.
label
Une chane reprsentant le label associ une valeur du type enum.
fonction_entre
Le nom d'une fonction de conversion des donnes de la forme textuelle externe du type en forme interne.
fonction_sortie
Le nom d'une fonction de conversion des donnes de la forme interne du type en forme textuelle externe.
fonction_rception
Le nom d'une fonction de conversion des donnes de la forme binaire externe du type en forme interne.
fonction_envoi
Le nom d'une fonction de conversion des donnes de la forme interne du type en forme binaire externe.
type_modifier_input_function
Le nom d'une fonction qui convertit un tableau de modifieurs pour le type vers sa forme interne.
type_modifier_output_function
Le nom d'une fonction qui convertit la forme interne des modifieurs du type vers leur forme textuelle externe.
analyze_function
Le nom d'une fonction d'analyses statistiques pour le type de donnes.
longueurinterne
Une constante numrique qui prcise la longueur en octets de la reprsentation interne du nouveau type. Suppose variable
par dfaut.
alignement
La spcification d'alignement du stockage du type de donnes. Peut tre char, int2, int4 ou double ; int4 par dfaut.
stockage
La stratgie de stockage du type de donnes. Peut tre plain, external, extended ou main ; plain par dfaut.
type_like
Le nom d'un type de donnes existant dont le nouveau type partagera la reprsentation. Les valeurs de longueurinterne,
passedbyvalue, alignement et stockage sont recopies partir de ce type, sauf si elles sont crases explicitement
ailleurs dans la mme commande CREATE TYPE.
catgorie
Le code de catgorie (un unique caractre ASCII) pour ce type. La valeur par dfaut est U pour user-defined type (type dfini par l'utilisateur). Les autres codes standard de catgorie peuvent tre trouvs dans Tableau 45.49, Codes typcategory . Vous pouvez aussi choisir d'autres caractres ASCII pour crer vos propres catgories personnalises.
prfr
True si ce type est un type prfr dans sa catgorie de types, sinon false. La valeur par dfaut est false. Faites trs attention
en crant un nouveau type prfr l'intrieur d'une catgorie existante car cela pourrait crer des modifications surprenantes
de comportement.
dfaut
La valeur par dfaut du type de donnes. Omise, elle est NULL.
lment
Type des lments du type tableau cr.
dlimiteur
Le caractre dlimiteur des valeurs des tableaux de ce type.
collatable
Vrai si les oprations de ce type peuvent utiliser les informations de collationnement. Par dfaut, faux.

1009

CREATE TYPE

Notes
Comme il n'y a pas de restrictions l'utilisation d'un type de donnes une fois qu'il a t cr, crer un type de base est quivalent
donner les droits d'excution ssur les fonctions mentionnes dans la dfinition du type. Ce n'est pas un problme habituellement
pour le genre de fonctions utiles dans la dfinition d'un type mais rflchissez bien avant de concevoir un type d'une faon qui ncessiterait que des informations secrtes soient utilises lors de sa convertion vers ou partir d'une forme externe.
Avant PostgreSQL version 8.3, le nom d'un type tableau gnr tait toujours exactement le nom du type lment avec un caractre tiret bas (_) en prfixe. (Les noms des types taient du coup limits en longueur un caractre de moins que les autres
noms.) Bien que cela soit toujours le cas, le nom d'un type tableau peut varier entre ceci dans le cas des noms de taille maximum
et les collisions avec des noms de type utilisateur qui commencent avec un tiret bas. crire du code qui dpend de cette convention
est du coup obsolte. la place, utilisez pg_type.typarray pour situer le type tableau associ avec un type donn.
Il est conseill d'viter d'utiliser des noms de table et de type qui commencent avec un tiret bas. Alors que le serveur changera les
noms des types tableau gnrs pour viter les collisions avec les noms donns par un utilisateur, il reste toujours un risque de
confusion, particulirement avec les anciens logiciels clients qui pourraient supposer que les noms de type commenant avec un tiret bas reprsentent toujours des tableaux.
Avant PostgreSQL version 8.2, la syntaxe CREATE TYPE nom n'existait pas. La faon de crer un nouveau type de base tait
de crer en premier les fonctions paramtres. Dans cette optique, PostgreSQL verra tout d'abord le nom d'un nouveau type de
donnes comme type de retour de la fonction en entre. Le type shell est cr implicitement dans ce cas et il est ensuite rfrenc
dans le reste des fonctions d'entre/sortie. Cette approche fonctionne toujours mais est obsolte et pourrait tre interdite dans une
version future. De plus, pour viter de faire grossir les catalogues de faon accidentelle avec des squelettes de type errons, un
squelette sera seulement cr quand la fonction en entre est crit en C.
Dans les versions de PostgreSQL antrieures la 7.3, la cration d'un type coquille tait habituellement vite en remplaant les
rfrences des fonctions au nom du type par le pseudotype opaque. Les arguments cstring et les rsultats taient galement dclars opaque. Pour supporter le chargement d'anciens fichiers de sauvegarde, CREATE TYPE accepte les fonctions
d'entres/sorties dclares avec le pseudotype opaque mais un message d'avertissement est affich. La dclaration de la fonction
est galement modifie pour utiliser les bons types.

Exemples
Crer un type composite utilis dans la dfinition d'une fonction :
CREATE TYPE compfoo AS (f1 int, f2 text);
CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$
SELECT fooid, fooname FROM foo
$$ LANGUAGE SQL;
Cet exemple cre un type numr et l'utilise dans la cration d'une table :
CREATE TYPE statut_bogue AS ENUM ('nouveau', 'ouvert', 'ferm');
CREATE TABLE bogue (
id serial,
description text,
status statut_bogue
);
Crer le type de donnes basique box utilis dans la dfinition d'une table :
CREATE TYPE box;
CREATE FUNCTION ma_fonction_entree_box(cstring) RETURNS box AS ... ;
CREATE FUNCTION ma_fonction_sortie_box(box) RETURNS cstring AS ... ;
CREATE TYPE box (
INTERNALLENGTH = 16,
INPUT = ma_fonction_entree_box,
OUTPUT = ma_fonction_sortie_box
);
CREATE TABLE myboxes (
id integer,
description box
);
1010

CREATE TYPE

Si la structure interne de box est un tableau de quatre lments float4, on peut crire :
CREATE TYPE box (
INTERNALLENGTH = 16,
INPUT = ma_fonction_entree_box,
OUTPUT = ma_fonction_sortie_box,
ELEMENT = float4
);
ce qui permet d'accder aux nombres composant la valeur d'une bote par les indices. Le comportement du type n'est pas modifi.
Crer un objet large utilis dans la dfinition d'une table :
CREATE TYPE bigobj (
INPUT = lo_filein, OUTPUT = lo_fileout,
INTERNALLENGTH = VARIABLE
);
CREATE TABLE big_objs (
id integer,
obj bigobj
);
D'autres exemples, intgrant des fonctions utiles d'entre et de sortie, peuvent tre consults dans Section 35.11, Types utilisateur .

Compatibilit
La premire forme de la commande CREATE TYPE, qui cre un type composite, est conforme au standard SQL. Les autres
formes sont des extensions de PostgreSQL. L'instruction CREATE TYPE du standard SQL dfinit aussi d'autres formes qui ne
sont pas implmentes dans PostgreSQL.
La possibilit de crer un type composite sans attributs est une diffrence spcifique de PostgreSQL que le standard ne propose
pas (de faon analogue au CREATE TABLE).

Voir aussi
ALTER TYPE(7), CREATE DOMAIN(7), CREATE FUNCTION(7), DROP TYPE(7)

1011

Nom
CREATE USER Dfinir un nouveau rle de base de donnes

Synopsis
CREATE USER nom [ [ WITH ] option [ ... ] ]
o option peut tre :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

SUPERUSER | NOSUPERUSER
CREATEDB | NOCREATEDB
CREATEROLE | NOCREATEROLE
CREATEUSER | NOCREATEUSER
INHERIT | NOINHERIT
LOGIN | NOLOGIN
REPLICATION | NOREPLICATION
CONNECTION LIMIT limite_connexion
[ ENCRYPTED | UNENCRYPTED ] PASSWORD 'motdepasse'
VALID UNTIL 'dateheure'
IN ROLE nom_role [, ...]
IN GROUP nom_role [, ...]
ROLE nom_role [, ...]
ADMIN nom_role [, ...]
USER nom_role [, ...]
SYSID uid

Description
CREATE USER est dornavant un alias de CREATE ROLE(7). Il y a toutefois une petite diffrence entre les deux commandes. Lorsque la commande CREATE USER est xcute, LOGIN est le comportement par dfaut. Au contraire, quand
CREATE ROLE est excute, NOLOGIN est utilis.

Compatibilit
L'instruction CREATE USER est une extension PostgreSQL. Le standard SQL laisse la dfinition des utilisateurs
l'implantation.

Voir aussi
CREATE ROLE(7)

1012

Nom
CREATE USER MAPPING Dfinir une nouvelle correspondance d'utilisateur (user mapping) pour un serveur distant

Synopsis
CREATE USER MAPPING FOR { nom_utilisateur | USER | CURRENT_USER | PUBLIC }
SERVER nom_serveur
[ OPTIONS ( option 'valeur' [ , ... ] ) ]

Description
CREATE USER MAPPING dfinit une nouvelle correspondance d'utilisateur (user mapping) pour un serveur distant. Une
correspondance d'utilisateur englobe typiquement les informations de connexion qu'un wrapper de donnes distantes utilise avec
l'information d'un serveur distant pour accder des ressources externes de donnes.
Le propritaire d'un serveur distant peut crer des correspondances d'utilisateur pour ce serveur pour n'importe quel utilisateur.
Par ailleurs, un utilisateur peut crer une correspondance d'utilisateur pour son propre nom d'utilisateur si le droit USAGE a t
donn sur le serveur son utilisateur.

Paramtres
nom_utilisateur
Le nom d'un utilisateur existant qui est mis en correspondance sur un serveur distant. CURRENT_USER et USER correspondent au nom de l'utilisateur courant. Quand PUBLIC est ajoute, une correspondance appele publique est cre pour
tre utilise quand aucune correspondance d'utilisateur spcifique n'est applicable.
nom_serveur
Le nom d'un serveur existant pour lequel la correspondance d'utilisateur sera cre.
OPTIONS ( option 'valeur' [, ... ] )
Cette clause dfinit les options pour la correspondance d'utilisateurs. Les options dfinissent typiquement le nom et le mot
de passe rels de la correspondance. Les nom d'options doivent tre uniques. Les noms et valeurs d'options autoriss sont
propres au wrapper de donnes trangre du serveur.

Exemples
Crer une correspondance d'utilisateur pour l'utilisateur bob, sur le serveur truc :
CREATE USER MAPPING FOR bob SERVER truc OPTIONS (user 'bob', password 'secret');

Compatibilit
CREATE USER MAPPING est conforme la norme ISO/IEC 9075-9 (SQL/MED).

Voir aussi
ALTER USER MAPPING(7), DROP USER MAPPING(7), CREATE FOREIGN DATA WRAPPER(7), CREATE SERVER(7)

1013

Nom
CREATE VIEW Dfinir une vue

Synopsis
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW nom [ ( nom_colonne [, ...] ) ]
AS requte

Description
CREATE VIEW dfinit une vue d'aprs une requte. La vue n'est pas matrialise physiquement. Au lieu de cela, la requte est
lance chaque fois qu'une vue est utilise dans une requte.
CREATE OR REPLACE VIEW a la mme finalit, mais si une vue du mme nom existe dj, elle est remplace. La nouvelle
requte doit gnrer les mmes colonnes que celles de l'ancienne requte (c-est--dire les mmes noms de colonnes dans le
mme ordre avec les mmes types de donnes). Par contre, elle peut ajouter des colonnes supplmentaires en fin de liste. Les
traitements qui donnent les colonnes en sortie pourraient tre compltement diffrents.
Si un nom de schma est donn (par exemple CREATE VIEW monschema.mavue ...), alors la vue est cre dans ce
schma. Dans le cas contraire, elle est cre dans le schma courant. Les vues temporaires existent dans un schma spcial. Il
n'est donc pas ncessaire de fournir de schma pour les vues temporaires. Le nom de la vue doit tre diffrent du nom de toute
autre vue, table, squence, index ou table distante du mme schma.

Paramtres
TEMPORARY ou TEMP
La vue est temporaire. Les vues temporaires sont automatiquement supprimes en fin de session. Les relations permanentes
qui portent le mme nom ne sont plus visibles pour la session tant que la vue temporaire existe, sauf s'il y est fait rfrence
avec le nom du schma.
Si l'une des tables rfrences par la vue est temporaire, la vue est alors elle-aussi temporaire (que TEMPORARY soit spcifi ou non).
nom
Le nom de la vue crer (ventuellement qualifi du nom du schma).
nom de colonne
Une liste optionnelle de noms utiliser pour les colonnes de la vue. Si elle n'est pas donne, le nom des colonnes est dduit
de la requte.
requte
Une commande SELECT(7) ou VALUES(7) qui fournira les colonnes et lignes de la vue.

Notes
Actuellement, les vues sont en lecture seule : le systme n'autorise pas une insertion, une mise jour ou une suppression sur une
vue. Les effets d'une vue actualisable peuvent tre reproduits par la cration de triggers INSTEAD sur la vue, qui devront transformer les insertions (ou autres) tentes sur la vue en actions appropries sur les autres tables. Voir CREATE TRIGGER(7) pour
plus d'informations. Une autre possibilit revient crer des rgles (voir CREATE RULE(7)). En pratique, il est plus facile de
comprendre et d'utiliser correctement les triggers.
L'instruction DROP VIEW(7) est utilise pour supprimer les vues.
Il est important de s'assurer que le nom et le type des colonnes de la vue correspondent ce qui est souhait. Ainsi :
CREATE VIEW vista AS SELECT 'Hello World';
prsente deux dfauts majeurs : le nom de la colonne prend la valeur implicite ?column? et son type de donnes le type implicite unknown. Pour obtenir une chane de caractres dans le rsultat de la vue, on peut crire :
CREATE VIEW vista AS SELECT text 'Hello World' AS hello;
L'accs aux tables rfrences dans la vue est dtermin par les droits du propritaire de la vue. Dans certains cas, cela peut tre
utilis pour fournir un accs scuris. Cependant, toutes les vues ne sont pas scurisables ; voir Section 37.4, Rgles et droits
pour des dtails. Les fonctions appeles dans la vue sont traites de la mme faon que si elles avaient t appeles directement
1014

CREATE VIEW

dans la requte utilisant la vue. Du coup, l'utilisateur d'une vue doit avoir les droits pour appeler toutes les fonctions utilises par la
vue.
Quand CREATE OR REPLACE VIEW est utilis sur une vue existante, seule la rgle SELECT dfinissant la vue est modifie.
Les autres proprits, comme les droits, le propritaire et les rgles autres que le SELECT, ne sont pas modifies. Vous devez tre
le propritaire de la vue pour la remplacer (ceci incluant aussi les membres du rle propritaire).

Exemples
Crer une vue compose des comdies :
CREATE VIEW comedies AS
SELECT *
FROM films
WHERE genre = 'Comdie';
Cette requte cre une vue contenant les colonnes de la table film au moment de la cration de la vue. Bien que l'toile (*) soit
utilise pour crer la vue, les colonnes ajoutes par la suite la table film ne feront pas partie de la vue.

Compatibilit
Le standard SQL spcifie quelques possibilits supplmentaires pour l'instruction CREATE VIEW :
CREATE VIEW nom [ ( nom_colonne [, ...] ) ]
AS requte
[ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
Les clauses optionnelles de la commande SQL complte sont :
CHECK OPTION
Cette option concerne les vues actualisables. Toutes les commandes INSERT et UPDATE appliques la vue sont contrles pour s'assurer que les donnes satisfont les conditions de dfinition de la vue (les nouvelles donnes sont visibles au travers de la vue). Si ce n'est pas le cas, la mise jour est rejete.
LOCAL
Contrle d'intgrit de la vue.
CASCADED
Contrle d'intgrit de la vue et de toutes les vues dpendantes. CASCADED est implicite si ni CASCADED ni LOCAL ne sont
prciss.
CREATE OR REPLACE VIEW est une extension PostgreSQL, tout comme le concept de vue temporaire.

Voir aussi
ALTER VIEW(7), DROP VIEW(7)

1015

Nom
DEALLOCATE Dsaffecter (librer) une instruction prpare

Synopsis
DEALLOCATE [ PREPARE ] { nom | ALL }

Description
DEALLOCATE est utilis pour dsaffecter une instruction SQL prpare prcdemment. Une instruction prpare qui n'est pas
explicitement libre l'est automatiquement en fin de session.
Pour plus d'informations sur les instructions prpares, voir PREPARE(7).

Paramtres
PREPARE
Mot cl ignor.
nom
Le nom de l'instruction prpare dsaffecter.
ALL
Dsaffecte toutes les instructions prpares.

Compatibilit
Le standard SQL inclut une instruction DEALLOCATE qui n'est utilise que pour le SQL imbriqu.

Voir aussi
EXECUTE(7), PREPARE(7)

1016

Nom
DECLARE Dfinir un curseur

Synopsis
DECLARE nom [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]
CURSOR [ { WITH | WITHOUT } HOLD ] FOR requte

Description
DECLARE permet un utilisateur de crer des curseurs. Ils peuvent tre utiliss pour rcuprer un petit nombre de lignes la
fois partir d'une requte plus importante. Aprs la cration du curseur, les lignes sont rcupres en utilisant FETCH(7).

Note
Cette page dcrit l'utilisation des curseurs au niveau de la commande SQL. Si vous voulez utiliser des curseurs
dans une fonction PL/pgSQL, les rgles sont diffrentes -- voir Section 39.7, Curseurs .

Paramtres
nom
Le nom du curseur crer.
BINARY
Le curseur retourne les donnes au format binaire.
INSENSITIVE
Les donnes rcupres partir du curseur ne doivent pas tre affectes par les mises jour des tables concernes par le
curseur qui surviennent une fois que ce dernier est cr. Dans PostgreSQL, c'est le comportement par dfaut ; ce mot-cl
n'a aucun effet. Il est seulement accept pour des raisons de compatibilit avec le standard SQL.
SCROLL, NO SCROLL
SCROLL indique une utilisation possible du curseur pour rcuprer des lignes de faon non squentielle (c'est--dire en remontant la liste). En fonction de la complexit du plan d'excution de la requte, SCROLL peut induire des pertes de performance sur le temps d'excution de la requte. NO SCROLL indique que le curseur ne peut pas tre utilis pour rcuprer
des lignes de faon non squentielle. La valeur par dfaut autorise la non-squentialit du curseur dans certains cas ; ce n'est
pas la mme chose que de spcifier SCROLL. Voir la section intitule Notes pour les dtails.
WITH HOLD, WITHOUT HOLD
WITH HOLD (NDT : persistant) indique une utilisation possible du curseur aprs la validation de la transaction qui l'a cr.
WITHOUT HOLD (NDT : volatil) interdit l'utilisation du curseur en dehors de la transaction qui l'a cr. WITHOUT HOLD
est la valeur par dfaut.
requte
Une commande SELECT(7) ou VALUES(7) qui fournira les lignes renvoyer par le curseur.
Les mots cls BINARY, INSENSITIVE et SCROLL peuvent apparatre dans n'importe quel ordre.

Notes
Les curseurs normaux renvoient les donnes au format texte, le mme que produirait un SELECT. L'option BINARY spcifie
que le curseur doit renvoyer les donnes au format binaire. Ceci rduit les efforts de conversion pour le serveur et le client, au
cot d'un effort particulier de dveloppement pour la gestion des formats de donnes binaires dpendants des plateformes.
Comme exemple, si une requte renvoie une valeur de un dans une colonne de type integer, vous obtiendrez une chane 1 avec
un curseur par dfaut. Avec un curseur binaire, vous obtiendrez un champ sur quatre octet contenant la reprsentation interne de
la valeur (dans l'ordre big-endian).
Les curseurs binaires doivent tre utiliss en faisant trs attention. Beaucoup d'applications, incluant psql, ne sont pas prpares
grer des curseurs binaires et s'attendent ce que les donnes reviennent dans le format texte.

Note
1017

DECLARE

Quand l'application cliente utilise le protocole des requtes tendues pour excuter la commande FETCH, le
message Bind du protocole spcifie si les donnes sont rcuprer au format texte ou binaire. Ce choix surcharge
la faon dont le curseur est dfini. Le concept de curseur binaire est donc obsolte lors de l'utilisation du protocole
des requtes tendues -- tout curseur peut tre trait soit en texte soit en binaire.
Si la clause WITH HOLD n'est pas prcise, le curseur cr par cette commande ne peut tre utilis qu' l'intrieur d'une transaction. Ainsi, DECLARE sans WITH HOLD est inutile l'extrieur d'un bloc de transaction : le curseur survivrait seulement jusqu'
la fin de l'instruction. PostgreSQL rapporte donc une erreur si cette commande est utilise en dehors d'un bloc de transactions.
On utilise BEGIN(7) et COMMIT(7) (ou ROLLBACK(7)) pour dfinir un bloc de transaction.
Si la clause WITH HOLD est prcise, et que la transaction qui a cr le curseur est valide, ce dernier reste accessible par les transactions ultrieures de la session. Au contraire, si la transaction initiale est annule, le curseur est supprim. Un curseur cr avec
la clause WITH HOLD est ferm soit par un appel explicite la commande CLOSE, soit par la fin de la session. Dans
l'implantation actuelle, les lignes reprsentes par un curseur persistant (WITH HOLD) sont copies dans un fichier temporaire ou
en mmoire afin de garantir leur disponibilit pour les transactions suivantes.
WITH HOLD n'est pas utilisable quand la requte contient dj FOR UPDATE ou FOR SHARE.
L'option SCROLL est ncessaire la dfinition de curseurs utiliss en rcupration remontante (retour dans la liste des rsultats,
backward fetch), comme prcis par le standard SQL. Nanmoins, pour des raisons de compatibilit avec les versions antrieures,
PostgreSQL autorise les rcuprations remontantes sans que l'option SCROLL ne soit prcis, sous rserve que le plan
d'excution du curseur soit suffisamment simple pour tre gr sans surcharge. Toutefois, il est fortement conseill aux dveloppeurs d'application ne pas utiliser les rcuprations remontantes avec des curseurs qui n'ont pas t crs avec l'option SCROLL. Si
NO SCROLL est spcifi, les rcuprations remontantes sont toujours dvalides.
Les parcours inverses sont aussi interdits lorsque la requte inclut les clauses FOR UPDATE et FOR SHARE ; donc SCROLL peut
ne pas tre indiqu dans ce cas.

Attention
Les curseurs scrollables et avec l'option WITH HOLD pourraient donner des rsultats inattendues s'ils font appel
des fonctions volatiles (voir Section 35.6, Catgories de volatilit des fonctions ). Quand une ligne prcdemment rcupre est de nouveau rcupre, la fonction pourrait tre r-excute, amenant peut-tre des rsultats diffrentes de la premire excution. Un contournement est de dclarer le curseur WITH HOLD et de valider la transaction avant de lire toute ligne de ce curseur. Cela forcera la sortie entire du cuseur tre matrialise dans un
stockage temporaire, pour que les fonctions volatiles soient excutes exactement une fois pour chaque ligne.
Si la requte du curseur inclut les clauses FOR UPDATE ou FOR SHARE, alors les lignes renvoyes sont verrouilles au moment
o elles sont rcupres, de la mme faon qu'une commande SELECT(7) standard avec ces options. De plus, les lignes renvoyes
seront les versions les plus jour ; du coup, ces options fournissent l'quivalent de ce que le standard SQL appelle un curseur
sensible . (Indiquer INSENSITIVE avec soit FOR UPDATE soit FOR SHARE est une erreur.)

Attention
Il est gnralement recommand d'utiliser FOR UPDATE si le curseur doit tre utilis avec UPDATE ... WHERE
CURRENT OF ou DELETE ... WHERE CURRENT OF. Utiliser FOR UPDATE empche les autres sessions de
modifier les lignes entre le moment o elles sont rcupres et celui o elles sont modifies. Sans FOR UPDATE,
une commande WHERE CURRENT OF suivante n'aura pas d'effet si la ligne a t modifie depuis la cration du
curseur.
Une autre raison d'utiliser FOR UPDATE est que, sans ce dernier, un appel suivant WHERE CURRENT OF pourrait chouer si la requte curseur ne rpond pas aux rgles du standard SQL d'tre mise jour simplement (en
particulier, le curseur doit rfrencer une seule table et ne pas utiliser de regroupement ou de tri comme ORDER
BY). Les curseurs qui ne peuvent pas tre mis jour pourraient fonctionner, ou pas, suivant les dtails du plan choisi ; dans le pire des cas, une application pourrait fonctionner lors des tests puis chouer en production.
La principale raison de ne pas utiliser FOR UPDATE avec WHERE CURRENT OF est si vous avez besoin que le
curseur soit dplaable ou qu'il soit insensible aux mises jour suivantes (c'est--dire qu'il continue afficher les
anciennes donnes). Si c'est un prrequis, faites trs attention aux problmes expliqus ci-dessus.
Le standard SQL ne mentionne les curseurs que pour le SQL embarqu. PostgreSQL n'implante pas l'instruction OPEN pour les
curseurs ; un curseur est considr ouvert sa dclaration. Nanmoins, ECPG, le prprocesseur de SQL embarqu pour PostgreSQL, supporte les conventions du standard SQL relatives aux curseurs, dont celles utilisant les instructions DECLARE et
OPEN.
1018

DECLARE

Vous pouvez voir tous les curseurs disponibles en excutant une requte sur la vue systme pg_cursors.

Exemples
Dclarer un curseur :
DECLARE liahona CURSOR FOR SELECT * FROM films;
Voir FETCH(7) pour plus d'exemples sur l'utilisation des curseurs.

Compatibilit
Le standard SQL indique que la sensibilit des curseurs aux mises jour en parallle des donnes rcupres est dpendante de
l'implantation par dfaut. Dans PostgreSQL, les curseurs n'ont pas ce comportement par dfaut, mais peuvent le devenir en
ajoutant FOR UPDATE. D'autres produits peuvent grer cela diffrement.
Le standard SQL n'autorise les curseurs que dans le SQL embarqu et dans les modules. PostgreSQL permet une utilisation interactive des curseurs.
Le standard SQL autorise les curseurs mettre jour les donnes d'une table. Tous les curseurs PostgreSQL sont en lecture
seule.
Les curseurs binaires sont une extension PostgreSQL.

Voir aussi
CLOSE(7), FETCH(7), MOVE(7)

1019

Nom
DELETE Supprimer des lignes d'une table

Synopsis
[ WITH [ RECURSIVE ] requte_with [, ...] ]
DELETE FROM [ ONLY ] table [ * ] [ [ AS ] alias ]
[ USING liste_using ]
[ WHERE condition | WHERE CURRENT OF nom_curseur ]
[ RETURNING * | expression_sortie [ [ AS ] output_name ] [, ...] ]

Description
DELETE supprime de la table spcifie les lignes qui satisfont la clause WHERE. Si la clause WHERE est absente, toutes les
lignes de la table sont supprimes. Le rsultat est une table valide, mais vide.

Astuce
TRUNCATE(7) est une extension PostgreSQL qui fournit un mcanisme plus rapide de suppression de
l'ensemble des lignes d'une table.
Il existe deux faons de supprimer des lignes d'une table en utilisant les informations d'autres tables de la base de donnes : les
sous-slections ou la spcification de tables supplmentaires dans la clause USING. La technique la plus approprie dpend des
circonstances.
La clause RETURNING optionnelle fait que DELETE calcule et renvoie le(s) valeur(s) base(s) sur chaque ligne en cours de
suppression. Toute expression utilisant les colonnes de la table et/ou les colonnes de toutes les tables mentionnes dans USING
peut tre calcule. La syntaxe de la liste RETURNING est identique celle de la commande SELECT.
Il est ncessaire de possder le droit DELETE sur la table pour en supprimer des lignes, et le droit SELECT sur toute table de la
clause USING et sur toute table dont les valeurs sont lues dans la condition.

Paramtres
requte_with
La clause WITH vous permet de spcifier une ou plusieurs sous-requtes qui peuvent tre rfrences par nom dans la requteDELETE. Voir Section 7.8, Requtes WITH (Common Table Expressions) et SELECT(7) pour les dtails.
table
Le nom (ventuellement qualifi du nom du schma) de la table dans laquelle il faut supprimer des lignes. Si ONLY est indiqu avant le nom de la table, les lignes supprimes ne concernent que la table nomme. Si ONLY n'est pas indique, les
lignes supprimes font partie de la table nomme et de ses tables filles. En option, * peut tre ajout aprs le nom de la
table pour indiquer explicitement que les tables filles doivent tre inclues.
alias
Un nom de substitution pour la table cible. Quand un alias est fourni, il cache compltement le nom rel de la table. Par
exemple, avec DELETE FROM foo AS f, le reste de l'instruction DELETE doit rfrencer la table avec f et non plus
foo.
liste_using
Une liste d'expressions de table, qui permet de faire apparatre des colonnes d'autres tables dans la condition WHERE. C'est
semblable la liste des tables utilises dans la clause la section intitule Clause FROM d'une instruction SELECT ; un
alias du nom d'une table peut ainsi tre utilis. La table cible ne doit pas tre prcise dans liste_using, sauf si une auto-jointure est envisage.
condition
Une expression retournant une valeur de type boolean. Seules les lignes pour lesquelles cette expression renvoie true seront supprimes.
nom_curseur
Le nom du curseur utiliser dans une condition WHERE CURRENT OF. La ligne supprimer est la dernire ligne rcupre avec ce curseur. Le curseur doit tre une requte sans regroupement sur la table cible du DELETE. Notez que WHERE
CURRENT OF ne peut pas se voir ajouter de condition boolenne. Voir DECLARE(7) pour plus d'informations sur
1020

DELETE

l'utilisation des curseurs avec WHERE CURRENT OF.


expression_sortie
Une expression calculer et renvoye par la commande DELETE aprs chaque suppression de ligne. L'expression peut utiliser tout nom de colonne de la table ou des tables listes dans la clause USING. Indiquez * pour que toutes les colonnes
soient renvoyes.
nom_sortie
Un nom utiliser pour une colonne renvoye.

Sorties
En cas de succs, une commande DELETE renvoie une information de la forme
DELETE nombre
Le nombre correspond au nombre de lignes supprimes. Si nombre vaut 0, c'est qu'aucune ligne ne correspond condition
(ce qui n'est pas considr comme une erreur).
Si la commande DELETE contient une clause RETURNING, le rsultat sera similaire celui d'une instruction SELECT contenant les colonnes et les valeurs dfinies dans la liste RETURNING, partir de la liste des lignes supprimes par la commande.

Notes
PostgreSQL autorise les rfrences des colonnes d'autres tables dans la condition WHERE par la spcification des autres tables
dans la clause USING. Par exemple, pour supprimer tous les films produits par un producteur donn :
DELETE FROM films USING producteurs
WHERE id_producteur = producteurs.id AND producteurs.nom = 'foo';
Pour l'essentiel, une jointure est tablie entre films et producteurs avec toutes les lignes jointes marques pour suppression. Cette
syntaxe n'est pas standard. Une faon plus standard de procder consiste utiliser une sous-selection :
DELETE FROM films
WHERE id_producteur IN (SELECT id FROM producteur WHERE nom = 'foo');
Dans certains cas, la jointure est plus facile crire ou plus rapide excuter que la sous-slection.

Exemples
Supprimer tous les films qui ne sont pas des films musicaux :
DELETE FROM films WHERE genre <> 'Comdie musicale';
Effacer toutes les lignes de la table films :
DELETE FROM films;
Supprimer les tches termines tout en renvoyant le dtail complet des lignes supprimes :
DELETE FROM taches WHERE statut = 'DONE' RETURNING *;
Supprimer la ligne de taches sur lequel est positionn le curseur c_taches :
DELETE FROM taches WHERE CURRENT OF c_taches;

Compatibilit
Cette commande est conforme au standard SQL, l'exception des clauses USING et RETURNING, qui sont des extensions de
PostgreSQL, comme la possibilit d'utiliser la clause WITH avec DELETE.

1021

Nom
DISCARD Annuler l'tat de la session

Synopsis
DISCARD { ALL | PLANS | TEMPORARY | TEMP }

Description
DISCARD libre les ressources internes associes avec une session de la base de donnes. Ces ressources sont normalementlibrer la fin de la session.
DISCARD TEMP supprime toutes les tables temporaires cres pendant cette session. DISCARD PLANS libre tous les plans
internes de requte mis en cache. DISCARD ALL rinitialise une session son tat d'origine, supprimant ainsi les ressources
temporaires et rinitialisant les modifications locales de configuration de la session.

Paramtres
TEMPORARY or TEMP
Supprime toutes les tables temporaires cres pendant cette session.
PLANS
Libre tous les plans de requte mis en cache.
ALL
Libre les ressources temporaires associes cette session et rinitialise une session son tat d'origine. Actuellement, ceci
a le mme effet que la squence d'instructions suivantes :
SET SESSION AUTHORIZATION DEFAULT;
RESET ALL;
DEALLOCATE ALL;
CLOSE ALL;
UNLISTEN *;
SELECT pg_advisory_unlock_all();
DISCARD PLANS;
DISCARD TEMP;

Notes
DISCARD ALL ne peut pas tre utilis dans un bloc de transaction.

Compatibilit
DISCARD est une extension PostgreSQL.

1022

Nom
DO excute un bloc de code anonyme

Synopsis
DO [ LANGUAGE nom_langage ] code

Description
DO excute un bloc de code anonyme, autrement dit une fonction temporaire dans le langage de procdure indiqu.
Le bloc de code est trait comme le corps d'une fonction sans paramtre et renvoyant void. Il est analys et excut une seule
fois.
La clause LANGUAGE optionnelle est utilisable avant ou aprs le bloc de code.

Paramtres
code
Le code excuter. Il doit tre spcifi comme une chane litrale, tout comme une fonction CREATE FUNCTION.
L'utilisation de la syntaxe des guillemets dollar est recommande.
nom_langage
Le nom du langage utilis par le code. Par dfaut plpgsql.

Notes
Le langage de procdure utilis doit dj tre install dans la base de donnes avec l'instruction CREATE LANGUAGE.
plpgsql est install par dfaut contrairement aux autres langages.
L'utilisateur doit avoir le droit USAGE sur le langage de procdures ou tre un superutilisateur s'il ne s'agit pas d'un langage de
confiance. Il s'agit des mmes prrequis que pour la cration d'une fonction dans ce langage.

Exemples
Donner les droits sur toutes les vues du schma public au rle webuser :
DO $$DECLARE r record;
BEGIN
FOR r IN SELECT table_schema, table_name FROM information_schema.tables
WHERE table_type = 'VIEW' AND table_schema = 'public'
LOOP
EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' ||
quote_ident(r.table_name) || ' TO webuser';
END LOOP;
END$$;

Compatibilit
Il n'existe pas d'instruction DO dans le standard SQL.

Voir aussi
CREATE LANGUAGE(7)

1023

Nom
DROP AGGREGATE Supprimer une fonction d'agrgat

Synopsis
DROP AGGREGATE [ IF EXISTS ] nom ( type ) [ CASCADE | RESTRICT ]

Description
DROP AGGREGATE supprime une fonction d'agrgat. Pour excuter cette commande, l'utilisateur courant doit tre le propritaire de la fonction.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom (ventuellement qualifi du nom de schma) d'une fonction d'agrgat.
type
Un type de donnes en entre avec lequel la fonction d'agrgat opre. input data type on which the aggregate function operates. Pour rfrencer une fonction d'agrgat sans arguments, crivez * la place de la liste des types.
CASCADE
Les objets qui dpendent de la fonction d'agrgat sont automatiquement supprims.
RESTRICT
La fonction d'agrgat n'est pas supprime si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer la fonction d'agrgat mamoyenne pour le type integer :
DROP AGGREGATE mamoyenne(integer);

Compatibilit
Il n'existe pas d'instruction DROP AGGREGATE dans le standard SQL.

Voir aussi
ALTER AGGREGATE(7), CREATE AGGREGATE(7)

1024

Nom
DROP CAST Supprimer un transtypage

Synopsis
DROP CAST [ IF EXISTS ] (type_source AS type_cible) [ CASCADE | RESTRICT ]

Description
DROP CAST supprime un transtypage (conversion entre deux types de donnes) prcdemment dfini.
Seul le propritaire du type de donnes source ou cible peut supprimer un transtypage. Les mmes droits sont requis que pour la
cration d'un transtypage.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
type_source
Le nom du type de donnes source du transtypage.
type_cible
Le nom du type de donnes cible du transtypage.
CASCADE, RESTRICT
Ces mots cls n'ont pas d'effet car il n'y aucune dpendance dans les transtypages.

Exemples
Supprimer le transtypage du type text en type int :
DROP CAST (text AS int);

Compatibilit
La commande DROP CAST est conforme au standard SQL.

Voir aussi
CREATE CAST(7)

1025

Nom
DROP COLLATION supprime une collation

Synopsis
DROP COLLATION [ IF EXISTS ] nom [ CASCADE | RESTRICT ]

Description
DROP COLLATION supprime une collation que vous avez dfini auparavant. Pour pouvoir supprimer une collation, vous devez en tre propritaire.

Paramtres
IF EXISTS
Ne gnre pas d'erreur si la collation n'existe pas. Dans ce cas, un avertissement est gnr.
nom
Le nom de la collation. Le nom de la collation peut tre prfix par le schma.
CASCADE
Supprime automatiquement les objets qui sont dpendants de la collation.
RESTRICT
Refuse de supprimer la collection si un quelconque objet en dpend. C'est l'option par dfaut.

Exemples
Pour supprimer la collation nomme allemand:
DROP COLLATION allemand;

Compatibilit
La commande DROP COLLATION est conforme au standard SQL , sauf pour l'option IF EXISTS , qui est une extension
PostgreSQL.

Voir galement
ALTER COLLATION(7), CREATE COLLATION(7)

1026

Nom
DROP CONVERSION Supprimer une conversion

Synopsis
DROP CONVERSION [ IF EXISTS ] nom [ CASCADE | RESTRICT ]

Description
DROP CONVERSION supprime une conversion prcdemment dfinie. Seul son propritaire peut supprimer une conversion.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom de la conversion (ventuellement qualifi du nom de schma).
CASCADE, RESTRICT
Ces mots cls n'ont pas d'effet car il n'existe pas de dpendances sur les conversions.

Exemples
Supprimer la conversion nomme mon_nom :
DROP CONVERSION mon_nom;

Compatibilit
Il n'existe pas d'instruction DROP CONVERSION dans le standard SQL. Par contre, une instruction DROP TRANSLATION
est disponible. Elle va de paire avec l'instruction CREATE TRANSLATION qui est similaire l'instruction CREATE
CONVERSION de PostgreSQL.

Voir aussi
ALTER CONVERSION(7), CREATE CONVERSION(7)

1027

Nom
DROP DATABASE Supprimer une base de donnes

Synopsis
DROP DATABASE [ IF EXISTS ] nom

Description
La commande DROP DATABASE dtruit une base de donnes. Elle supprime les entres du catalogue pour la base et le rpertoire contenant les donnes. Elle ne peut tre excute que par le propritaire de la base de donnes ou le superutilisateur. De
plus, elle ne peut tre excute si quelqu'un est connect sur la base de donnes cible, y compris l'utilisateur effectuant la demande de suppression. (On peut se connecter postgres ou toute autre base de donnes pour lancer cette commande.)
DROP DATABASE ne peut pas tre annule. Il convient donc de l'utiliser avec prcaution !

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
name
Le nom de la base de donnes supprimer.

Notes
DROP DATABASE ne peut pas tre excute l'intrieur d'un bloc de transactions.
Cette commande ne peut pas tre excute en cas de connexion la base de donnes cible. Il peut paratre plus facile d'utiliser le
programme dropdb(1) la place, qui est un enrobage de cette commande.

Compatibilit
Il n'existe pas d'instruction DROP DATABASE dans le standard SQL.

Voir aussi
CREATE DATABASE(7), Variables d'environnement (Section 31.13, Variables d'environnement )

1028

Nom
DROP DOMAIN Supprimer un domaine

Synopsis
DROP DOMAIN [ IF EXISTS ] nom [, ...]

[ CASCADE | RESTRICT ]

Description
DROP DOMAIN supprime un domaine. Seul le propritaire d'un domaine peut le supprimer.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom (ventuellement qualifi du nom du schma) d'un domaine.
CASCADE
Les objets qui dpendent du domaine (les colonnes de table, par exemple) sont automatiquement supprims.
RESTRICT
Le domaine n'est pas supprim si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer le domaine boite :
DROP DOMAIN boite;

Compatibilit
Cette commande est conforme au standard SQL, l'exception de l'option IF EXISTS qui est une extension PostgreSQL.

Voir aussi
CREATE DOMAIN(7), ALTER DOMAIN(7)

1029

Nom
DROP EXTENSION Supprime une extension

Synopsis
DROP EXTENSION [ IF EXISTS ] extension_name [, ...] [ CASCADE | RESTRICT ]

Description
DROP EXTENSION supprime les extensions de la base de donnes. La suppression d'une extension entraine la suppression
des objets inclus dans l'extension.
Vous devez tre propritaire de l'extension pour utiliser DROP EXTENSION.

Paramtres
IF EXISTS
Permet de ne pas retourner d'erreur si l'extension n'existe pas. Une simple notice est alors rapporte.
extension_name
Le nom d'une extension pralablement installe.
CASCADE
Supprime automatiquement les objets dont dpend cette extension.
RESTRICT
Permet de spcifier que l'extension ne sera pas supprime si des objets en dpendent (des objets autres que ses propres objets et autres que les autres extensions supprimes simultanment dans la mme commande DROP). Il s'agit du comportement par dfaut.

Exemples
Pour supprimer l'extension hstore de la base de donnes en cours:
DROP EXTENSION hstore;
Cette commande va chouer si parmi les objets de hstore certains sont en cours d'utilisation sur la base de donnes. Par
exemple, si des tables ont des colonnes du type hstore. Dans ce cas de figure, ajoutez l'option cascade CASCADE pour forcer la
suppression de ces objets.

Compatibilit
DROP EXTENSION est une extension PostgreSQL.

Voir aussi
CREATE EXTENSION(7), ALTER EXTENSION(7)

1030

Nom
DROP FOREIGN DATA WRAPPER Supprimer un wrapper de donnes distantes

Synopsis
DROP FOREIGN DATA WRAPPER [ IF EXISTS ] nom [ CASCADE | RESTRICT ]

Description
DROP FOREIGN DATA WRAPPER supprime un wrapper de donnes distantes existant. Pour excuter cette commande,
l'utilisateur courant doit tre le propritaire du wrapper de donnes distantes.

Paramtres
IF EXISTS
Ne gnre pas d'erreur si le wrapper de donnes distantes n'existe pas. Un avertissement est mis dans ce cas.
nom
Le nom d'un wrapper de donnes distantes existant.
CASCADE
Supprime automatiquement les objets dpendant du wrapper de donnes distantes (tels que les serveurs).
RESTRICT
Refuse de supprimer le wrapper de donnes distantes si un objet dpend de celui-ci. C'est le cas par dfaut.

Exemples
Supprimer le wrapper de donnes distantes dbi :
DROP FOREIGN DATA WRAPPER dbi;

Compatibilit
DROP FOREIGN DATA WRAPPER est conforme la norme ISO/IEC 9075-9 (SQL/MED). La clause IF EXISTS est une
extension PostgreSQL .

Voir aussi
CREATE FOREIGN DATA WRAPPER(7), ALTER FOREIGN DATA WRAPPER(7)

1031

Nom
DROP FOREIGN TABLE Supprime une table distante

Synopsis
DROP FOREIGN TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]

Description
DROP FOREIGN TABLE supprime une table distante.
Vous devez tre propritaire de la table distante pour utiliser DROP FOREIGN TABLE.

Paramtres
IF EXISTS
Permet de ne pas retourner d'erreur si la table distante n'existe pas. Une simple notice est alors rapporte.
name
Le nom de la table distante supprimer. Il est aussi possible de spcifier le schma qui contient cette table.
CASCADE
Supprime automatiquement les objets qui dpendent de cette table distante (comme les vues par exemple).
RESTRICT
Permet de spcifier que la table distante ne sera pas supprime si des objets en dpendent. Il s'agit du comportement par dfaut.

Exemples
Pour supprimer deux tables distantes, films et distributeurs:
DROP FOREIGN TABLE films, distributeurs;
Cette commande va chouer s'il existe des objets qui dpendent de films ou distributeurs. Par exemple, si des
contraintes sont lies des colonnes de films. Dans ce cas de figure, ajoutez l'option cascade CASCADE pour forcer la suppression de ces objets.

Compatibilit
Cette commande est conforme avec le standard ISO/IEC 9075-9 (SQL/MED), aux exceptions prtes que ce standard n'accepte la
suppression que d'une table distante par commande, et de l'option IF EXISTS, qui est une spcificit de PostgreSQL.

Voir aussi
ALTER FOREIGN TABLE(7), CREATE FOREIGN TABLE(7)

1032

Nom
DROP FUNCTION Supprimer une fonction

Synopsis
DROP FUNCTION [ IF EXISTS ] nom ( [ [ modearg ] [ nomarg ] typearg [, ...] ] )
[ CASCADE | RESTRICT ]

Description
DROP FUNCTION supprime la dfinition d'une fonction. Seul le propritaire de la fonction peut excuter cette commande.
Les types d'argument de la fonction doivent tre prciss car plusieurs fonctions peuvent exister avec le mme nom et des listes
diffrentes d'arguments.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom (ventuellement qualifi du nom du schma) de la fonction.
modearg
Le mode d'un argument : IN, OUT, INOUT ou VARIADIC. Sans prcision, la valeur par dfaut est IN. DROP FUNCTION ne s'intresse pas aux arguments OUT car seuls ceux en entre dterminent l'identit de la fonction. Il est ainsi suffisant de lister les arguments IN, INOUT et VARIADIC.
nomarg
Le nom d'un argument. DROP FUNCTION ne tient pas compte des noms des arguments car seuls les types de donnes
sont ncessaires pour dterminer l'identit de la fonction.
typearg
Le(s) type(s) de donnes des arguments de la fonction (ventuellement qualifi(s) du nom du schma).
CASCADE
Les objets qui dpendent de la fonction (oprateurs ou dclencheurs) sont automatiquement supprims.
RESTRICT
La fonction n'est pas supprime si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer la fonction de calcul d'une racine carre :
DROP FUNCTION sqrt(integer);

Compatibilit
Une instruction DROP FUNCTION est dfinie dans le standard SQL mais elle n'est pas compatible avec celle dcrite ici.

Voir aussi
CREATE FUNCTION(7), ALTER FUNCTION(7)

1033

Nom
DROP GROUP Supprimer un rle de base de donnes

Synopsis
DROP GROUP [ IF EXISTS ] nom [, ... ]

Description
DROP GROUP est dsormais un alias de DROP ROLE(7).

Compatibilit
Il n'existe pas d'instruction DROP GROUP dans le standard SQL.

Voir aussi
DROP ROLE(7)

1034

Nom
DROP INDEX Supprimer un index

Synopsis
DROP INDEX [ IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]

Description
DROP INDEX supprime un index. Seul le propritaire de l'index peut excuter cette commande.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom (ventuellement qualifi du nom du schma) de l'index supprimer.
CASCADE
Les objets qui dpendent de l'index sont automatiquement supprims.
RESTRICT
L'index n'est pas supprim si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer l'index title_idx :
DROP INDEX title_idx;

Compatibilit
DROP INDEX est une extension PostgreSQL. Il n'est pas fait mention des index dans le standard SQL.

Voir aussi
CREATE INDEX(7)

1035

Nom
DROP LANGUAGE Supprimer un langage procdural

Synopsis
DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] nom [ CASCADE | RESTRICT ]

Description
DROP LANGUAGE supprime la dfinition d'un langage procdural enregistr prcdemment. Vous devez tre un superutilisateur ou le propritaire du langage pour utiliser DROP LANGUAGE.

Note
partir de PostgreSQL 9.1, la plupart des langages procduraux sont devenus des extensions et doivent du
coup tre supprims avec la commande DROP EXTENSION(7), et non pas avec DROP LANGUAGE.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si le langage n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom du langage procdural supprimer. Pour une compatibilit ascendante, le nom peut tre entour de guillemets
simples.
CASCADE
Les objets qui dpendent du langage (fonctions, par exemple) sont automatiquement supprims.
RESTRICT
Le langage n'est pas supprim si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer le langage procdural plexemple :
DROP LANGUAGE plexemple;

Compatibilit
Il n'existe pas d'instruction DROP LANGUAGE dans le standard SQL.

Voir aussi
ALTER LANGUAGE(7), CREATE LANGUAGE(7), droplang(1)

1036

Nom
DROP OPERATOR Supprimer un oprateur

Synopsis
DROP OPERATOR [ IF EXISTS ] nom ( { type_gauche | NONE }, { type_droit | NONE } )
[ CASCADE | RESTRICT ]

Description
DROP OPERATOR supprime un oprateur. Seul le propritaire de l'oprateur peut excuter cette commande.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom de l'oprateur (ventuellement qualifi du nom du schma) supprimer.
type_gauche
Le type de donnes de l'oprande gauche de l'oprateur ; NONE est utilis si l'oprateur n'en a pas.
type_droit
Le type de donnes de l'oprande droit de l'oprateur ; NONE est utilis si l'oprateur n'en a pas.
CASCADE
Les objets qui dpendent de l'oprateur sont automatiquement supprims.
RESTRICT
L'oprateur n'est pas supprim si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer l'oprateur puissance a^b sur le type integer :
DROP OPERATOR ^ (integer, integer);
Supprimer l'oprateur de complment binaire ~b sur le type bit :
DROP OPERATOR ~ (none, bit);
Supprimer l'oprateur unaire factorielle x! sur le type bigint :
DROP OPERATOR ! (bigint, none);

Compatibilit
Il n'existe pas d'instruction DROP OPERATOR dans le standard SQL.

Voir aussi
CREATE OPERATOR(7), ALTER OPERATOR(7)

1037

Nom
DROP OPERATOR CLASS Supprimer une classe d'oprateur

Synopsis
DROP OPERATOR CLASS [ IF EXISTS ] nom USING mthode_index [ CASCADE | RESTRICT ]

Description
DROP OPERATOR CLASS supprime une classe d'oprateur. Seul le propritaire de la classe peut la supprimer.
DROP OPERATOR CLASS ne supprime aucun des oprateurs et aucune des fonctions rfrencs par la classe. Si un index
dpend de la classe d'oprateur, vous devez indiquer CASCADE pour que la suppression se fasse rellement.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom (ventuellement qualifi du nom du schma) d'une classe d'oprateur.
mthode_index
Le nom de la mthode d'accs aux index pour laquelle l'oprateur est dfini.
CASCADE
Les objets qui dpendent de cette classe sont automatiquement supprims.
RESTRICT
La classe d'oprateur n'est pas supprime si un objet en dpend. Comportement par dfaut.

Notes
DROP OPERATOR CLASS ne supprimera pas la famille d'oprateur contenant la classe, mme si la famille en devient vide
(en particulier, dans le cas o la famille a t implicitement cre par CREATE OPERATOR CLASS). Avoir une famille
d'oprateur vide est sans risque. Pour plus de claret, il est prfrable de supprimer la famille avec DROP OPERATOR FAMILY ; ou encore mieux, utilisez DROP OPERATOR FAMILY ds le dbut.

Exemples
Supprimer la classe d'oprateur widget_ops des index de type arbre-balanc (B-tree) :
DROP OPERATOR CLASS widget_ops USING btree;
La commande choue si un index utilise la classe d'oprateur. CASCADE permet de supprimer ces index simultanment.

Compatibilit
Il n'existe pas d'instruction DROP OPERATOR CLASS dans le standard SQL.

Voir aussi
ALTER OPERATOR CLASS(7), CREATE OPERATOR CLASS(7), DROP OPERATOR FAMILY(7)

1038

Nom
DROP OPERATOR FAMILY Supprimer une famille d'oprateur

Synopsis
DROP OPERATOR FAMILY [ IF EXISTS ] nom USING methode_indexage [ CASCADE | RESTRICT ]

Description
DROP OPERATOR FAMILY supprime une famille d'oprateur existante. Pour excuter cette commande, vous devez tre le
propritaire de la famille d'oprateur.
DROP OPERATOR FAMILY inclut la suppression de toutes classes d'oprateur contenues dans la famille, mais elle ne supprime pas les oprateurs et fonctions rfrences par la famille. Si des index dpendent des classes d'oprateur de la famille,
vous devez ajouter CASCADE pour que la suppression russisse.

Paramtres
IF EXISTS
Ne renvoie pas une erreur si la famille d'oprateur n'existe pas. Un message de niveau NOTICE est enregistr dans ce
cas.
nom
Le nom de la famille d'oprateur (quelque fois qualifi du schma).
methode_indexage
Le nom de la mthode d'accs l'index associe la famille d'oprateur.
CASCADE
Supprime automatiquement les objets dpendant de cette famille d'oprateur.
RESTRICT
Refuse la suppression de la famille d'oprateur si des objets en dpendent. C'est la valeur par dfaut.

Exemples
Supprimer la famille d'oprateur B-tree float_ops :
DROP OPERATOR FAMILY float_ops USING btree;
Cette commande chouera car il existe des index qui utilisent les classes d'oprateur de cette famille. Ajoutez CASCADE pour
supprimer les index avec la famille d'oprateurs.

Compatibilit
Il n'existe pas d'instruction DROP OPERATOR FAMILY dans le standard SQL.

Voir aussi
ALTER OPERATOR FAMILY(7), CREATE OPERATOR FAMILY(7), ALTER OPERATOR CLASS(7), CREATE OPERATOR CLASS(7), DROP OPERATOR CLASS(7)

1039

Nom
DROP OWNED Supprimer les objets de la base possds par un rle

Synopsis
DROP OWNED BY nom [, ...] [ CASCADE | RESTRICT ]

Description
DROP OWNED supprime tous les objets de la base qui ont pour propritaire un des rles spcifis. Tout droit donn un des
rles sur ces objets ainsi qu'aux objets partags (bases de donnes, tablespaces) sera aussi supprim.

Paramtres
nom
Le nom d'un rle dont les objets seront supprims et dont les droits seront rvoqus.
CASCADE
Supprime automatiquement les objets qui dpendent des objets affects.
RESTRICT
Refuse de supprimer les objets possds par un rle si un autre objet de la base dpend de ces objets. C'est la valeur par dfaut.

Notes
DROP OWNED est souvent utilis pour prparer la suppression d'un ou plusieurs rles. Comme DROP OWNED affecte
seulement les objets de la base en cours, il est gnralement ncessaire d'excuter cette commande dans chaque base contenant
des objets appartenant au rle supprimer.
Utiliser l'option CASCADE pourrait demander la suppression d'objets appartenant d'autres utilisateurs.
La commande REASSIGN OWNED(7) est une alternative qui r-affecte la proprit de tous les objets de la base possds par
un ou plusieurs rles.
Les bases de donnes et les tablespaces appartenant au(x) rle(s) ne seront pas supprims.

Compatibilit
L'instruction DROP OWNED est une extension PostgreSQL.

Voir aussi
REASSIGN OWNED(7), DROP ROLE(7)

1040

Nom
DROP ROLE Supprimer un rle de base de donnes

Synopsis
DROP ROLE [ IF EXISTS ] nom [, ...]

Description
DROP ROLE supprime le(s) rle(s) spcifi(s). Seul un superutilisateur peut supprimer un rle de superutilisateur. Le droit
CREATEROLE est ncessaire pour supprimer les autres rles.
Un rle ne peut pas tre supprim s'il est toujours rfrenc dans une base de donnes du groupe. Dans ce cas, toute tentative
aboutit l'affichage d'une erreur. Avant de supprimer un rle, il est ncessaire de supprimer au pralable tous les objets qu'il
possde (ou de modifier leur appartenance) et de supprimer tous les droits dfinis par ce rle. Les commandes REASSIGN OWNED(7) et DROP OWNED(7) peuvent tre utiles pour cela.
Nanmoins, il n'est pas ncessaire de supprimer toutes les appartenances de rle impliquant ce rle ; DROP ROLE supprime
automatiquement toute appartenance du rle cible dans les autres rles et des autres rles dans le rle cible. Les autres rles ne
sont pas supprims ou affects.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom du rle supprimer.

Notes
PostgreSQL inclut un programme dropuser(1) qui a la mme fonctionnalit que cette commande (en fait, il appelle cette commande) mais qui est lanc partir du shell.

Exemples
Supprimer un rle :
DROP ROLE jonathan;

Compatibilit
Le standard SQL dfinit DROP ROLE mais il ne permet la suppression que d'un seul rle la fois et il spcifie d'autres droits
obligatoires que ceux utiliss par PostgreSQL.

Voir aussi
CREATE ROLE(7), ALTER ROLE(7), SET ROLE(7)

1041

Nom
DROP RULE Supprimer une rgle de rcriture

Synopsis
DROP RULE [ IF EXISTS ] nom ON table [ CASCADE | RESTRICT ]

Description
DROP RULE supprime une rgle de rcriture.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom de la rgle supprimer.
table
Le nom (ventuellement qualifi du nom du schma) de la table ou vue sur laquelle s'applique la rgle.
CASCADE
Les objets qui dpendent de la rgle sont automatiquement supprims.
RESTRICT
La rgle n'est pas supprime si un objet en dpend. Comportement par dfaut.

Exemples
Suppression de la rgle de rcriture nouvellergle :
DROP RULE nouvellergle ON matable;

Compatibilit
Il n'existe pas d'instruction DROP RULE dans le standard SQL.

Voir aussi
CREATE RULE(7)

1042

Nom
DROP SCHEMA Supprimer un schma

Synopsis
DROP SCHEMA [ IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]

Description
DROP SCHEMA supprime des schmas de la base de donnes.
Un schma ne peut tre supprim que par son propritaire ou par un superutilisateur. Son propritaire peut supprimer un schma
et tous les objets qu'il contient quand bien mme il ne possde pas tous les objets contenus dans ce schma.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom du schma.
CASCADE
Les objets (tables, fonctions...) contenus dans le schma sont automatiquement supprims.
RESTRICT
Le schma n'est pas supprim s'il contient des objets. Comportement par dfaut.

Exemples
Supprimer le schma mes_affaires et son contenu :
DROP SCHEMA mes_affaires CASCADE;

Compatibilit
DROP SCHEMA est totalement compatible avec le standard SQL. Le standard n'autorise cependant pas la suppression de plusieurs schmas en une seule commande. L'option IF EXISTS est aussi une extension de PostgreSQL.

Voir aussi
ALTER SCHEMA(7), CREATE SCHEMA(7)

1043

Nom
DROP SEQUENCE Supprimer une squence

Synopsis
DROP SEQUENCE [ IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]

Description
DROP SEQUENCE permet de supprimer les gnrateurs de nombres squentiels. Une squence peut seulement tre supprime
par son propritaire ou par un superutilisateur.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom de la squence (ventuellement qualifi du nom du schma).
CASCADE
Les objets qui dpendent de la squence sont automatiquement supprims.
RESTRICT
La squence n'est pas supprime si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer la squence serie :
DROP SEQUENCE serie;

Compatibilit
DROP SEQUENCE est conforme au standard SQL. Cependant, le standard n'autorise pas la suppression de plusieurs squences en une seule commande. De plus, l'option IF EXISTS est une extension de PostgreSQL.

Voir aussi
CREATE SEQUENCE(7), ALTER SEQUENCE(7)

1044

Nom
DROP SERVER Supprimer un descripteur de serveur distant

Synopsis
DROP SERVER [ IF EXISTS ] nom_serveur [ CASCADE | RESTRICT ]

Description
DROP SERVER supprime un descripteur de serveur distant existant. Pour excuter cette commande, l'utilisateur courant doit
tre le propritaire du serveur.

Paramtres
IF EXISTS
Ne gnre pas d'erreur si le serveur n'existe pas. Un avertissement est mis dans ce cas.
nom_serveur
Nom d'un serveur existant.
CASCADE
Supprime automatiquement les objets dpendant du serveur (tels que les correspondances d'utilisateur).
RESTRICT
Refuse de supprimer le serveur si des objets en dpendent. C'est le cas par dfaut.

Exemples
Supprimer un serveur truc s'il existe :
DROP SERVER IF EXISTS truc;

Compatibilit
DROP SERVER est conforme la norme ISO/IEC 9075-9 (SQL/MED). La clause IF EXISTS est une extension
PostgreSQL .

Voir aussi
CREATE SERVER(7), ALTER SERVER(7)

1045

Nom
DROP TABLE Supprimer une table

Synopsis
DROP TABLE [ IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]

Description
DROP TABLE supprime des tables de la base de donnes. Seul son propritaire peut dtruire une table. DELETE(7) et TRUNCATE(7) sont utilises pour supprimer les lignes d'une table sans dtruire la table.
DROP TABLE supprime tout index, rgle, dclencheur ou contrainte qui existe sur la table cible. Nanmoins, pour supprimer
une table rfrence par une vue ou par une contrainte de cl trangre d'une autre table, CASCADE doit tre ajout. (CASCADE
supprime compltement une vue dpendante mais dans le cas de la cl trangre, il ne supprime que la contrainte, pas l'autre
table.)

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom de la table supprimer (ventuellement qualifi du nom du schma).
CASCADE
Les objets qui dpendent de la table (vues, par exemple) sont automatiquement supprims.
RESTRICT
La table n'est pas supprime si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer les deux tables films et distributeurs :
DROP TABLE films, distributeurs;

Compatibilit
Cette commande est conforme au standard SQL. Cependant, le standard n'autorise pas la suppression de plusieurs tables en une
seule commande. De plus, l'option IF EXISTS est une extension de PostgreSQL.

Voir aussi
ALTER TABLE(7), CREATE TABLE(7)

1046

Nom
DROP TABLESPACE Supprimer un tablespace

Synopsis
DROP TABLESPACE [ IF EXISTS ] nom_tablespace

Description
DROP TABLESPACE supprime un tablespace du systme.
Un tablespace ne peut tre supprim que par son propritaire ou par un superutilisateur. Le tablespace doit tre vide de tout objet
de base de donnes avant sa suppression. Mme si le tablespace ne contient plus d'objets de la base de donnes courante, il est
possible que des objets d'autres bases de donnes l'utilisent. De plus, si le tablespace se trouve parmi les tablespaces du paramtre temp_tablespaces d'une session active, la commande DROP pourrait chouer cause de fichiers temporaires stocks dans
le tablespace.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom_tablespace
Le nom du tablespace.

Notes
DROP TABLESPACE ne peut pas tre excut l'intrieur d'un bloc de transactions.

Exemples
Supprimer le tablespace mes_affaires :
DROP TABLESPACE mes_affaires;

Compatibilit
DROP TABLESPACE est une extension PostgreSQL.

Voir aussi
CREATE TABLESPACE(7), ALTER TABLESPACE(7)

1047

Nom
DROP TEXT SEARCH CONFIGURATION Supprimer une configuration de recherche plein texte

Synopsis
DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] nom [ CASCADE | RESTRICT ]

Description
DROP TEXT SEARCH CONFIGURATION supprime une configuration existante de la recherche plein texte. Pour excuter
cette commande, vous devez tre le propritaire de la configuration.

Paramtres
IF EXISTS
Ne renvoie pas une erreur si la configuration de recherche plein texte n'existe pas. Un message de niveau NOTICE est
enregistr dans ce cas.
name
Le nom de la configuration de recherche plein texte (quelque fois qualifi du schma).
CASCADE
Supprime automatiquement les objets dpendant de cette configuration de recherche plein texte.
RESTRICT
Refuse la suppression de la configuration de recherche plein texte si des objets en dpendent. C'est la valeur par dfaut.

Exemples
Supprimer la configuration de recherche plein texte the text search configuration my_english:
DROP TEXT SEARCH CONFIGURATION my_english;
Cette commande chouera s'il existe des index qui rfrencent la configuration dans des appels to_tsvector. Ajoutez CASCADE pour supprimer ces index avec la configuration de recherche plein texte.

Compatibilit
Il n'existe pas d'instruction DROP TEXT SEARCH CONFIGURATION dans le standard SQL.

Voir aussi
ALTER TEXT SEARCH CONFIGURATION(7), CREATE TEXT SEARCH CONFIGURATION(7)

1048

Nom
DROP TEXT SEARCH DICTIONARY Supprimer un dictionnaire de recherche plein texte

Synopsis
DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] nom [ CASCADE | RESTRICT ]

Description
DROP TEXT SEARCH DICTIONARY supprime un dictionnaire existant de la recherche plein texte. Pour excuter cette
commande, vous devez tre le propritaire du dictionnaire.

Paramtres
IF EXISTS
Ne renvoie pas une erreur si le dictionnaire de recherche plein texte n'existe pas. Un message de niveau NOTICE est enregistr dans ce cas.
name
Le nom du dictionnaire de recherche plein texte (quelque fois qualifi du schma).
CASCADE
Supprime automatiquement les objets dpendant de ce dictionnaire de recherche plein texte.
RESTRICT
Refuse la suppression du dictionnaire de recherche plein texte si des objets en dpendent. C'est la valeur par dfaut.

Exemples
Supprimer le dictionnaire de recherche plein texte english :
DROP TEXT SEARCH DICTIONARY english;
Cette commande chouera s'il existe des configurations qui utilisent ce dictionnaire. Ajoutez CASCADE pour supprimer ces
configurations avec le dictionnaire de recherche plein texte.

Compatibilit
Il n'existe pas d'instruction DROP TEXT SEARCH DICTIONARY dans le standard SQL.

Voir aussi
ALTER TEXT SEARCH DICTIONARY(7), CREATE TEXT SEARCH DICTIONARY(7)

1049

Nom
DROP TEXT SEARCH PARSER Supprimer un analyseur de recherche plein texte

Synopsis
DROP TEXT SEARCH PARSER [ IF EXISTS ] nom [ CASCADE | RESTRICT ]

Description
DROP TEXT SEARCH PARSER supprime un analyseur existant de la recherche plein texte. Pour excuter cette commande,
vous devez tre superutilisateur.

Paramtres
IF EXISTS
Ne renvoie pas une erreur si l'analyseur de recherche plein texte n'existe pas. Un message de niveau NOTICE est enregistr dans ce cas.
name
Le nom de l'analyseur de recherche plein texte (quelque fois qualifi du schma).
CASCADE
Supprime automatiquement les objets dpendant de l'analyseur de recherche plein texte.
RESTRICT
Refuse la suppression de l'analyseur de recherche plein texte si des objets en dpendent. C'est la valeur par dfaut.

Exemples
Supprimer l'analyseur de recherche plein texte mon_analyseur :
DROP TEXT SEARCH PARSER mon_analyseur;
Cette commande chouera s'il existe des configurations qui utilisent ce dictionnaire. Ajoutez CASCADE pour supprimer ces
configurations avec l'analyseur de recherche plein texte.

Compatibilit
Il n'existe pas d'instruction DROP TEXT SEARCH PARSER dans le standard SQL.

Voir aussi
ALTER TEXT SEARCH PARSER(7), CREATE TEXT SEARCH PARSER(7)

1050

Nom
DROP TEXT SEARCH TEMPLATE Supprimer un modle de recherche plein texte

Synopsis
DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] nom [ CASCADE | RESTRICT ]

Description
DROP TEXT SEARCH TEMPLATE supprime un modle existant de la recherche plein texte. Pour excuter cette commande, vous devez superutilisateur.

Paramtres
IF EXISTS
Ne renvoie pas une erreur si le modle de recherche plein texte n'existe pas. Un message de niveau NOTICE est enregistr dans ce cas.
name
Le nom du modle de recherche plein texte (quelque fois qualifi du schma).
CASCADE
Supprime automatiquement les objets dpendant de ce modle de recherche plein texte.
RESTRICT
Refuse la suppression du modle de recherche plein texte si des objets en dpendent. C'est la valeur par dfaut.

Exemples
Supprimer le modle de recherche plein texte thesaurus :
DROP TEXT SEARCH TEMPLATE thesaurus;
Cette commande chouera s'il existe des dictionnaires qui utilisent ce modles. Ajoutez CASCADE pour supprimer ces dictionnaires avec le modle de recherche plein texte.

Compatibilit
Il n'existe pas d'instruction DROP TEXT SEARCH TEMPLATE dans le standard SQL.

Voir aussi
ALTER TEXT SEARCH TEMPLATE(7), CREATE TEXT SEARCH TEMPLATE(7)

1051

Nom
DROP TRIGGER Supprimer un dclencheur

Synopsis
DROP TRIGGER [ IF EXISTS ] nom ON table [ CASCADE | RESTRICT ]

Description
DROP TRIGGER supprime la dfinition d'un dclencheur. Seul le propritaire de la table sur laquelle le dclencheur est dfini
peut excuter cette commande.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom du dclencheur supprimer.
table
Le nom de la table (ventuellement qualifi du nom du schma) sur laquelle le dclencheur est dfini.
CASCADE
Les objets qui dpendent du dclencheur sont automatiquement supprims.
RESTRICT
Le dclencheur n'est pas supprim si un objet en dpend. Comportement par dfaut.

Exemples
Destruction du dclencheur si_dist_existe de la table films :
DROP TRIGGER si_dist_existe ON films;

Compatibilit
L'instruction DROP TRIGGER de PostgreSQL est incompatible avec le standard SQL. Dans le standard, les noms de dclencheurs ne se dfinissent pas par rapport aux tables. La commande est donc simplement DROP TRIGGER nom.

Voir aussi
CREATE TRIGGER(7)

1052

Nom
DROP TYPE Supprimer un type de donnes

Synopsis
DROP TYPE [ IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]

Description
DROP TYPE supprime un type de donnes utilisateur. Seul son propritaire peut le supprimer.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom du type de donnes (ventuellement qualifi du nom de schma) supprimer.
CASCADE
Les objets qui dpendent du type (colonnes de table, fonctions, oprateurs...) sont automatiquement supprims.
RESTRICT
Le type n'est pas supprim si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer le type de donnes boite :
DROP TYPE boite;

Compatibilit
Cette commande est similaire celle du standard SQL en dehors de l'option IF EXISTS qui est une extension PostgreSQL.
La majorit de la commande CREATE TYPE et les mcanismes d'extension de type de donnes de PostgreSQL diffrent du
standard.

Voir aussi
ALTER TYPE(7), CREATE TYPE(7)

1053

Nom
DROP USER Supprimer un rle de base de donnes

Synopsis
DROP USER [ IF EXISTS ] nom [, ...]

Description
DROP USER est dsormais un alias de DROP ROLE(7).

Compatibilit
L'instruction DROP USER est une extension PostgreSQL. Le standard SQL laisse la dfinition des utilisateurs
l'implantation.

Voir aussi
DROP ROLE(7)

1054

Nom
DROP USER MAPPING Supprimer une correspondance d'utilisateur pour un serveur distant

Synopsis
DROP USER MAPPING [ IF EXISTS ] FOR { nom_utilisateur | USER | CURRENT_USER | PUBLIC
} SERVER nom_serveur

Description
DROP USER MAPPING supprime une correspondance d'utilisateur existant pour un serveur distant.
Le propritaire d'un serveur distant peut supprimer les correspondances d'utilisateur pour ce serveur pour n'importe quel utilisateur. Par ailleurs, un utilisateur peut supprimer une correspondance d'utilisateur pour son propre nom d'utilisateur s'il a reu le
droit USAGE sur le serveur.

Paramtres
IF EXISTS
Ne gnre pas d'erreur si la correspondance d'utilisateur n'existe pas. Un avertissement est mis dans ce cas.
nom_utilisateur
Nom d'utilisateur de la correspondance. CURRENT_USER et USER correspondent au nom de l'utilisateur courant. PUBLIC
est utilis pour correspondre tous les noms d'utilisateurs prsents et futurs du systme.
nom_serveur
Nom du serveur de la correspondance d'utilisateur.

Exemples
Supprimer une correspondance d'utilisateur bob, sur le serveur truc si elle existe :
DROP USER MAPPING IF EXISTS FOR bob SERVER truc;

Compatibilit
DROP USER MAPPING est conforme la norme ISO/IEC 9075-9 (SQL/MED). La clause IF EXISTS est une extension
PostgreSQL.

Voir aussi
CREATE USER MAPPING(7), ALTER USER MAPPING(7)

1055

Nom
DROP VIEW Supprimer une vue

Synopsis
DROP VIEW [ IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]

Description
DROP VIEW supprime une vue existante. Seul le propritaire de la vue peut excuter cette commande.

Paramtres
IF EXISTS
Ne pas renvoyer une erreur si l'agrgat n'existe pas. Un message d'avertissement est affich dans ce cas.
nom
Le nom de la vue (ventuellement qualifi du nom de schma) supprimer.
CASCADE
Les objets qui dpendent de la vue (d'autres vues, par exemple) sont automatiquement supprims.
RESTRICT
La vue n'est pas supprime si un objet en dpend. Comportement par dfaut.

Exemples
Supprimer la vue genre :
DROP VIEW genre;

Compatibilit
Cette commande est conforme au standard SQL. Cependant, le standard n'autorise pas la suppression de plusieurs vues en une
seule commande. De plus, l'option IF EXISTS est une extension de PostgreSQL.

Voir aussi
ALTER VIEW(7), CREATE VIEW(7)

1056

Nom
END Valider la transaction en cours

Synopsis
END [ WORK | TRANSACTION ]

Description
END valide la transaction en cours. Toutes les modifications ralises lors de la transaction deviennent visibles pour les autres
utilisateurs et il est garanti que les donnes ne seront pas perdues si un arrt brutal survient. Cette commande est une extension
PostgreSQL quivalente COMMIT(7).

Paramtres
WORK, TRANSACTION
Mots cls optionnels. Ils n'ont pas d'effet.

Notes
ROLLBACK(7) est utilis pour annuler une transaction.
Lancer END l'extrieur d'une transaction n'a aucun effet mais provoque un message d'avertissement.

Exemples
Valider la transaction en cours et rendre toutes les modifications persistantes :
END;

Compatibilit
END est une extension PostgreSQL fournissant une fonctionnalit quivalente COMMIT(7), spcifi dans le standard SQL.

Voir aussi
BEGIN(7), COMMIT(7), ROLLBACK(7)

1057

Nom
EXECUTE Excuter une instruction prpare

Synopsis
EXECUTE nom [ (paramtre [, ...] ) ]

Description
EXECUTE est utilis pour excuter une instruction prpare au pralable. Comme les instructions prpares existent seulement
pour la dure d'une session, l'instruction prpare doit avoir t cre par une instruction PREPARE excute plus tt dans la
session en cours.
Si l'instruction PREPARE qui cre l'instruction est appele avec des paramtres, un ensemble compatible de paramtres doit
tre pass l'instruction EXECUTE, sinon une erreur est leve. Contrairement aux fonctions, les instructions prpares ne sont
pas surcharges en fonction de leur type ou du nombre de leurs paramtres ; le nom d'une instruction prpare doit tre unique
au sein d'une session.
Pour plus d'informations sur la cration et sur l'utilisation des instructions prpares, voir PREPARE(7).

Paramtres
nom
Le nom de l'instruction prpare excuter.
paramtre
La valeur relle du paramtre d'une instruction prpare. Ce paramtre doit tre une expression ramenant une valeur dont le
type est compatible avec celui spcifi pour ce paramtre positionnel dans la commande PREPARE qui a cr l'instruction
prpare.

Sorties
La sortie renvoye par la commande EXECUTE est celle de l'instruction prpare, et non celle de la commande EXECUTE.

Exemples
Des exemples sont donns dans la section la section intitule Exemples de la documentation de PREPARE(7).

Compatibilit
Le standard SQL inclut une instruction EXECUTE qui n'est utilise que dans le SQL embarqu. La syntaxe utilise par cette
version de l'instruction EXECUTE diffre quelque peu.

Voir aussi
DEALLOCATE(7), PREPARE(7)

1058

Nom
EXPLAIN Afficher le plan d'excution d'une instruction

Synopsis
EXPLAIN [ ( option [, ...] ) ] instruction
EXPLAIN [ ANALYZE ] [ VERBOSE ] instruction
o option est :
ANALYZE [ boolean ]
VERBOSE [ boolean ]
COSTS [ boolean ]
BUFFERS [ boolean ]
FORMAT { TEXT | XML | JSON | YAML }

Description
Cette commande affiche le plan d'excution que l'optimiseur de PostgreSQL engendre pour l'instruction fournie. Le plan
d'excution dcrit le parcours de la (des) table(s) utilise(s) dans la requte -- parcours squentiel, parcours d'index, etc. -- . Si
plusieurs tables sont rfrences, il prsente galement les algorithmes de jointures utiliss pour rassembler les lignes issues des
diffrentes tables.
La partie la plus importante de l'affichage concerne l'affichage des cots estims d'excution. Ils reprsentent l'estimation faite
par le planificateur des temps d'excution de la requte (mesurs en units de rcupration de pages sur le disque). Deux
nombres sont affichs : le temps de dmarrage, coul avant que la premire ligne soit renvoye, et le temps d'excution total,
ncessaire au renvoi de toutes les lignes. Pour la plupart des requtes, le temps qui importe est celui d'excution totale. Mais
dans certains cas, tel que pour une sous-requte dans la clause EXISTS, le planificateur choisira le temps de dmarrage le plus
court, et non celui d'excution totale (car, de toute faon, l'excuteur s'arrte aprs la rcupration d'une ligne). De mme, lors de
la limitation des rsultats retourner par une clause LIMIT, la planificateur effectue une interpolation entre les deux temps limites pour choisir le plan rellement le moins coteux.
L'option ANALYZE impose l'excution de la requte en plus de sa planification. Le temps total d'excution de chaque nud du
plan (en millisecondes) et le nombre total de lignes effectivement retournes sont ajouts l'affichage. C'est utile pour vrifier la
vracit des informations fournies par le planificateur.

Important
Il ne faut pas oublier que l'instruction est rellement excute avec l'option ANALYZE. Bien qu'EXPLAIN inhibe
l'affichage des retours d'une commande SELECT, les autres effets de l'instruction sont prsents. Si EXPLAIN
ANALYZE doit tre utilis sur une instruction INSERT, UPDATE, DELETE CREATE TABLE AS ou EXECUTE sans que la commande n'affecte les donnes, l'approche suivante peut tre envisage :
BEGIN;
EXPLAIN ANALYZE ...;
ROLLBACK;
Seules les options ANALYZE et VERBOSE peuvent tre utilises et dans cet ordre seulement si la liste d'options
entre parenthses n'est pas utilis. Avant PostgreSQL 9.0, la seule syntaxe supporte tait celle sans parenthses. Les nouvelles options ne seront supportes que par la nouvelle syntaxe, celle avec les parenthses.

Paramtres
ANALYZE
Excute la commande et affiche les temps d'excution rels. Ce paramtre est par dfaut FALSE.
VERBOSE
Affiche des informations supplmentaires sur le plan. Cela inclut la liste des colonnes en sortie pour chaque nud du plan,
les noms des tables et fonctions avec le nom du schma, les labels des variables dans les expressions avec des alias de tables
et le nom de chaque trigger pour lesquels les statistiques sont affiches. Ce paramtre est par dfaut FALSE.
COSTS
1059

EXPLAIN

Inclut des informations sur le cot estim au dmarrage et au total de chaque nud du plan, ainsi que le nombre estim de
lignes et la largeur estime de chaque ligne. Ce paramtre est par dfaut TRUE.
BUFFERS
Inclut des informations sur l'utilisation des blocs. Cela inclut le nombre de lecture de blocs partags en cache, sur le disque
ainsi que le nombre de blocs crits. Cela inclut aussi le nombre de blocs locaux lus dans le cache, sur le disque et le nombre
de blocs locaux crits. Enfin, cela inclut le nombre de blocs temporaires lus et crits. Les blocs partags, les blocs locaux et
les blocs temporaires contiennent respectivement des tables et des index, des tables temporaires et des index temporaires, et
les blocs disques utiliss dans les tris et les plans matrialiss. Le nombre de blocs affichs pour un nud de haut niveau inclut ceux utiliss par tous ses enfants. Dans le format texte, seuls les valeurs diffrentes de zro sont affichs. Ce paramtre
pourrait seulement tre utilis avec le paramtre ANALYZE. Il vaut par dfaut FALSE.
FORMAT
Indique le format de sortie. Il peut valoir TEXT, XML, JSON ou YAML. Toutes les sorties contiennent les mmes informations, mais les programmes pourront plus facilement traiter les sorties autres que TEXT. Ce paramtre est par dfaut TEXT.
boolean
Spcifie si l'option slectionne doit tre active ou dsactive. Vous pouvez crire TRUE, ON ou 1 pour activer l'option, et
FALSE, OFF ou 0 pour la dsactiver. La valeur de type boolean peut aussi tre omise, auquel cas la valeur sera TRUE.
instruction
Toute instruction SELECT, INSERT, UPDATE, DELETE, VALUES EXECUTE, DECLARE ou CREATE TABLE AS
dont le plan d'excution est souhait.

Notes
La documentation sur l'utilisation faite par l'optimiseur des informations de cot est assez rduite dans PostgreSQL. On peut se
rfrer Section 14.1, Utiliser EXPLAIN pour plus d'informations.
Pour que le planificateur de requtes de PostgreSQL puisse prendre des dcisions en connaissance de cause, l'instruction ANALYZE(7) doit avoir t excute afin d'enregistrer les statistiques de distribution des donnes dans la table. Si cela n'a pas t fait,
(ou si la distribution statistique des donnes dans la table a chang de manire significative depuis la dernire excution de la commande ANALYZE) les cots estims risquent de ne pas reflter les proprits relles de la requte. De ce fait, un plan de requte
infrieur risque d'tre choisi.
Pour mesurer le cot d'excution du plan d'excution, l'implmentation actuelle de EXPLAIN ANALYZE peut ajouter un dlai
considrable l'excution de la requte cause du profilage. De ce fait, excuter EXPLAIN ANALYZE sur une requte peut
prendre bien plus de temps que d'excuter la requte seule. Ce dlai dpend de la nature de la requte.

Exemples
Afficher le plan d'une requte simple sur une table d'une seule colonne de type integer et 10000 lignes :
EXPLAIN SELECT * FROM foo;
QUERY PLAN
--------------------------------------------------------Seq Scan on foo (cost=0.00..155.00 rows=10000 width=4)
(1 row)
Voici le mme plan, mais format avec JSON :
EXPLAIN (FORMAT JSON) SELECT * FROM foo;
QUERY PLAN
-------------------------------[
+
{
+
"Plan": {
+
"Node Type": "Seq Scan",+
"Relation Name": "foo", +
"Alias": "foo",
+
"Startup Cost": 0.00,
+
"Total Cost": 155.00,
+
"Plan Rows": 10000,
+
"Plan Width": 4
+
}
+
}
+
]
1060

EXPLAIN

(1 row)
S'il existe un index et que la requte contient une condition WHERE indexable, EXPLAIN peut afficher un plan diffrent :
EXPLAIN SELECT * FROM foo WHERE i = 4;
QUERY PLAN
-------------------------------------------------------------Index Scan using fi on foo (cost=0.00..5.98 rows=1 width=4)
Index Cond: (i = 4)
(2 rows)
Voici le mme plan, mais format avec YAML :
EXPLAIN (FORMAT YAML) SELECT * FROM foo WHERE i='4';
QUERY PLAN
------------------------------- Plan:
+
Node Type: "Index Scan" +
Scan Direction: "Forward"+
Index Name: "fi"
+
Relation Name: "foo"
+
Alias: "foo"
+
Startup Cost: 0.00
+
Total Cost: 5.98
+
Plan Rows: 1
+
Plan Width: 4
+
Index Cond: "(i = 4)"
(1 row)
L'obtention du format XML est laiss en exercice au lecteur.
Voici le mme plan avec les cots supprims :
EXPLAIN (COSTS FALSE) SELECT * FROM foo WHERE i = 4;
QUERY PLAN
---------------------------Index Scan using fi on foo
Index Cond: (i = 4)
(2 rows)
Exemple de plan de requte pour une requte utilisant une fonction d'agrgat :
EXPLAIN SELECT sum(i) FROM foo WHERE i < 10;
QUERY PLAN
--------------------------------------------------------------------Aggregate (cost=23.93..23.93 rows=1 width=4)
-> Index Scan using fi on foo (cost=0.00..23.92 rows=6 width=4)
Index Cond: (i < 10)
(3 rows)
Exemple d'utilisation de EXPLAIN EXECUTE pour afficher le plan d'excution d'une requte prpare :
PREPARE query(int, int) AS SELECT sum(bar) FROM test
WHERE id > $1 AND id < $2
GROUP BY foo;
EXPLAIN ANALYZE EXECUTE query(100, 200);
QUERY PLAN
------------------------------------------------------------------------------------HashAggregate (cost=39.53..39.53 rows=1 width=8) (actual time=0.661..0.672 rows=7
loops=1)
-> Index Scan using test_pkey on test (cost=0.00..32.97 rows=1311 width=8) (actual
time=0.050..0.395 rows=99 loops=1)
Index Cond: ((id > $1) AND (id < $2))
Total runtime: 0.851 ms
1061

EXPLAIN

(4 rows)
Il est vident que les nombres prsents ici dpendent du contenu effectif des tables impliques. De plus, les nombres, et la stratgie slectionne elle-mme, peuvent diffrer en fonction de la version de PostgreSQL du fait des amliorations apportes au
planificateur. Il faut galement savoir que la commande ANALYZE calcule les statistiques des donnes partir d'extraits alatoires ; il est de ce fait possible que les cots estims soient modifis aprs l'excution de cette commande, alors mme la distribution relle des donnes dans la table n'a pas chang.

Compatibilit
L'instruction EXPLAIN n'est pas dfinie dans le standard SQL.

Voir aussi
ANALYZE(7)

1062

Nom
FETCH Rcuprer les lignes d'une requte l'aide d'un curseur

Synopsis
FETCH [ direction [ FROM | IN ] ] nom_curseur
o direction peut tre vide ou tre :
NEXT
PRIOR
FIRST
LAST
ABSOLUTE nombre
RELATIVE nombre
nombre
ALL
FORWARD
FORWARD nombre
FORWARD ALL
BACKWARD
BACKWARD nombre
BACKWARD ALL

Description
FETCH rcupre des lignes en utilisant un curseur prcdemment ouvert.
un curseur est associe une position associe utilise par FETCH. Le curseur peut tre positionn avant la premire ligne du
rsultat de la requte, sur une ligne particulire du rsultat ou aprs la dernire ligne du rsultat. sa cration, le curseur est positionn avant la premire ligne. Aprs rcupration de lignes, le curseur est positionn sur la ligne la plus rcemment rcupre.
Si FETCH atteint la fin des lignes disponibles, il est positionn aprs la dernire ligne ou avant la premire ligne dans le cas
d'une rcupration remontante. FETCH ALL ou FETCH BACKWARD ALL positionne toujours le curseur aprs la dernire
ligne ou avant la premire ligne.
Les formes NEXT, PRIOR, FIRST, LAST, ABSOLUTE, RELATIVE rcuprent une seule ligne aprs dplacement appropri du
curseur. Si cette ligne n'existe pas, un rsultat vide est renvoy et le curseur est positionn avant la premire ligne ou aprs la
dernire ligne, en fonction du sens de la progression.
Les formes utilisant FORWARD et BACKWARD rcuprent le nombre de lignes indiqu en se dplaant en avant ou en arrire,
laissant le curseur positionn sur la dernire ligne renvoye (ou aprs/avant toutes les lignes si nombre dpasse le nombre de
lignes disponibles).
RELATIVE 0, FORWARD 0 et BACKWARD 0 rcuprent tous la ligne actuelle sans dplacer le curseur, c'est--dire qu'ils effectuent une nouvelle rcupration de la ligne dernirement rcupre. La commande russit sauf si le curseur est positionn
avant la premire ligne ou aprs la dernire ligne ; dans ce cas, aucune ligne n'est renvoye.

Note
Cette page dcrit l'utilisation des curseurs au niveau de la commande SQL. Si vous voulez utiliser des curseurs
dans une fonction PL/pgSQL, les rgles sont diffrentes -- voir Section 39.7, Curseurs .

Paramtres
direction
La direction et le nombre de lignes rcuprer. Ce paramtre peut prendre les valeurs suivantes :
NEXT
La ligne suivante est rcupre. C'est le comportement par dfaut si direction est omis.
PRIOR
La ligne prcdente est rcupre.
FIRST
1063

FETCH

La premire ligne de la requte est rcupre. C'est identique ABSOLUTE 1.


LAST
La dernire ligne de la requte est rcupre. C'est identique ABSOLUTE -1.
ABSOLUTE nombre
La nombre-ime ligne de la requte est rcuprre, ou la abs(nombre)-ime ligne partir de la fin si nombre est ngatif. Le curseur est positionn avant la premire ligne ou aprs la dernire si nombre est en dehors des bornes ; en particulier,
ABSOLUTE 0 le positionne avant la premire ligne.
RELATIVE nombre
La nombre-ime ligne suivante est rcupre, ou la abs(nombre)-ime ligne prcdente si nombre est ngatif. RELATIVE 0 rcupre de nouveau la ligne courante, si elle existe.
nombre
Les nombre lignes suivantes sont rcupres. C'est identique FORWARD nombre.
ALL
Toutes les lignes restantes sont rcupres. C'est identique FORWARD ALL).
FORWARD
La ligne suivante est rcupre. C'est identique NEXT.
FORWARD nombre
Les nombre lignes suivantes sont rcupres. FORWARD 0 rcupre de nouveau la ligne courante.
FORWARD ALL
Toutes les lignes restantes sont rcupres.
BACKWARD
La ligne prcdente est rcupre. C'est identique PRIOR.
BACKWARD nombre
Les nombre lignes prcdentes sont rcupres (parcours inverse). BACKWARD 0 rcupre de nouveau la ligne courante.
BACKWARD ALL
Toutes les lignes prcdentes sont rcupres (parcours inverse).
nombre
Constante de type entier ventuellement sign, qui prcise l'emplacement ou le nombre de lignes rcuprer. Dans le cas de
FORWARD et BACKWARD, prciser une valeur ngative pour nombre est quivalent modifier le sens de FORWARD et BACKWARD.
nom_curseur
Le nom d'un curseur ouvert.

Sorties
En cas de succs, une commande FETCH renvoie une balise de commande de la forme
FETCH nombre
Le nombre est le nombre de lignes rcupres (ventuellement zro). Dans psql, la balise de commande n'est pas rellement affiche car psql affiche la place les lignes rcupres.

Notes
Le curseur doit tre dclar avec l'option SCROLL si les variantes de FETCH autres que FETCH NEXT ou FETCH FORWARD avec un nombre positif sont utilises. Pour les requtes simples, PostgreSQL autorise les parcours inverses partir de
curseurs non dclars avec SCROLL. il est toutefois prfrable de ne pas se fonder sur ce comportement. Si le curseur est dclar
avec NO SCROLL, aucun parcours inverse n'est autoris.
Les rcuprations ABSOLUTE ne sont pas plus rapides que la navigation vers la ligne dsire par dplacement relatif : de toute
faon, l'implantation sous-jacente doit parcourir toutes les lignes intermdiaires. Les rcuprations absolues ngatives font mme
pis : la requte doit tre lue jusqu' la fin pour trouver la dernire ligne, puis relue en sens inverse partir de l. Nanmoins, remonter vers le dbut de la requte (comme avec FETCH ABSOLUTE 0) est rapide.
DECLARE(7) est utilis pour dfinir un curseur. MOVE(7) est utilis pour modifier la position du curseur sans rcuprer les donnes.

1064

FETCH

Exemples
Parcourir une table l'aide d'un curseur :
BEGIN WORK;
-- Initialiser le curseur :
DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;
-- Rcuprer les 5 premires lignes du curseur liahona :
FETCH FORWARD 5 FROM liahona;
code |
titre
| did | date_prod |
genre | longueur
-------+-------------------------+-----+------------+----------+----------BL101 | The Third Man
| 101 | 1949-12-23 | Drama
| 01:44
BL102 | The African Queen
| 101 | 1951-08-11 | Romantic | 01:43
JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25
P_301 | Vertigo
| 103 | 1958-11-14 | Action
| 02:08
P_302 | Becket
| 103 | 1964-02-03 | Drama
| 02:28
-- Rcuprer la ligne prcdente :
FETCH PRIOR FROM liahona;
code | titre | did | date_prod | genre | longueur
-------+---------+-----+------------+--------+----------P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08
-- Fermer le curseur et terminer la transaction:
CLOSE liahona;
COMMIT WORK;

Compatibilit
Le standard SQL ne dfinit FETCH que pour une utilisation en SQL embarqu. La variante de FETCH dcrite ici renvoie les
donnes comme s'il s'agissait du rsultat d'un SELECT plutt que de le placer dans des variables htes. part cela, FETCH est
totalement compatible avec le standard SQL.
Les formes de FETCH qui impliquent FORWARD et BACKWARD, ainsi que les formes FETCH nombre et FETCH ALL, dans
lesquelles FORWARD est implicite, sont des extensions PostgreSQL.
Le standard SQL n'autorise que FROM devant le nom du curseur ; la possibilit d'utiliser IN, ou de les laisser, est une extension.

Voir aussi
CLOSE(7), DECLARE(7), MOVE(7)

1065

Nom
GRANT Dfinir les droits d'accs

Synopsis
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] nom_table [, ...]
| ALL TABLES IN SCHEMA nom_schma [, ...] }
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( nom_colonne [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( nom_colonne [, ...] ) }
ON [ TABLE ] nom_table [, ...]
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { USAGE | SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON { SEQUENCE nom_squence [, ...]
| ALL SEQUENCES IN SCHEMA nom_schma [, ...] }
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
ON DATABASE nom_base [, ...]
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN DATA WRAPPER nom_fdw [, ...]
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN SERVER nom_serveur [, ...]
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON { FUNCTION nom_fonction ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] ) [,
...]
| ALL FUNCTIONS IN SCHEMA nom_schma [, ...] }
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE nom_lang [, ...]
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT loid [, ...]
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA nom_schma [, ...]
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE tablespace_name [, ...]
TO { [ GROUP ] nom_rle | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT nom_rle [, ...] TO nom_rle [, ...] [ WITH ADMIN OPTION ]

Description
La commande GRANT a deux variantes basiques : la premire donne des droits sur un objet de la base de donnes (table, colonne, vue, table distante, squence, base de donnes, wrapper de donnes distantes, serveur distant, fonction, langage de procdure, schma ou espace logique), la seconde gre les appartenances un rle. Ces variantes sont assez similaires mais somme
toute assez diffrentes pour tre dcrites sparment.

GRANT sur les objets de la base de donnes


1066

GRANT

Cette variante de la commande GRANT donne des droits spcifiques sur un objet de la base de donnes a un ou plusieurs rles.
Ces droits sont ajouts ceux dj possds, s'il y en a.
Il existe aussi une option pour donner les droits sur tous les objets d'un mme type sur un ou plusieurs schmas. Cette fonctionnalit n'est actuellement propose que pour les tables, squences et fonctions (mais notez que ALL TABLES incluent aussi les vues
et les tables distantes).
Le mot cl PUBLIC indique que les droits sont donns tous les rles, y compris ceux crs ultrieurement. PUBLIC peut tre vu
comme un groupe implicitement dfini qui inclut en permanence tous les rles. Un rle particulier dispose de la somme des droits
qui lui sont acquis en propre, des droits de tout rle dont il est membre et des droits donns PUBLIC.
Si WITH GRANT OPTION est prcis, celui qui reoit le droit peut le transmettre son tour (NDT : par la suite on parlera d'
option de transmission de droit , l o en anglais il est fait mention de grant options ). Sans l'option GRANT, l'utilisateur ne
peut pas le faire. Cette option ne peut pas tre donne PUBLIC.
Il n'est pas ncessaire d'accorder des droits au propritaire d'un objet (habituellement l'utilisateur qui l'a cr) car, par dfaut, le
propritaire possde tous les droits. (Le propritaire peut toutefois choisir de rvoquer certains de ses propres droits.)
Le droit de supprimer un objet ou de modifier sa dfinition n'est pas configurable avec cette commande. Il est spcifique au propritaire de l'objet. Ce droit ne peut ni tre donn ni supprim. Nanmoins, il est possible d'avoir le mme effet en rendant un utilisateur membre du rle qui possde cet object ou en le supprimant de ce rle. Le propritaire a aussi implicitement les options de
transmission de droits pour l'objet.
En fonction du type de l'objet, les privilges initiaux par dfaut peuvent inclure la transmission de certains privilges PUBLIC.
Par dfaut, aucun accs public n'est accord sur les tables, colonnes, schmas et tablespaces ; le droit de cration de table
CONNECT et TEMP est accord sur les bases de donnes ; le droit EXECUTE sur les fonctions ; et le droit USAGE sur les langages.
Le propritaire de l'objet peut videmment choisir de rvoquer ces droits. (Pour un maximum de scurit, REVOKE est lanc
dans la mme transaction que la cration de l'objet ; ainsi, il n'y a pas de laps de temps pendant lequel un autre utilisateur peut utiliser l'objet.) De plus, cette configuration des droits par dfaut peut tre modifie en utilisant la commande ALTER DEFAULT
PRIVILEGES(7).
Les droits possibles sont :
SELECT
Autorise SELECT(7) sur toutes les colonnes, ou sur les colonnes listes spcifiquement, de la table, vue ou squence indique. Autorise aussi l'utilisation de COPY(7) TO. De plus, ce droit est ncessaire pour rfrencer des valeurs de colonnes
existantes avec UPDATE(7) ou DELETE(7). Pour les squences, ce droit autorise aussi l'utilisation de la fonction currval.
Pour les Large Objects , ce droit permet la lecture de l'objet.
INSERT
Autorise INSERT(7) d'une nouvelle ligne dans la table indique. Si des colonnes spcifiques sont listes, seules ces colonnes
peuvent tre affectes dans une commande INSERT, (les autres colonnes recevront par consquent des valeurs par dfaut).
Autorise aussi COPY(7) FROM.
UPDATE
Autorise UPDATE(7) sur toute colonne de la table spcifie, ou sur les colonnes spcifiquement listes. (En fait, toute commande UPDATE non triviale ncessite aussi le droit SELECT car elle doit rfrencer les colonnes pour dterminer les lignes
mettre jour et/ou calculer les nouvelles valeurs des colonnes.) SELECT ... FOR UPDATE et SELECT ... FOR
SHARE requirent galement ce droit sur au moins une colonne en plus du droit SELECT. Pour les squences, ce droit autorise l'utilisation des fonctions nextval et setval. Pour les Large Objects , ce droit permet l'criture et le tronquage de
l'objet.
DELETE
Autorise DELETE(7) d'une ligne sur la table indique. (En fait, toute commande DELETE non triviale ncessite aussi le
droit SELECT car elle doit rfrencer les colonnes pour dterminer les lignes supprimer.)
TRUNCATE
Autorise TRUNCATE(7) sur la table indique.
REFERENCES
Ce droit est requis sur les colonnes de rfrence et les colonnes qui rfrencent pour crer une contrainte de cl trangre. Le
droit peut tre accord pour toutes les colonnes, ou seulement des colonnes spcifiques.
TRIGGER
Autorise la cration d'un dclencheur sur la table indique. (Voir l'instruction CREATE TRIGGER(7).)
CREATE
Pour les bases de donnes, autorise la cration de nouveaux schmas dans la base de donnes.
1067

GRANT

Pour les schmas, autorise la cration de nouveaux objets dans le schma. Pour renommer un objet existant, il est ncessaire
d'en tre le propritaire et de possder ce droit sur le schma qui le contient.
Pour les tablespaces, autorise la cration de tables, d'index et de fichiers temporaires dans le tablespace et autorise la cration
de bases de donnes utilisant ce tablespace par dfaut. (Rvoquer ce privilge ne modifie pas l'emplacement des objets existants.)
CONNECT
Autorise l'utilisateur se connecter la base indique. Ce droit est vrifi la connexion (en plus de la vrification des restrictions imposes par pg_hba.conf).
TEMPORARY, TEMP
Autorise la cration de tables temporaires lors de l'utilisation de la base de donnes spcifie.
EXECUTE
Autorise l'utilisation de la fonction indique et l'utilisation de tout oprateur dfini sur cette fonction. C'est le seul type de
droit applicable aux fonctions. (Cette syntaxe fonctionne aussi pour les fonctions d'agrgat.)
USAGE
Pour les langages procduraux, autorise l'utilisation du langage indiqu pour la cration de fonctions. C'est le seul type de
droit applicable aux langages procduraux.
Pour les schmas, autorise l'accs aux objets contenus dans le schma indiqu (en supposant que les droits des objets soient
respects). Cela octroie, pour l'essentiel, au bnficiaire le droit de consulter les objets contenus dans ce schma. Sans ce
droit, il est toujours possible de voir les noms des objets en lanant des requtes sur les tables systme. De plus, aprs avoir
rvoqu ce droit, les processus serveur existants pourraient recevoir des requtes qui ont dj ralis cette recherche auparavant, donc ce n'est pas un moyen compltement scuris d'empcher l'accs aux objets.
Pour les squences, ce droit autorise l'utilisation des fonctions currval et nextval.
Pour des wrappers de donnes distantes, ce droit autorise son bnficiaire crer de nouveaux serveurs utilisant ce wrapper.
Pour les serveurs distants, ce droit autorise son bnficiaire crer, modifier et supprimer les correspondances utilisateur de
l'utilisateur associ ce serveur. De plus, il autorise son bnficiaire interroger les options du serveur et les correspondances
d'utilisateurs associes.
ALL PRIVILEGES
Octroie tous les droits disponibles en une seule opration. Le mot cl PRIVILEGES est optionnel sous PostgreSQL mais
est requis dans le standard SQL.
Les droits requis par les autres commandes sont lists sur les pages de rfrence de ces commandes.

GRANT sur les rles


Cette variante de la commande GRANT dfinit l'appartenance d'un (ou plusieurs) rle(s) un autre. L'appartenance un rle est
importante car elle offre tous les droits accords un rle l'ensemble de ses membres.
Si WITH ADMIN OPTION est spcifi, le membre peut la fois en octroyer l'appartenance d'autres rles, et la rvoquer. Sans
cette option, les utilisateurs ordinaires ne peuvent pas le faire. Un rle ne dispose pas de l'option WITH ADMIN OPTION luimme mais il peut donner ou enlever son appartenance partir d'une session o l'utilisateur correspond au rle. Les superutilisateurs peuvent donner ou supprimer l'appartenance tout rle. Les rles disposant de l'attribut CREATEROLE peuvent donner ou
supprimer l'appartenance tout rle qui n'est pas un superutilisateur.
Contrairement au cas avec les droits, l'appartenance un rle ne peut pas tre donn PUBLIC. Notez aussi que ce format de la
commande n'autorise pas le mot GROUP.

Notes
La commande REVOKE(7) est utilise pour retirer les droits d'accs.
Depuis PostgreSQL 8.1, le concept des utilisateurs et des groupes a t unifi en un seul type d'entit appel rle. Il n'est donc
plus ncessaire d'utiliser le mot cl GROUP pour indiquer si le bnficiaire est un utilisateur ou un groupe. GROUP est toujours autoris dans cette commande mais est ignor.
Un utilisateur peut excuter des SELECT, INSERT, etc. sur une colonne si il a le privilge soit sur cette colonne spcifique, soit
sur la table entire. Donner un privilge de table puis le rvoquer pour une colonne ne fera pas ce que vous pourriez esprer :
l'autorisation au niveau de la table n'est pas affecte par une opration au niveau de la colonne.
Quand un utilisateur, non propritaire d'un objet, essaie d'octroyer des droits sur cet objet, la commande choue si l'utilisateur n'a
aucun droit sur l'objet. Tant que des privilges existent, la commande s'excute, mais n'octroie que les droits pour lesquels
1068

GRANT

l'utilisateur dispose de l'option de transmission. Les formes GRANT ALL PRIVILEGES engendrent un message d'avertissement
si aucune option de transmission de droit n'est dtenue, tandis que les autres formes n'engendrent un message que lorsque les options de transmission du privilge concern par la commande ne sont pas dtenues. (Cela s'applique aussi au propritaire de l'objet,
mais comme on considre toujours que ce dernier dtient toutes les options de transmission, le problme ne se pose jamais.)
Les superutilisateurs de la base de donnes peuvent accder tous les objets sans tenir compte des droits qui les rgissent. Cela est
comparable aux droits de root sur un systme Unix. Comme avec root, il est dconseill d'oprer en tant que superutilisateur,
sauf en cas d'imprieuse ncessit.
Si un superutilisateur lance une commande GRANT ou REVOKE, tout se passe comme si la commande tait excute par le propritaire de l'objet concern. Les droits octroys par cette commande semblent ainsi l'avoir t par le propritaire de l'objet.
(L'appartenance rle, elle, semble tre donne par le rle conteneur.)
GRANT et REVOKE peuvent aussi tre excutes par un rle qui n'est pas le propritaire de l'objet considr, mais est membre
du rle propritaire de l'objet, ou membre du rle titulaire du privilge WITH GRANT OPTION sur cet objet. Dans ce cas, les
droits sont enregistrs comme donns par le rle propritaire de l'objet ou titulaire du privilge WITH GRANT OPTION. Par
exemple, si la table t1 appartient au rle g1, dont le rle u1 est membre, alors u1 peut donner les droits sur t1 u2, mais ces
droits apparaissent octroys directement par g1. Tout autre membre du rle g1 peut les rvoquer par la suite.
Si le rle qui excute GRANT dtient, de manire indirecte, les droits souhaits travers plus d'un niveau d'appartenance, il est
difficile de prvoir le rle reconnu comme fournisseur du privilge. Dans de tels cas, le meilleur moyen d'utiliser SET ROLE est
de devenir le rle qui doit octroyer les droits.
Donner un droit sur une table n'tend pas automatiquement les droits sur les squences utilises par cette table, ceci incluant les
squences lies par des colonnes de type SERIAL. Les droits sur les squences doivent tre donns sparment.
La commande \dp de psql(1) permet d'obtenir des informations sur les droits existants pour les tables et colonnes, par exemple :
=> \z matable
Access privileges
Schema | Name
| Type |
Access privileges
| Column access privileges
--------+---------+-------+-----------------------+-------------------------public | mytable | table | miriam=arwdDxt/miriam | col1:
: =r/miriam
:
miriam_rw=rw/miriam
: admin=arw/miriam
(1 row)
Les entres affiches par \dp sont interprtes ainsi :
rolename=xxxx -- privileges granted to a role
=xxxx -- privileges granted to PUBLIC
r
w
a
d
D
x
t
X
U
C
c
T
arwdDxt
*

---------------

SELECT ("lecture")
UPDATE ("criture")
INSERT ("ajout")
DELETE
TRUNCATE
REFERENCES
TRIGGER
EXECUTE
USAGE
CREATE
CONNECT
TEMPORARY
ALL PRIVILEGES (pour les tables, varie pour les autres objets)
option de transmission du privilge qui prcde

/yyyy -- role qui a donn le droit


L'exemple ci-dessus prsente ce que voit l'utilisatrice miriam aprs la cration de la table matable et l'excution de :
GRANT SELECT ON matable TO PUBLIC;
GRANT SELECT, UPDATE, INSERT ON matable TO admin;
GRANT SELECT (col1), UPDATE (col1) ON matable TO miriam_rw;
Pour les objects non-tables, il y a d'autres commandes \d qui peuvent afficher leurs privilges.
Si la colonne Access privileges est vide pour un objet donn, cela signifie que l'objet possde les droits par dfaut (c'est--dire
que la colonne des droits est NULL). Les droits par dfaut incluent toujours les droits complets pour le propritaire et peuvent inclure quelques droits pour PUBLIC en fonction du type d'objet comme cela est expliqu plus haut. Le premier GRANT ou RE1069

GRANT

VOKE sur un objet instancie les droits par dfaut (produisant, par exemple, {=,miriam=arwdDxt/miriam}) puis les modifie en fonction de la requte spcifie. Les entres sont affiches en Privilges d'accs aux colonnes seulement pour les colonnes qui ont des privilges diffrents de ceux par dfaut. (Notez que, dans ce but, default privileges signifie toujours les
droits par dfaut inhrents au type de l'objet. Un objet dont les droits ont t modifis avec la commande ALTER DEFAULT
PRIVILEGES sera toujours affich avec une entre de droit effective qui inclut les effets de la commande ALTER.)
Les options de transmission de privilges implicites du propritaire ne sont pas indiques dans l'affichage des droits d'accs. Une
* apparat uniquement lorsque les options de transmission ont t explicitement octroyes.

Exemples
Donner le droit d'insertion tous les utilisateurs sur la table films :
GRANT INSERT ON films TO PUBLIC;
Donner tous les droits possibles l'utilisateur manuel sur la vue genres :
GRANT ALL PRIVILEGES ON genres TO manuel;
Bien que la commande ci-dessus donne tous les droits lorsqu'elle est excute par un superutilisateur ou par le propritaire de
genres, excute par quelqu'un d'autre, elle n'accorde que les droits pour lesquels cet utilisateur possde l'option de transmission.
Rendre joe membre de admins :
GRANT admins TO joe;

Compatibilit
Conformment au standard SQL, le mot cl PRIVILEGES est requis dans ALL PRIVILEGES. Le standard SQL n'autorise pas
l'initialisation des droits sur plus d'un objet par commande.
PostgreSQL autorise un propritaire d'objet rvoquer ses propres droits ordinaires : par exemple, le propritaire d'un objet peut
le placer en lecture seule pour lui-mme en rvoquant ses propres droits INSERT, UPDATE, DELETE et TRUNCATE. Le standard
SQL ne l'autorise pas. La raison en est que PostgreSQL traite les droits du propritaire comme ayant t donns par le propritaire ; il peut, de ce fait, aussi les rvoquer. Dans le standard SQL, les droits du propritaire sont donns par une entit
_SYSTEM . N'tant pas _SYSTEM , le propritaire ne peut pas rvoquer ces droits.
Le standard SQL fournit un droit USAGE sur d'autres types d'objet : jeux de caractres, collations, conversions, domaines.
Les droits sur les bases de donnes, tablespaces, langages, schmas et squences sont des extensions PostgreSQL.

Voir aussi
REVOKE(7), ALTER DEFAULT PRIVILEGES(7)

1070

Nom
INSERT Insrer de nouvelles lignes dans une table

Synopsis
[ WITH [ RECURSIVE ] requte_with [, ...] ]
INSERT INTO table [ ( colonne [, ...] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | requte
}
[ RETURNING * | expression_sortie [ [ AS ] nom_sortie ] [, ...] ]

Description
INSERT insre de nouvelles lignes dans une table. Vous pouvez insrer une ou plusieurs lignes spcifies par les expressions
de valeur, ou zro ou plusieurs lignes provenant d'une requte.
L'ordre des noms des colonnes n'a pas d'importance. Si aucune liste de noms de colonnes n'est donne, toutes les colonnes de la
table sont utilise dans l'ordre de leur dclaration (les N premiers noms de colonnes si seules N valeurs de colonnes sont fournies
dans la clause VALUES ou dans la requte). Les valeurs fournies par la clause VALUES ou par la requte sont associes
la liste explicite ou implicite des colonnes de gauche droite.
Chaque colonne absente de la liste, implicite ou explicite, des colonnes se voit attribuer sa valeur par dfaut, s'il y en a une, ou
NULL dans le cas contraire.
Un transtypage automatique est entrepris lorsque l'expression d'une colonne ne correspond pas au type de donne dclar.
La clause RETURNING optionnelle fait que INSERT calcule et renvoie le(s) valeur(s) base(s) sur chaque ligne en cours
d'insertion. C'est principalement utile pour obtenir les valeurs qui ont t fournies par dfaut, comme un numro de squence.
Nanmoins, toute expression utilisant les colonnes de la table est autorise. La syntaxe de la liste RETURNING est identique
celle de la commande SELECT.
Le droit INSERT sur une table est requis pour pouvoir y insrer des lignes. Si une liste de colonne est indique, vous avez
seulement besoin d'avoir le droit INSERT sur les colonnes listes. L'utilisation de la clause RETURNING ncessite le droit SELECT sur tous les colonnes mentionnes dans RETURNING. Si la clause requte est utilise pour insrer des lignes, le droit
SELECT sur toute table ou colonne utilise dans la requte est galement requis.

Paramtres
with_query
La clause WITH vous permet de spcifier une ou plusieurs sous-requtes qui peuvent tre rfrences par nom dans la requte INSERT. Voir Section 7.8, Requtes WITH (Common Table Expressions) et SELECT(7) pour des dtails.
Il est possible que la requte (instruction SELECT) contienne aussi une clause WITH. Dans ce cas, les deux ensembles
de requte_with peuvent tre rfrencs l'intrieur de la requte mais la deuxime prend prcdence car elle est
plus fortement imbrique.
table
Le nom de la table (ventuellement qualifi du nom du schma).
colonne
Le nom d'une colonne de table. Le nom de la colonne peut tre qualifi avec un nom de sous-champ ou un indice de tableau, si ncessaire. (N'insrer que certains champs d'une colonne composite laisse les autres champs NULL.)
DEFAULT VALUES
Toutes les colonnes se voient attribuer leur valeur par dfaut.
expression
Une expression ou une valeur affecter la colonne correspondante.
DEFAULT
La colonne correspondante se voit attribuer sa valeur par dfaut.
requte
Une requte (instruction SELECT) dont le rsultat fournit les lignes insrer. La syntaxe complte de la commande est dcrite dans la documentation de l'instruction SELECT(7).

1071

INSERT

expression_sortie
Une expression calculer et renvoye par la commande INSERT aprs chaque insertion de ligne. L'expression peut utiliser
tout nom de colonne de la table. Indiquez * pour que toutes les colonnes soient renvoyes.
nom_sortie
Un nom utiliser pour une colonne renvoye.

Sorties
En cas de succs, la commande INSERT renvoie un code de la forme
INSERT oid nombre
nombre correspond au nombre de lignes insres. Si nombre vaut exactement un et que la table cible contient des OID, alors
oid est l'OID affect la ligne insre. Sinon, oid vaut zro.
Si la commande INSERT contient une clause RETURNING, le rsultat sera similaire celui d'une instruction SELECT contenant
les colonnes et les valeurs dfinies dans la liste RETURNING, partir de la liste des lignes insres par la commande.

Exemples
Insrer une ligne dans la table films :
INSERT INTO films
VALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comdie', '82 minutes');
Dans l'exemple suivant, la colonne longueur est omise et prend donc sa valeur par dfaut :
INSERT INTO films (code, titre, did, date_prod, genre)
VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drame');
L'exemple suivant utilise la clause DEFAULT pour les colonnes date plutt qu'une valeur prcise :
INSERT INTO films VALUES
('UA502', 'Bananas', 105, DEFAULT, 'Comdie', '82 minutes');
INSERT INTO films (code, titre, did, date_prod, genre)
VALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drame');
Insrer une ligne constitue uniquement de valeurs par dfaut :
INSERT INTO films DEFAULT VALUES;
Pour insrer plusieurs lignes en utilisant la syntaxe multi-lignes VALUES :
INSERT INTO films (code, titre, did, date_prod, genre) VALUES
('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
Insrer dans la table films des lignes extraites de la table tmp_films (la disposition des colonnes est identique dans les deux
tables) :
INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
Insrer dans des colonnes de type tableau :
-- Crer un jeu de 3 cases sur 3
INSERT INTO tictactoe (game, board[1:3][1:3])
VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}');
-- Les indices de l'exemple ci-dessus ne sont pas vraiment ncessaires
INSERT INTO tictactoe (game, board)
VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}');
Insrer une ligne simple dans la table distributeurs, en renvoyant le numro de squence gnr par la clause DEFAULT :
INSERT INTO distributeurs (did, dnom) VALUES (DEFAULT, 'XYZ Widgets')
RETURNING did;
Augmenter le nombre de ventes du vendeur qui gre le compte Acme Corporation, et enregistrer la ligne compltement mise
jour avec l'heure courante dans une table de traage :
1072

INSERT

WITH upd AS (
UPDATE employees SET sales_count = sales_count + 1 WHERE id =
(SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')
RETURNING *
)
INSERT INTO employees_log SELECT *, current_timestamp FROM upd;

Compatibilit
INSERT est conforme au standard SQL, sauf la clause RETURNING qui est une extension PostgreSQL, comme la possibilit
d'utiliser la clause WITH avec l'instruction INSERT. Le standard n'autorise toutefois pas l'omission de la liste des noms de colonnes alors qu'une valeur n'est pas affecte chaque colonne, que ce soit l'aide de la clause VALUES ou partir de la
requte.
Les limitations possibles de la clause requte sont documentes sous SELECT(7).

1073

Nom
LISTEN Attendre une notification

Synopsis
LISTEN canal

Description
LISTEN enregistre la session courante comme listener du canal de notification canal. Si la session courante est dj enregistre comme listener de ce canal de notification, il ne se passe rien de plus.
chaque appel de la commande NOTIFY canal, que ce soit par cette session ou par une autre connecte la mme base de
donnes, toutes les sessions attendant sur ce canal en sont avises et chacune en avise en retour son client. Voir NOTIFY pour
plus d'informations.
La commande UNLISTEN permet d'annuler l'enregistrement d'une session comme listener d'un canal de notification. Les enregistrements d'coute d'une session sont automatiquement effacs lorsque la session se termine.
La mthode utilis par un client pour dtecter les vnements de notification dpend de l'interface de programmation PostgreSQL qu'il utilise. Avec la bibliothque libpq, l'application excute LISTEN comme une commande SQL ordinaire, puis appelle priodiquement la fonction PQnotifies pour savoir si un vnement de notification est reu. Les autres interfaces, telle
libpgtcl, fournissent des mthodes de plus haut niveau pour grer les vnements de notification ; en fait, avec libpgtcl, le dveloppeur de l'application n'a mme pas lancer LISTEN ou UNLISTEN directement. Tous les dtails se trouvent dans la documentation de l'interface utilise.
NOTIFY(7) dcrit plus en dtails l'utilisation de LISTEN et NOTIFY.

Paramtres
canal
Le nom d'un canal de notification (tout identifiant).

Notes
LISTEN prend effet la validation de la transaction. Si LISTEN ou UNLISTEN est excut dans une transaction qui sera ensuite annule, l'ensemble des canaux de notification couts sera inchang.
Une transaction qui a excut LISTEN ne peut pas tre prpare pour la validation en deux phases.

Exemples
Configurer et excuter une squence listen/notify partir de psql :
LISTEN virtual;
NOTIFY virtual;
Notification asynchrone "virtual" reue en provenance du processus serveur de PID
8448.

Compatibilit
Il n'existe pas d'instruction LISTEN dans le standard SQL.

Voir aussi
NOTIFY(7), UNLISTEN(7)

1074

Nom
LOAD Charger une bibliothque partage

Synopsis
LOAD 'fichier'

Description
Cette commande charge une bibliothque partage dans l'espace d'adressage de PostgreSQL. Si le fichier a dj t charg, la
commande ne fait rien. Les fichiers des bibliothques partages contenant des fonctions C sont automatiquement chargs
chaque fois qu'une de leur fonctions est appele. Du coup, un appel explicite LOAD est habituellement seulement ncessaire
pour charger une bibliothque qui modifie le comportement du serveur via des points d'accroche plutt qu'en fournissant un
ensemble de fonctions.
Le nom du fichier est indiqu de la mme faon que pour les noms de bibliothques partages dans CREATE FUNCTION(7) ;
il est, en particulier, possible d'utiliser un chemin de recherche et l'ajout automatique de l'extension de la bibliothque partage,
suivant les standards systme. Voir Section 35.9, Fonctions en langage C pour plus d'informations sur ce thme.
Les utilisateurs normaux peuvent seulement utiliser LOAD avec des bibliothques situes dans $libdir/plugins/ -- le
nom_fichier indiqu doit commencer avec cette chane exacte. (Il est de la responsabilit de l'administrateur de bases de
donnes de s'assurer que seules des bibliothques sres y sont installes.)

Compatibilit
LOAD est une extension PostgreSQL.

Voir aussi
CREATE FUNCTION(7)

1075

Nom
LOCK verrouiller une table

Synopsis
LOCK [ TABLE ] [ ONLY ] nom [ * ] [, ...] [ IN mode_verrou MODE ] [ NOWAIT ]
o mode_verrou peut tre :
ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE
ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

Description
LOCK TABLE prend un verrou de niveau table, attendant si ncessaire que tout verrou conflictuel soit relch. Si NOWAIT est
spcifi, LOCK TABLE n'attend pas l'acquisition du verrou dsir : s'il ne peut pas tre obtenu immdiatement, la commande
est annule et une erreur est mise. Une fois obtenu, le verrou est conserv jusqu' la fin de la transaction en cours. (Il n'y a pas
de commande UNLOCK TABLE ; les verrous sont systmatiquement relchs la fin de la transaction.)
Lors de l'acquisition automatique de verrous pour les commandes qui rfrencent des tables, PostgreSQL utilise toujours le
mode de verrou le moins restrictif possible. LOCK TABLE est utilisable lorsqu'il est ncessaire d'obtenir des verrous plus restrictifs.
Soit, par exemple, une application qui excute une transaction de niveau d'isolation lecture des valids (Read Committed).
Pour s'assurer que les donnes de la table sont immuables pendant toute la dure de la transaction, un verrou SHARE de niveau
table peut tre obtenu avant d'effectuer la requte. Cela empche toute modification concurrente des donnes. Cela assure galement que toute lecture intervenant ensuite sur la table accde la mme vue des donnes valides. En effet, un verrou SHARE
entre en conflit avec le verrou ROW EXCLUSIVE pris par les modificateurs et l'instruction LOCK TABLE nom IN SHARE
MODE attend que tout dtenteur concurrent de verrous de mode ROW EXCLUSIVE valide ou annule. De ce fait, une fois le
verrou obtenu, il ne reste aucune criture non valide en attente ; de plus, aucune ne peut commencer tant que le verrou acquis
n'est pas relch.
Pour obtenir un effet similaire lors de l'excution d'une transaction de niveau d'isolation REPEATABLE READ ou SERIALIZABLE, il est ncessaire d'excuter l'instruction LOCK TABLE avant toute instruction SELECT ou de modification de donnes. La vue des donnes utilise par une transaction REPEATABLE READ or SERIALIZABLE est fige au moment o dbute
la premire instruction SELECT ou de modification des donnes. Un LOCK TABLE ultrieur empche encore les critures
concurrentes -- mais il n'assure pas que la transaction lit les dernires donnes valides.
Si une telle transaction modifie les donnes de la table, elle doit utiliser le mode de verrou SHARE ROW EXCLUSIVE au lieu
du mode SHARE. Cela assure l'excution d'une seule transaction de ce type la fois. Sans cela, une situation de verrou mort est
possible : deux transactions peuvent acqurir le mode SHARE et tre ensuite incapables d'acqurir aussi le mode ROW EXCLUSIVE pour rellement effectuer leurs mises jour. (Les verrous d'une transaction ne sont jamais en conflit. Une transaction peut
de ce fait acqurir le mode ROW EXCLUSIVE alors qu'elle dtient le mode SHARE -- mais pas si une autre transaction dtient le
mode SHARE.) Pour viter les verrous bloquants, il est prfrable que toutes les transactions qui acquirent des verrous sur les
mmes objets le fassent dans le mme ordre. De plus si de multiples modes de verrous sont impliqus pour un mme objet, le
verrou de mode le plus restrictif doit tre acquis le premier.
Plus d'informations sur les modes de verrou et les stratgies de verrouillage sont disponibles dans Section 13.3, Verrouillage
explicite .

Paramtres
nom
Le nom d'une table verrouiller (ventuellement qualifi du nom du schma). Si ONLY est prcis avant le nom de la table,
seule cette table est verrouille. Dans le cas contraire, la table et toutes ses tables filles (si elle en a) sont verrouilles. En
option, * peut tre plac aprs le nom de la table pour indiquer explicitement que les tables filles sont inclues.
La commande LOCK a, b; est quivalente LOCK a; LOCK b;. Les tables sont verrouilles une par une dans l'ordre
prcis par la commande LOCK TABLE.
modeverrou
Le mode de verrou prcise les verrous avec lesquels ce verrou entre en conflit. Les modes de verrou sont dcrits dans Section 13.3, Verrouillage explicite .
1076

LOCK

Si aucun mode de verrou n'est prcis, ACCESS EXCLUSIVE, mode le plus restrictif, est utilis.
NOWAIT
LOCK TABLE n'attend pas que les verrous conflictuels soient relchs : si le verrou indiqu ne peut tre acquis immdiatement sans attente, la transaction est annule.

Notes
LOCK TABLE ... IN ACCESS SHARE MODE requiert les droits SELECT sur la table cible. Toutes les autres formes de
LOCK requirent au moins un des droits UPDATE, DELETE et TRUNCATE au niveau table.
LOCK TABLE est inutile l'extrieur d'un bloc de transaction : le verrou est dtenu jusqu' la fin de l'instruction. Du coup, PostgreSQL renvoie une erreur si LOCK est utilis en dehors d'un bloc de transaction. Utilisez BEGIN(7) et COMMIT(7) (ou
ROLLBACK(7)) pour dfinir un bloc de transaction.
LOCK TABLE ne concernent que les verrous de niveau table. Les noms de mode contenant ROW sont donc tous mal nomms.
Ces noms de modes doivent gnralement tre compris comme indiquant l'intention de l'utilisateur d'acqurir des verrous de niveau ligne l'intrieur de la table verrouille. Le mode ROW EXCLUSIVE est galement un verrou de table partageable. Tous les
modes de verrou ont des smantiques identiques en ce qui concerne LOCK TABLE ; ils ne diffrent que dans les rgles de conflit
entre les modes. Pour des informations sur la faon d'acqurir un vrai verrou de niveau ligne, voir Section 13.3.2, Verrous au niveau ligne et la section intitule Clause FOR UPDATE/FOR SHARE dans la documentation de rfrence de SELECT.

Exemples
Obtenir un verrou SHARE sur une table avec cl primaire avant de raliser des insertions dans une table disposant de la cl trangre :
BEGIN WORK;
LOCK TABLE films IN SHARE MODE;
SELECT id FROM films
WHERE nom = 'Star Wars : Episode I - La menace fantme';
-- Effectuer un ROLLBACK si aucun enregistrement n'est retourn
INSERT INTO commentaires_films VALUES
(_id_, 'SUPER ! Je l''attendais depuis si longtemps !');
COMMIT WORK;
Prendre un verrou SHARE ROW EXCLUSIVE sur une table avec cl primaire lors du dbut des oprations de suppression :
BEGIN WORK;
LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
DELETE FROM commentaires_films WHERE id IN
(SELECT id FROM films WHERE score < 5);
DELETE FROM films WHERE score < 5;
COMMIT WORK;

Compatibilit
LOCK TABLE n'existe pas dans le standard SQL. la place, il utilise SET TRANSACTION pour spcifier les niveaux de
concurrence entre transactions. PostgreSQL en dispose galement ; voir SET TRANSACTION(7) pour les dtails.
l'exception des modes de verrous ACCESS SHARE, ACCESS EXCLUSIVE et SHARE UPDATE EXCLUSIVE, les modes de
verrou PostgreSQL et la syntaxe LOCK TABLE sont compatibles avec ceux prsents dans Oracle.

1077

Nom
MOVE positionner un curseur

Synopsis
MOVE [ direction [ FROM | IN ] ] nom_curseur
o direction peut tre
vide ou faire partie de :
NEXT
PRIOR
FIRST
LAST
ABSOLUTE nombre
RELATIVE nombre
nombre
ALL
FORWARD
FORWARD nombre
FORWARD ALL
BACKWARD
BACKWARD nombre
BACKWARD ALL

Description
MOVE repositionne un curseur sans retourner de donne. MOVE fonctionne exactement comme la commande FETCH la
diffrence que MOVE ne fait que positionner le curseur et ne retourne aucune ligne.
Les paramtres de la commande MOVE sont identiques ceux de la commande FETCH. FETCH(7) contient les dtails de
syntaxe et d'utilisation.

Sortie
En cas de russite, une commande MOVE retourne une balise de commande de la forme
MOVE compteur
compteur est le nombre de lignes qu'une commande FETCH avec les mmes paramtres aurait renvoye (ventuellement zro).

Exemples
BEGIN WORK;
DECLARE liahona CURSOR FOR SELECT * FROM films;
-- Saute les 5 premires lignes :
MOVE FORWARD 5 IN liahona;
MOVE 5
-- Rcupre la 6me ligne partir du curseur liahona :
FETCH 1 FROM liahona;
code | titre | did | date_prod | genre | longueur
-------+--------+-----+------------+--------+----------P_303 | 48 Hrs | 103 | 1982-10-22 | Action | 01:37
(1 row)
-- Ferme le curseur liahona et termine la transaction :
CLOSE liahona;
COMMIT WORK;

Compatibilit
Il n'existe pas d'instruction MOVE dans le standard SQL.
1078

MOVE

Voir aussi
CLOSE(7), DECLARE(7), FETCH(7)

1079

Nom
NOTIFY engendrer une notification

Synopsis
NOTIFY canal [ , charge ]

Description
La commande NOTIFY envoie une notification avec une chane de charge supplmentaire chaque application cliente qui a
excut prcdemment la commande LISTEN canal dans la base de donnes courante pour le nom du canal indiqu.
NOTIFY fournit un mcanisme simple de communication interprocessus pour tout ensemble de processus accdant la mme
base de donnes PostgreSQL. Une chane de charge peut tre envoye avec la notification, et des mcanismes de plus haut niveau permettant de passer des donnes structures peuvent tre construits en utilisant les tables de la base de donnes.
L'information passe au client pour une notification inclut le nom de la notification et le PID du processus serveur de la session
le notifiant.
C'est au concepteur de la base de donnes de dfinir les noms de notification utiliss dans une base de donnes prcise et la signification de chacun. Habituellement, le nom du canal correspond au nom d'une table dans la base de donnes. L'vnement
notify signifie essentiellement J'ai modifi cette table, jetez-y un il pour vrifier ce qu'il y a de nouveau . Mais cette association n'est pas contrle par les commandes NOTIFY et LISTEN. Un concepteur de bases de donnes peut, par exemple, utiliser plusieurs noms de canal diffrents pour signaler diffrentes sortes de modifications au sein d'une mme table. Sinon, la
chane de charge peut tre utilise pour diffrencier plusieurs cas.
Lorsque NOTIFY est utilis pour signaler des modifications sur une table particulire, une technique de programmation utile
est de placer le NOTIFY dans une rgle dclenche par les mises jour de la table. De cette faon, la notification est automatique lors d'une modification de la table et le programmeur de l'application ne peut accidentellement oublier de le faire.
NOTIFY interagit fortement avec les transactions SQL. Primo, si un NOTIFY est excut l'intrieur d'une transaction, les
vnements notify ne sont pas dlivrs avant que la transaction ne soit valide, et cette condition uniquement. En effet, si la
transaction est annule, les commandes qu'elle contient n'ont aucun effet, y compris NOTIFY. Cela peut toutefois s'avrer dconcertant pour quiconque s'attend une dlivrance immdiate des notifications.
Secondo, si une session l'coute reoit un signal de notification alors qu'une transaction y est active, la notification n'est pas
dlivre au client connect avant la fin de cette transaction (par validation ou annulation). L encore, si une notification est dlivre l'intrieur d'une transaction finalement annule, on pourrait esprer annuler cette notification par quelque moyen -- mais
le serveur ne peut pas reprendre une notification dj envoye au client. C'est pourquoi les notifications ne sont dlivrs
qu'entre les transactions. Il est, de ce fait, important que les applications qui utilisent NOTIFY pour l'envoi de signaux en temps
rel conservent des transactions courtes.
Si le mme nom de canal est signal plusieurs fois partir de la mme transaction avec des chanes de charge identiques, le serveur de bases de donnes peut dcider de dlivrer une seule notification. Par contre, les notifications avec des chanes de charges
distinctes seront toujours dlivres par des notifications distinctes. De faon similaire, les notifications provenant de diffrentes
transactions ne seront jamais regroupes en une seule notification. Sauf pour supprimer des instances ultrieures de notifications
dupliques, la commande NOTIFY garantie que les notifications de la mme transaction seront dlivres dans l'ordre o elles
ont t envoyes. Il est aussi garantie que les messages de transactions diffrentes seront dlivres dans l'ordre dans lequel les
transactions ont t valides.
Il est courant qu'un client qui excute NOTIFY coute lui-mme des notifications de mme canal. Dans ce cas, il rcupre une
notification, comme toutes les autres sessions en coute. Suivant la logique de l'application, cela peut engendre un travail inutile,
par exemple lire une table de la base de donnes pour trouver les mises jour que cette session a elle-mme crites. Il est possible d'viter ce travail supplmentaire en verifiant si le PID du processus serveur de la session notifiante (fourni dans le message d'vnement de la notification) est le mme que le PID de la session courante (disponible partir de libpq). S'ils sont identiques, la notification est le retour du travail actuel et peut tre ignore.

Paramtres
canal
Nom du canal signaler (identifiant quelconque).
charge
La chane de charge communiquer avec la notification. Elle doit tre spcifie comme une chane litrale. Dans la
1080

NOTIFY

configuration par dfaut, elle doit avoir une taille infrieure 8000 octets. (Si des donnes binaires ou de tailles plus importantes doivent tre communiques, il est mieux de les placer dans une table de la base et d'envoyer la cl correspondant
l'enregistrement.)

Notes
Il existe une queue qui rcupre les notifications qui ont t envoyes mais pas encore traites par les sessions en coute. Si la
queue est remplie, les transactions appelant NOTIFY choueront la validation. La queue est assez large (8 Go dans une installation standard) et devrait tre suffisamment bien taille dans la majorit des cas. Nanmoins, aucun nettoyage ne peut se faire si
une session excute LISTEN puis entre en transaction pendant une longue priode. Une fois qu'une queue est moiti pleine, des
messages d'avertissements seront envoys dans les traces indiquant la session qui empche le nettoyage. Dans ce cas, il faut
s'assurer que la session termine sa transaction en cours pour que le nettoyage puisse se faire.
Une transaction qui a excut NOTIFY ne peut pas tre prpare pour une validation en deux phases.

pg_notify
Pour envoyer une notification, vous pouvez aussi utiliser la fonction pg_notify(text, text). La fonction prend en premier
argument le nom du canal et en second la charge. La fonction est bien plus simple utiliser que la commande NOTIFY si vous
avez besoin de travailler avec des noms de canaux et des charges non constants.

Exemples
Configurer et excuter une squence listen/notify partir de psql :
LISTEN virtual;
NOTIFY virtual;
Asynchronous notification "virtual" received from server process with PID 8448.
NOTIFY virtual, 'This is the payload';
Asynchronous notification "virtual" with payload "This is the payload" received from
server process with PID 8448.
LISTEN foo;
SELECT pg_notify('fo' || 'o', 'pay' || 'load');
Asynchronous notification "foo" with payload "payload" received from server process
with PID 14728.

Compatibilit
Il n'y a pas d'instruction NOTIFY dans le standard SQL.

Voir aussi
LISTEN(7), UNLISTEN(7)

1081

Nom
PREPARE prpare une instruction pour excution

Synopsis
PREPARE nom [ (type_donnes [, ...] ) ] AS instruction

Description
PREPARE cre une instruction prpare. Une instruction prpare est un objet ct serveur qui peut tre utilis pour optimiser
les performances. Quand l'instruction PREPARE est excute, l'instruction spcifie est analyse, rcrite et planifie. Quand
une commande EXECUTE est lance par la suite, l'instruction prpare a seulement besoin d'tre excute. Du coup, les tapes
d'analyse, de rcriture et de planification sont ralises une seule fois, la place de chaque fois que l'instruction est excute.
Les instructions prpares peuvent prendre des paramtres : les valeurs sont substitues dans l'instruction lorsqu'elle est excute. Lors de la cration de l'instruction prpare, faites rfrence aux paramtres suivant leur position, $1, $2, etc. Une liste correspondante des types de donnes des paramtres peut tre spcifie si vous le souhaitez. Quand le type de donne d'un paramtre n'est pas indiqu ou est dclar comme inconnu (unknown), le type est infr partir du contexte dans lequel le paramtre est utilis (si possible). Lors de l'excution de l'instruction, indiquez les valeurs relles de ces paramtres dans l'instruction
EXECUTE. Rfrez-vous EXECUTE(7) pour plus d'informations ce sujet.
Les instructions prpares sont seulement stockes pour la dure de la session en cours. Lorsque la session se termine,
l'instruction prpare est oublie et, du coup, elle doit tre recre avant d'tre utilise de nouveau. Ceci signifie aussi qu'une
seule instruction prpare ne peut pas tre utilise par plusieurs clients de bases de donnes simultanment ; nanmoins, chaque
client peut crer sa propre instruction prpare utiliser. L'instruction prpare peut tre supprims manuellement en utilisant la
commande DEALLOCATE(7).
Les instructions prpares sont principalement intressantes quand une seule session est utilise pour excuter un grand nombre
d'instructions similaires. La diffrence de performances est particulirement significative si les instructions sont complexes
planifier ou rcrire, par exemple, si la requte implique une jointure de plusieurs tables ou requiert l'application de diffrentes
rgles. Si l'instruction est relativement simple planifier ou rcrire mais assez coteuse excuter, l'avantage de performance
des instructions prpares est moins net.

Paramtres
nom
Un nom quelconque donn cette instruction prpare particulire. Il doit tre unique dans une session et est utilis par la
suite pour excuter ou dsallouer cette instruction prpare.
type_donnes
Le type de donnes d'un paramtre de l'instruction prpare. Si le type de donnes d'un paramtre particulier n'est pas spcifi ou est spcifi comme tant inconnu (unknown), il sera inferr partir du contexte dans lequel le paramtre est utilis.
Pour rfrencer les paramtres de l'instruction prpare, utilisez $1, $2, etc.
instruction
Toute instruction SELECT, INSERT, UPDATE, DELETE ou VALUES.

Notes
Dans certaines situations, le plan de requte produit par une instruction prpare est infrieur au plan qui aurait t produit si
l'instruction avait t soumise et excute normalement. C'est parce que, quand l'instruction est planifie et que le planificateur
tente de dterminer le plan de requte optimal, les valeurs relles de tous les paramtres spcifis dans l'instruction ne sont pas
disponibles. PostgreSQL rcupre les statistiques de la distribution des donnes dans la table et peut utiliser les valeurs
constantes dans une instruction pour deviner le rsultat probable de l'excution de l'instruction. Comme cette donne n'est pas
disponible lors de la planification d'instructions prpares avec paramtres, le plan choisi pourrait ne pas tre optimal. Pour examiner le plan de requte que PostgreSQL a choisi pour une instruction prpare, utilisez EXPLAIN(7).
Pour plus d'informations sur la planification de la requte et les statistiques rcupres par PostgreSQL dans ce but, voir la
documentation de ANALYZE(7).
Vous pouvez voir toutes les instructions prpares disponibles d'une session en excutant une requte sur la vue systme
pg_prepared_statements.
1082

PREPARE

Exemples
Cre une instruction prpare pour une instruction INSERT, puis l'excute :
PREPARE fooplan (int, text, bool, numeric) AS
INSERT INTO foo VALUES($1, $2, $3, $4);
EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
Cre une instruction prpare pour une instruction SELECT, puis l'excute :
PREPARE usrrptplan (int) AS
SELECT * FROM users u, logs l WHERE u.usrid=$1 AND u.usrid=l.usrid
AND l.date = $2;
EXECUTE usrrptplan(1, current_date);
Note that the data type of the second parameter is not specified, so it is inferred from the context in which $2 is used.

Compatibilit
Le standard SQL inclut une instruction PREPARE mais il est seulement utilis en SQL embarqu. Cette version de l'instruction
PREPARE utilise aussi une syntaxe quelque peu diffrente.

Voir aussi
DEALLOCATE(7), EXECUTE(7)

1083

Nom
PREPARE TRANSACTION prpare la transaction en cours pour une validation en deux phases

Synopsis
PREPARE TRANSACTION id_transaction

Description
PREPARE TRANSACTION prpare la transaction courante en vue d'une validation en deux phases. la suite de cette commande, la transaction n'est plus associe la session courante ; au lieu de cela, son tat est entirement stock sur disque. La
probabilit est donc forte qu'elle puisse tre valide avec succs, y compris en cas d'arrt brutal de la base de donnes avant la
demande de validation.
Une fois prpare, une transaction peut tre valide ou annule ultrieurement par, respectivement, COMMIT PREPARED(7) et
ROLLBACK PREPARED(7). Ces commandes peuvent tre excutes partir d'une session quelconque. Il n'est pas ncessaire
de le faire depuis celle qui a excut la transaction initiale.
Du point de vue de la session l'initiant, PREPARE TRANSACTION diffre peu de la commande ROLLBACK : aprs son
excution, il n'y a plus de transaction active et les effets de la transaction prpare ne sont plus visibles. (Les effets redeviendront visibles si la transaction est valide.)
Si la commande PREPARE TRANSACTION choue, quelqu'en soit la raison, elle devient une commande ROLLBACK : la
transaction courante est annule.

Paramtres
id_transaction
Un identifiant arbitraire de la transaction pour les commandes COMMIT PREPARED et ROLLBACK PREPARED.
L'identifiant, obligatoirement de type chane littrale, doit tre d'une longueur infrieure 200 octets. Il ne peut tre identique un autre identifiant de transaction prpare.

Notes
PREPARE TRANSACTION n'a pas pour but d'tre utilis dans des applications ou des sessions interactives. Son but est de
permettre un gestionnaire de transactions externe pour raliser des transactions globales atomiques au travers de plusieurs
bases de donnes ou de ressources transactionnelles. Sauf si vous crivez un gestionnaire de transactions, vous ne devriez probablement pas utiliser PREPARE TRANSACTION.
Cette commande doit tre utilise dans un bloc de transaction, initi par BEGIN(7).
Il n'est actuellement pas possible de prparer (PREPARE) une transaction qui a excut des oprations impliquant des tables
temporaires ou qui a cr des curseurs WITH HOLD, ou qui a excut LISTEN ou UNLISTEN. Ces fonctionnalits sont trop
intgres la session en cours pour avoir la moindre utilit dans une transaction prpare.
Si la transaction a modifi des paramtres en excution l'aide de la commande SET (sans l'option LOCAL), ces effets persistent
au-del du PREPARE TRANSACTION et ne seront pas affects par les commandes COMMIT PREPARED et ROLLBACK PREPARED. Du coup, dans ce cas, PREPARE TRANSACTION agit plus comme COMMIT que comme ROLLBACK.
Toutes les transactions prpares disponibles sont listes dans la vue systme pg_prepared_xacts.

Attention
Il est prfrable de ne pas conserver trop longtemps des transactions prpares dans cet tat ; cela compromet, par
exemple, les possibilits de rcupration de l'espace par VACUUM, et dans certains cas extrmes peut causer
l'arrt de la base de donnes pour empcher une rutilisation d'identifiants de transactions (voir Section 23.1.4,
viter les cycles des identifiants de transactions ). Il ne faut pas oublier non plus qu'une telle transaction maintient les verrous qu'elle a pos. L'usage principal de cette fonctionnalit consiste valider ou annuler une transaction prpare ds lors qu'un gestionnaire de transactions externe a pu s'assurer que les autres bases de donnes
sont prpares la validation.
Si vous n'avez pas configur un gestionnaire de transactions externe pour grer les transactions prpares et vous
1084

PREPARE TRANSACTION

assurer qu'elles sont fermes rapidement, il est prfrable de dsactiver la fonctionnalit des transactions prpares
en configurant max_prepared_transactions zro. Ceci empchera toute cration accidentelle de transactions prpares qui pourraient alors tre oublies, ce qui finira par causer des problmes.

Exemples
Prparer la transaction en cours pour une validation en deux phases en utilisant foobar comme identifiant de transaction :
PREPARE TRANSACTION 'foobar';

Voir aussi
COMMIT PREPARED(7), ROLLBACK PREPARED(7)

1085

Nom
REASSIGN OWNED Modifier le propritaire de tous les objets de la base appartenant un rle spcifique

Synopsis
REASSIGN OWNED BY ancien_rle [, ...] TO nouveau_rle

Description
REASSIGN OWNED demande au systme de changer le propritaire certains objets de la base. Les objets appartenant ancien_rle auront ensuite comme propritaire nouveau_rle.

Paramtres
ancien_rle
Le nom d'un rle. Tous les objets de la base appartenant ce rle seront la proprit de nouveau_rle.
nouveau_rle
Le nom du rle qui sera le nouveau propritaire des objets affects.

Notes
REASSIGN OWNED est souvent utilis pour prparer la suppression de un ou plusieurs rles. Comme REASSIGN OWNED touche seulement les objets de la base o l'utilisateur est connect, il est gnralement ncessaire d'excuter cette commande pour chaque base contenant des objets dont le rle supprimer est propritaire.
REASSIGN OWNED ncessite des droits sur le rle source et sur le rle cible.
La commande DROP OWNED(7) est une alternative qui supprime tous les objets de la base possds par un ou plusieurs rles.
Notez aussi que DROP OWNED ncessite seulement des droits sur le rle source.
La commande REASSIGN OWNED ne modifie pas les droits donns ancien_rle pour les objets dont il n'est pas propritaire. Utilisez DROP OWNED pour supprimer ces droits.
La commande REASSIGN OWNED ne modifie pas le propritaire des bases de donnes, mme si le rle est en propritaire.
Utilisez ALTER DATABASE(7) pour modifier le propritaire des bases de donnes.

Compatibilit
L'instruction REASSIGN OWNED est une extension PostgreSQL.

Voir aussi
DROP OWNED(7), DROP ROLE(7), ALTER DATABASE(7)

1086

Nom
REINDEX reconstruit les index

Synopsis
REINDEX { INDEX | TABLE | DATABASE | SYSTEM } nom [ FORCE ]

Description
REINDEX reconstruit un index en utilisant les donnes stockes dans la table, remplaant l'ancienne copie de l'index. Il y a plusieurs raisons pour utiliser REINDEX :

Un index a t corrompu et ne contient plus de donnes valides. Bien qu'en thorie, ceci ne devrait jamais arriver, en pratique, les index peuvent se corrompre cause de bogues dans le logiciel ou d'checs matriels. REINDEX fournit une mthode de rcupration.

L'index en question a explos , c'est--dire qu'il contient beaucoup de pages d'index mortes ou presque mortes. Ceci peut
arriver avec des index B-tree dans PostgreSQL sous certains modles d'accs inhabituels. REINDEX fournit un moyen de
rduire la consommation d'espace de l'index en crivant une nouvelle version de l'index sans les pages mortes. Voir Section 23.2, R-indexation rgulire pour plus d'informations.

Vous avez modifi un paramtre de stockage (par exemple, fillfactor) pour un index et vous souhaitez vous assurer que la
modification a t prise en compte.

La construction d'un index avec l'option CONCURRENTLY a chou, laissant un index invalide . De tels index sont inutiles donc il est intressant d'utiliser REINDEX pour les reconstruire. Notez que REINDEX n'excutera pas une construction en parallle. Pour construire l'index sans interfrer avec le systme en production, vous devez supprimer l'index et rexcuter la commande CREATE INDEX CONCURRENTLY.

Paramtres
INDEX
Recre l'index spcifi.
TABLE
Recre tous les index de la table spcifie. Si la table a une seconde table TOAST , elle est aussi rindexe.
DATABASE
Recre tous les index de la base de donnes en cours. Les index sur les catalogues systme partags sont aussi traits. Cette
forme de REINDEX ne peut pas tre excut l'intrieur d'un bloc de transaction.
SYSTEM
Recre tous les index des catalogues systme l'intrieur de la base de donnes en cours. Les index sur les catalogues systme partags sont aussi inclus. Les index des tables utilisateur ne sont pas traits. Cette forme de REINDEX ne peut pas
tre excut l'intrieur d'un bloc de transaction.
nom
Le nom de l'index, de la table ou de la base de donnes spcifique rindexer. Les noms de table et d'index peuvent tre
qualifis du nom du schma. Actuellement, REINDEX DATABASE et REINDEX SYSTEM ne peuvent rindexer que la
base de donnes en cours, donc ce paramtre doit correspondre au nom de la base de donnes en cours.
FORCE
Ceci est une option obsolte ; elle sera ignore si celle-ci est spcifie.

Notes
Si vous suspectez la corruption d'un index sur une table utilisateur, vous pouvez simplement reconstruire cet index, ou tous les
index de la table, en utilisant REINDEX INDEX ou REINDEX TABLE.
Les choses sont plus difficiles si vous avez besoin de rcuprer la corruption d'un index sur une table systme. Dans ce cas, il est
important pour le systme de ne pas avoir utilis lui-mme un des index suspects. (En fait, dans ce type de scnario, vous pourriez constater que les processus serveur s'arrtent brutalement au lancement du service, en cause l'utilisation des index corrompus.) Pour rcuprer proprement, le serveur doit tre lanc avec l'option -P, qui inhibe l'utilisation des index pour les recherches
1087

REINDEX

dans les catalogues systme.


Une autre faon est d'arrter le serveur et de relancer le serveur PostgreSQL en mode simple utilisateur avec l'option -P place
sur la ligne de commande. Ensuite, REINDEX DATABASE, REINDEX SYSTEM, REINDEX TABLE ou REINDEX INDEX peuvent tre lancs suivant ce que vous souhaitez reconstruire. En cas de doute, utilisez la commande REINDEX SYSTEM
pour activer la reconstruction de tous les index systme de la base de donnes. Enfin, quittez la session simple utilisateur du serveur et relancez le serveur en mode normal. Voir la page de rfrence de postgres(1) pour plus d'informations sur l'interaction avec
l'interface du serveur en mode simple utilisateur.
Une session standard du serveur peut aussi tre lance avec -P dans les options de la ligne de commande. La mthode pour ce
faire varie entre les clients mais dans tous les clients bass sur libpq, il est possible de configurer la variable d'environnement
PGOPTIONS -P avant de lancer le client. Notez que, bien que cette mthode ne verrouille pas les autres clients, il est conseill
d'empcher les autres utilisateurs de se connecter la base de donnes endommage jusqu' la fin des rparations.
REINDEX est similaire une suppression et une nouvelle cration de l'index, dans les fait le contenu de l'index est compltement recr. Nanmoins, les considrations de verrouillage sont assez diffrentes. REINDEX verrouille les critures mais pas les
lectures de la table mre de l'index. Il positionne galement un verrou exclusif sur l'index en cours de traitement, ce qui bloque les
lectures qui tentent de l'utiliser. Au contraire, DROP INDEX cre temporairement un verrou exclusif sur la table parent, bloquant
ainsi critures et lectures. Le CREATE INDEX qui suit verrouille les critures mais pas les lectures ; comme l'index n'existe pas,
aucune lecture ne peut tre tente, signifiant qu'il n'y a aucun blocage et que les lectures sont probablement forces de raliser des
parcours squentiels complets.
R-indexer un seul index ou une seule table requiert d'tre le propritaire de cet index ou de cette table. R-indexer une base de
donnes requiert d'tre le propritaire de la base de donnes (notez du coup que le propritaire peut reconstruire les index de tables
possdes par d'autres utilisateurs). Bien sr, les superutilisateurs peuvent toujours tout r-indexer.
Avant PostgreSQL 8.1, REINDEX DATABASE traitait seulement les index systmes, pas tous les index comme on pourrait le
supposer d'aprs le nom. Ceci a t modifi pour rduire le facteur de surprise. L'ancien comportement est disponible en tant que
REINDEX SYSTEM.
Avant PostgreSQL 7.4, REINDEX TABLE ne traitait pas automatiquement les tables TOAST et du coup, elles devaient tre
rindexes par des commandes spares. C'est toujours possible mais redondant.

Exemples
Reconstruit un index simple :
REINDEX INDEX my_index;
Recre les index sur la table ma_table :
REINDEX TABLE ma_table;
Reconstruit tous les index d'une base de donnes particulire sans faire confiance la validit des index systme :
$ export PGOPTIONS="-P"
$ psql broken_db
...
broken_db=> REINDEX DATABASE broken_db;
broken_db=> \q

Compatibilit
Il n'existe pas de commande REINDEX dans le standard SQL.

1088

Nom
RELEASE SAVEPOINT dtruit un point de sauvegarde prcdemment dfini

Synopsis
RELEASE [ SAVEPOINT ] nom_pointsauvegarde

Description
RELEASE SAVEPOINT dtruit un point de sauvegarde dfini prcdemment dans la transaction courante.
La destruction d'un point de sauvegarde le rend indisponible comme point de retour. C'est, pour l'utilisateur, le seul comportement visible. Elle ne dfait pas les commandes excutes aprs l'tablissement du point de sauvegarde (pour cela, voir ROLLBACK TO SAVEPOINT(7)). Dtruire un point de sauvegarde quand il n'est plus ncessaire peut permettre au systme de rcuprer certaines ressources sans attendre la fin de la transaction.
RELEASE SAVEPOINT dtruit aussi tous les points de sauvegarde crs ultrieurement au point de sauvegarde indiqu.

Paramtres
nom_pointsauvegarde
Le nom du point de sauvegarde dtruire.

Notes
Spcifier un nom de point de sauvegarde qui n'a pas t dfini est une erreur.
Il n'est pas possible de librer un point de sauvegarde lorsque la transaction est dans un tat d'annulation.
Si plusieurs points de transaction ont le mme nom, seul le plus rcent est libr.

Exemples
Pour tablir puis dtruire un point de sauvegarde :
BEGIN;
INSERT INTO table1 VALUES (3);
SAVEPOINT mon_pointsauvegarde;
INSERT INTO table1 VALUES (4);
RELEASE SAVEPOINT mon_pointsauvegarde;
COMMIT;
La transaction ci-dessus insre la fois 3 et 4.

Compatibilit
Cette commande est conforme au standard SQL. Le standard impose le mot cl SAVEPOINT mais PostgreSQL autorise son
omission.

Voir aussi
BEGIN(7), COMMIT(7), ROLLBACK(7), ROLLBACK TO SAVEPOINT(7), SAVEPOINT(7)

1089

Nom
RESET reinitialise un paramtre d'excution sa valeur par dfaut

Synopsis
RESET paramtre_configuration
RESET ALL

Description
RESET rinitialise les paramtres d'excution leur valeur par dfaut. RESET est une alternative
SET paramtre_configuration TO DEFAULT
On pourra se rfrer SET(7) pour plus de dtails.
La valeur par dfaut est dfinie comme la valeur qu'aurait la variable si aucune commande SET n'avait modifi sa valeur pour la
session en cours. La source effective de cette valeur peut tre dans les valeurs par dfaut compiles, le fichier de configuration,
les options de la ligne de commande ou les paramtrages spcifiques la base de donnes ou l'utilisateur. Ceci est subtilement
diffrent de le dfinir comme la valeur qu'a le paramtre au lancement de la session parce que, si la valeur provenait du fichier de configuration, elle sera annule par ce qui est spcifi maintenant dans le ficher deconfiguration. Voir Chapitre 18,
Configuration du serveur pour les dtails.
Le comportement transactionnel de RESET est identique celui de la commande SET : son effet sera annule par une annulation de la transaction.

Paramtres
paramtre_configuration
Nom d'un paramtre configurable. Les paramtres disponibles sont documents dans Chapitre 18, Configuration du serveur
et sur la page de rfrence SET(7).
ALL
Rinitialise tous les paramtres configurables l'excution.

Exemples
Pour rinitialiser timezone :
RESET timezone;

Compatibilit
RESET est une extension de PostgreSQL.

Voir aussi
SET(7), SHOW(7)

1090

Nom
REVOKE supprime les droits d'accs

Synopsis
REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] nom_table [, ...]
| ALL TABLES IN SCHEMA nom_schma [, ...] }
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | REFERENCES } ( colonne [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( colonne [, ...] ) }
ON [ TABLE ] nom_table [, ...]
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ { USAGE | SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON { SEQUENCE nom_squence [, ...]
| ALL SEQUENCES IN SCHEMA nom_schma [, ...] }
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
ON DATABASE nom_base [, ...]
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN DATA WRAPPER nom_fdw [, ...]
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN SERVER nom_serveur [, ...]
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ EXECUTE | ALL [ PRIVILEGES ] }
ON { FUNCTION nom_fonction ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] ) [,
...]
| ALL FUNCTIONS IN SCHEMA nom_schma [, ...] }
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE nom_lang [, ...]
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT loid [, ...]
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
1091

REVOKE

{ { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }


ON SCHEMA nom_schma [, ...]
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE nom_tablespace [, ...]
FROM { [ GROUP ] nom_rle | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ ADMIN OPTION FOR ]
nom_rle [, ...] FROM nom_rle [, ...]
[ CASCADE | RESTRICT ]

Description
La commande REVOKE retire des droits prcdemment attribus un ou plusieurs rles. Le mot cl PUBLIC fait rfrence au
groupe implicitement dfini de tous les rles.
Voir la description de la commande GRANT(7) pour connatre la signification des types de droits.
Notez qu'un rle possde la somme des droits qui lui ont t donns directement, des droits qui ont t donns un rle dont il est
membre et des droits donns PUBLIC. Du coup, par exemple, retirer les droits de SELECT PUBLIC ne veut pas ncessairement dire que plus aucun rle n'a le droit de faire de SELECT sur l'objet : ceux qui en avaient obtenu le droit directement ou via
un autre rle l'ont toujours. De mme, rvoquer SELECT d'un utilisateur ne l'empchera peut-tre pas d'utiliser SELECT si PUBLIC ou un autre de ses rle a toujours les droits SELECT.
Si GRANT OPTION FOR est prcis, seul l'option de transmission de droit (grant option) est supprime, pas le droit lui mme.
Sinon, le droit et l'option de transmission de droits sont rvoqus.
Si un utilisateur dtient un privilge avec le droit de le transmettre, et qu'il l'a transmis d'autres utilisateurs, alors les droits de
ceux-ci sont appels des droits dpendants. Si les droits ou le droit de transmettre du premier utilisateur sont supprims, et que des
droits dpendants existent, alors ces droits dpendants sont aussi supprims si l'option CASCADE est utilise. Dans le cas
contraire, la suppression de droits est refuse. Cette rvocation rcursive n'affecte que les droits qui avaient t attribus travers
une chane d'utilisateurs traable jusqu' l'utilisateur qui subit la commande REVOKE. Du coup, les utilisateurs affects peuvent finalement garder le droit s'il avait aussi t attribu via d'autres utilisateurs.
En cas de rvocation des droits sur une table, les droits sur les colonnes correspondantes (s'il y en a) sont automatiquement rvoqus pour toutes les colonnes de la table en mme temps.
Lors de la rvocation de l'appartenance d'un rle, GRANT OPTION est appel ADMIN OPTION mais le comportement est similaire. Notez aussi que cette forme de la commande ne permet pas le mot GROUP.

Notes
Utilisez la commande \dp de psql(1) pour afficher les droits donns sur des tables et colonnes. Voir GRANT(7) pour plus
d'informations sur le format. Pour les objets qui ne sont pas des tables, il existe d'autres commandes \d qui peuvent afficher leurs
droits.
Un utilisateur ne peut rvoquer que les droits qu'il a donns directement. Si, par exemple, un utilisateur A a donn un droit et la
possibilit de le transmettre un utilisateur B, et que B son tour l'a donn C, alors A ne peut pas retirer directement le droit de
C. la place, il peut supprimer le droit de transmettre B et utiliser l'option CASCADE pour que le droit soit automatiquement
supprim C. Autre exemple, si A et B ont donn le mme droit C, A peut rvoquer son propre don de droit mais pas celui de B,
donc C dispose toujours de ce droit.
Lorsqu'un utilisateur, non propritaire de l'objet, essaie de rvoquer (REVOKE) des droits sur l'objet, la commande choue si
l'utilisateur n'a aucun droit sur l'objet. Tant que certains droits sont disponibles, la commande s'excute mais ne sont supprims
que les droits dont l'utilisateur a l'option de transmission. La forme REVOKE ALL PRIVILEGES affiche un message
d'avertissement si les options de transmissions pour un des droits nomms spcifiquement dans la commande ne sont pas possds. (En principe, ces instructions s'appliquent aussi au propritaire de l'objet mais comme le propritaire est toujours trait
comme celui dtenant toutes les options de transmission, ces cas n'arrivent jamais.)
Si un superutilisateur choisit d'excuter une commande GRANT ou REVOKE, la commande est excute comme si elle tait lance par le propritaire de l'objet affect. Comme tous les droits proviennent du propritaire d'un objet (directement ou via une
chane de transmissions de droits), un superutilisateur peut supprimer tous les droits sur un objet mais cela peut ncessiter
l'utilisation de CASCADE comme expliqu prcdemment.
REVOKE peut aussi tre effectu par un rle qui n'est pas le propritaire de l'objet affect mais qui est un membre du rle qui
1092

REVOKE

possde l'objet ou qui est un membre d'un rle qui dtient les droits WITH GRANT OPTION sur cet objet. Dans ce cas, la commande est excute comme si elle avait t excute par le rle qui possde rellement l'objet ou dtient les droits WITH GRANT
OPTION. Par exemple, si la table t1 est possde par le rle g1, dont le rle u1 est membre, alors u1 peut supprimer des droits
sur t1 qui sont enregistrs comme donns par g1. Ceci incluera les dons de droits effectus par u1 ainsi que ceux effectus par
les autres membres du rle g1.
Si le rle excutant REVOKE dtient les droits indirectement via plus d'un chemin d'appartenance, le rle indiqu comme ayant
effectu la commande est non dterminable l'avance. Dans de tels cas, il est prfrable d'utiliser SET ROLE pour devenir le rle
que vous souhaitez voir excuter la commande REVOKE. Ne pas faire cela peut avoir comme rsultat de supprimer des droits
autres que ceux que vous vouliez, voire mme de ne rien supprimer du tout.

Exemples
Enlve au groupe public le droit d'insrer des lignes dans la table films :
REVOKE INSERT ON films FROM PUBLIC;
Supprime tous les droits de l'utilisateur manuel sur la vue genres :
REVOKE ALL PRIVILEGES ON genres FROM manuel;
Notez que ceci signifie en fait rvoque tous les droits que j'ai donn .
Supprime l'appartenance de l'utilisateur joe au rle admins :
REVOKE admins FROM joe;

Compatibilit
La note de compatibilit de la commande GRANT(7) s'applique par analogie REVOKE. Les mots cls RESTRICT ou CASCADE sont requis d'aprs le standard, mais PostgreSQL utilise RESTRICT par dfaut.

Voir aussi
GRANT(7)

1093

Nom
ROLLBACK annule la transaction en cours

Synopsis
ROLLBACK [ WORK | TRANSACTION ]

Description
ROLLBACK annule la transaction en cours et toutes les modifications effectues lors de cette transaction.

Paramtres
WORK, TRANSACTION
Mots cls optionnels. Ils sont sans effet.

Notes
L'utilisation de la commande COMMIT(7) permet de terminer une transaction avec succs.
Lancer ROLLBACK en dehors de toute transaction n'a pas d'autre consquence que l'affichage d'un message d'avertissement.

Exemples
Pour annuler toutes les modifications :
ROLLBACK;

Compatibilit
Le standard SQL spcifie seulement les deux formes ROLLBACK et ROLLBACK WORK. part cela, cette commande est totalement compatible.

Voir aussi
BEGIN(7), COMMIT(7), ROLLBACK TO SAVEPOINT(7)

1094

Nom
ROLLBACK PREPARED annule une transaction prcdemment prpare en vue d'une validation en deux phases

Synopsis
ROLLBACK PREPARED id_transaction

Description
ROLLBACK PREPARED annule une transaction prpare.

Paramtres
id_transaction
L'identifiant de la transaction annuler.

Notes
Pour annuler une transaction prpare, il est impratif d'tre soit l'utilisateur qui a initi la transaction, soit un superutilisateur. Il
n'est, en revanche, pas ncessaire d'tre dans la session qui a initi la transaction.
Cette commande ne peut pas tre excute l'intrieur d'un bloc de transaction. La transaction prpare est annule immdiatement.
Toutes les transactions prpares disponibles sont listes dans la vue systme pg_prepared_xacts.

Exemples
Annuler la transaction identifie par foobar :
ROLLBACK PREPARED 'foobar';

Voir aussi
PREPARE TRANSACTION(7), COMMIT PREPARED(7)

1095

Nom
ROLLBACK TO SAVEPOINT annule les instructions jusqu'au point de sauvegarde

Synopsis
ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] nom_pointsauvegarde

Description
Annule toutes les commandes qui ont t excutes aprs l'tablissement du point de sauvegarde. Le point de sauvegarde reste
valide. Il est possible d'y d'y revenir encore si cela s'avrait ncessaire.
ROLLBACK TO SAVEPOINT dtruit implicitement tous les points de sauvegarde tablis aprs le point de sauvegarde indiqu.

Paramtres
nom_pointsauvegarde
Le point de sauvegarde o retourner.

Notes
RELEASE SAVEPOINT(7) est utilis pour dtruire un point de sauvegarde sans annuler les effets de commandes excutes
aprs son tablissement.
Spcifier un nom de point de sauvegarde inexistant est une erreur.
Les curseurs ont un comportement quelque peu non transactionnel en ce qui concerne les points de sauvegarde. Tout curseur ouvert l'intrieur d'un point de sauvegarde est ferm lorsque le point de sauvegarde est rejoint. Si un curseur prcdemment ouvert est affect par une commande FETCH ou MOVE l'intrieur d'un point de sauvegarde rejoint par la suite, la position du
curseur reste celle obtenue par FETCH (c'est--dire que le dplacement du curseur d au FETCH n'est pas annul). La fermeture d'un curseur n'est pas non plus remise en cause par une annulation. Nanmoins, certains effets de bord causs par la requte
du curseur (comme les effets de bord des fonctions volatiles appeles par la requte) sont annuls s'ils surviennent lors d'un
point de sauvegarde qui est annul plus tard. Un curseur dont l'excution provoque l'annulation d'une transaction est plac dans
un tat non excutable. De ce fait, alors mme que la transaction peut tre restaure par ROLLBACK TO SAVEPOINT, le
curseur ne peut plus tre utilis.

Exemples
Pour annuler les effets des commandes excutes aprs l'tablissement de mon_pointsauvegarde :
ROLLBACK TO SAVEPOINT mon_pointsauvegarde;
La position d'un curseur n'est pas affecte par l'annulation des points de sauvegarde :
BEGIN;
DECLARE foo CURSOR FOR SELECT 1 UNION SELECT 2;
SAVEPOINT foo;
FETCH 1 FROM foo;
?column?
---------1
ROLLBACK TO SAVEPOINT foo;
FETCH 1 FROM foo;
?column?
---------2
COMMIT;
1096

ROLLBACK TO SAVEPOINT

Compatibilit
Le standard SQL spcifie que le mot cl SAVEPOINT est obligatoire mais PostgreSQL et Oracle autorisent son omission.
SQL n'autorise que WORK, pas TRANSACTION, aprs ROLLBACK. De plus, SQL dispose d'une clause optionnelle AND [ NO ]
CHAIN qui n'est actuellement pas supporte par PostgreSQL. Pour le reste, cette commande est conforme au standard SQL.

Voir aussi
BEGIN(7), COMMIT(7), RELEASE SAVEPOINT(7), ROLLBACK(7), SAVEPOINT(7)

1097

Nom
SAVEPOINT dfinit un nouveau point de sauvegarde l'intrieur de la transaction en cours

Synopsis
SAVEPOINT nom_pointsauvegarde

Description
SAVEPOINT tablit un nouveau point de sauvegarde l'intrieur de la transaction en cours.
Un point de sauvegarde est une marque spciale l'intrieur d'une transaction qui autorise l'annulation de toutes les commandes
excutes aprs son tablissement, restaurant la transaction dans l'tat o elle tait au moment de l'tablissement du point de sauvegarde.

Paramtres
nom_pointsauvegarde
Le nom du nouveau point de sauvegarde.

Notes
Utilisez ROLLBACK TO SAVEPOINT(7) pour annuler un point de sauvegarde. Utilisez RELEASE SAVEPOINT(7) pour dtruire un point de sauvegarde, conservant l'effet des commandes excutes aprs son tablissement.
Les points de sauvegarde peuvent seulement tre tablis l'intrieur d'un bloc de transaction. Plusieurs points de sauvegarde
peuvent tre dfinis dans une transaction.

Exemples
Pour tablir un point de sauvegarde et annuler plus tard les effets des commandes excutes aprs son tablissement :
BEGIN;
INSERT INTO table1 VALUES (1);
SAVEPOINT mon_pointsauvegarde;
INSERT INTO table1 VALUES (2);
ROLLBACK TO SAVEPOINT mon_pointsauvegarde;
INSERT INTO table1 VALUES (3);
COMMIT;
La transaction ci-dessus insre les valeurs 1 et 3, mais pas 2.
Pour tablir puis dtruire un point de sauvegarde :
BEGIN;
INSERT INTO table1 VALUES (3);
SAVEPOINT mon_pointsauvegarde;
INSERT INTO table1 VALUES (4);
RELEASE SAVEPOINT mon_pointsauvegarde;
COMMIT;
La transaction ci-dessus insre la fois les valeurs 3 et 4.

Compatibilit
SQL requiert la destruction automatique d'un point de sauvegarde quand un autre point de sauvegarde du mme nom est cr.
Avec PostgreSQL, l'ancien point de sauvegarde est conserv, mais seul le plus rcent est utilis pour une annulation ou une libration. (Librer avec RELEASE SAVEPOINT le point de sauvegarde le plus rcent fait que l'ancien est de nouveau accessible aux commandes ROLLBACK TO SAVEPOINT et RELEASE SAVEPOINT.) Sinon, SAVEPOINT est totalement
conforme SQL.

Voir aussi
BEGIN(7), COMMIT(7), RELEASE SAVEPOINT(7), ROLLBACK(7), ROLLBACK TO SAVEPOINT(7)

1098

Nom
SECURITY LABEL Dfinir ou modifier une label de scurit applique un objet

Synopsis
SECURITY LABEL [ FOR fournisseur ] ON
{
TABLE nom_objet |
COLUMN nom_table.nom_colonne |
AGGREGATE nom_aggrgat (type_aggrgat [, ...] ) |
DOMAIN nom_objet |
FOREIGN TABLE nom_objet
FUNCTION nom_fonction ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] ) |
LARGE OBJECT oid_large_objet |
[ PROCEDURAL ] LANGUAGE nom_objet |
SCHEMA nom_objet |
SEQUENCE nom_objet |
TYPE nom_objet |
VIEW nom_objet
} IS 'label'

Description
SECURITY LABEL applique un label de scurit un objet de la base de donnes. Un nombre arbitraire de labels de scurit,
un par fournisseur d'labels, peut tre associ un objet donn de la base. Les fournisseurs de labels sont des modules dynamiques qui s'enregistrent eux-mmes en utilisant la fonction register_label_provider.

Note
register_label_provider n'est pas une fonction SQL ; elle ne peut tre appele que depuis du code C
charg et excut au sein du serveur.
Le fournisseur de labels dtermine si un label donn est valide, et dans quelle mesure il est permis de l'appliquer un objet donn. Le sens des labels est galement laiss la discrtion du fournisseur d'labels. PostgreSQL n'impose aucune restriction
quant l'interprtation que peut faire un fournisseur d'un label donn, se contentant simplement d'offrir un mcanisme de stockage de ces labels. En pratique, il s'agit de permettre l'intgration de systmes de contrles d'accs obligatoires (en anglais,
mandatory access control ou MAC) tels que SE-Linux. De tels systmes fondent leurs autorisations d'accs sur des labels appliqus aux objets, contrairement aux systmes traditionnels d'autorisations d'accs discrtionnaires (en anglais, discretionary
access control ou DAC) gnralement bass sur des concepts tels que les utilisateurs et les groupes.

Paramtres
nom_objet, nom_table.nom_colonne, nom_aggr, nom_fonction
Le nom de l'objet. Ce sont les noms des tables, aggrgats, domaines, tables distantes, fonctions, squences, types et vues qui
peuvent tre qualifis du nom de schma.
fournisseur
Le nom du fournisseur auquel le label est associ. Le fournisseur dsign doit tre charg et accepter l'opration qui lui est
propose. Si un seul et unique fournisseur est charg, le nom du fournisseur peut tre omis par soucis de concision.
type_arg
Le type de donne en entre sur lequel la fonction d'aggrgation doit oprer. Pour rfrencer une fonction d'aggrgation
sans argument, il convient d'crire * en guise de liste de types de donnes.
mode_arg
Le mode d'un argument de fonction : IN, OUT, INOUT ou VARIADIC. Si le mode est omis, le mode par dfaut IN est alors
appliqu. noter que SECURITY LABEL ON FUNCTION ne porte actuellement pas sur les arguments de mode OUT
dans la mesure o seuls les arguments fournis en entre sont ncessaires l'identification d'une fonction. Il suffit donc de
lister les arguments IN, INOUT, et VARIADIC afin d'identifier sans ambigut une fonction.
nom_arg
Le nom d'un argument de fonction. noter que SECURITY LABEL ON FUNCTION ne porte actuellement pas sur les
1099

SECURITY LABEL

nom des arguments fournis aux fonctions dans la mesure o seul le type des arguments est ncessaire l'identification d'une
fonction.
type_arg
Le ou les types de donnes des arguments des fonctions, si elles en comportent, ventuellement qualifis du nom de schma.
oid_large_objet
L'OID de l'objet large.
PROCEDURAL
Qualificatif optionnel du langage, peut tre omis.
label
Le nom du label affecter, fourni sous la forme d'une chaine littrale ou NULL pour supprimer un label de scurit prcdemment affect.

Exemples
L'exemple suivant montre comment modifier le label de scurit d'une table.
SECURITY LABEL FOR selinux ON TABLE matable IS 'system_u:object_r:sepgsql_table_t:s0';

Compatibilit
La commande SECURITY LABEL n'existe pas dans le standard SQL.

Voir aussi
sepgsql, dummy_seclabel

1100

Nom
SELECT, TABLE, WITH rcupre des lignes d'une table ou d'une vue

Synopsis
[ WITH [ RECURSIVE ] requte_with [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
* | expression [ [ AS ] nom_d_affichage ] [, ...]
[ FROM lments_from [, ...] ]
[ WHERE condition ]
[ GROUP BY expression [, ...] ]
[ HAVING condition [, ...] ]
[ WINDOW nom_window AS ( dfinition_window ) [, ...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC | USING oprateur ] [ NULLS { FIRST | LAST } ]
[, ...] ]
[ LIMIT { nombre | ALL } ]
[ OFFSET dbut ] [ ROW | ROWS ] ]
[ FETCH { FIRST | NEXT } [ total ] { ROW | ROWS } ONLY ]
[ FOR { UPDATE | SHARE } [ OF nom_table [, ...] ] [ NOWAIT ] [...] ]
avec lments_from qui peut tre :
[ ONLY ] nom_table [ * ] [ [ AS ] alias [ ( alias_colonne [, ...] ) ] ]
( select ) [ AS ] alias [ ( alias_colonne [, ...] ) ]
nom_requte_with [ [ AS ] alias [ ( alias_colonne [, ...] ) ] ]
nom_fonction ( [ argument [, ...] ] ) [ AS ] alias [ ( alias_colonne [, ...] |
dfinition_colonne [, ...] ) ]
nom_fonction ( [ argument [, ...] ] ) AS ( dfinition_colonne [, ...] )
lments_from [ NATURAL ] type_jointure lments_from [ ON condition_jointure |
USING ( colonne_jointure [, ...] ) ]
et requte_with est :
nom_requte_with [ ( nom_colonne [, ...] ) ] AS ( select | insert | update |
delete )
TABLE [ ONLY ] nom_table [ * ]

Description
SELECT rcupre des lignes de zro ou plusieurs tables. Le traitement gnral de SELECT est le suivant :
1. Toutes les requtes dans la liste WITH sont values. Elles jouent le rle de tables temporaires qui peuvent tre rfrences
dans la liste FROM. Une requte WITH qui est rfrence plus d'une fois dans FROM n'est calcule qu'une fois (voir la section
intitule Clause WITH ci-dessous).
2. Tous les lments de la liste FROM sont calculs. (Chaque lment dans la liste FROM est une table relle ou virtuelle.) Si
plus d'un lment sont spcifis dans la liste FROM, ils font l'objet d'une jointure croise (cross-join). (Voir la section intitule
Clause FROM ci-dessous.)
3. Si la clause WHERE est spcifie, toutes les lignes qui ne satisfont pas les conditions sont limines de l'affichage. (Voir la
section intitule Clause WHERE ci-dessous.)
4. Si la clause GROUP BY est spcifie, l'affichage est divis en groupes de lignes qui correspondent une ou plusieurs valeurs.
Si la clause HAVING est prsente, elle limine les groupes qui ne satisfont pas la condition donne. (Voir la section intitule
Clause GROUP BY et la section intitule Clause HAVING ci-dessous.)
5. Les lignes retournes sont traites en utilisant les expressions de sortie de SELECT pour chaque ligne ou groupe de ligne slectionn. (Voir la section intitule Liste SELECT ci-dessous.)
6. SELECT DISTINCT limine du rsultat les lignes en double. SELECT DISTINCT ON limine les lignes qui correspondent sur toute l'expression spcifie. SELECT ALL (l'option par dfaut) retourne toutes les lignes, y compris les doublons. (cf. la section intitule DISTINCT Clause ci-dessous.)
7. En utilisant les oprateurs UNION, INTERSECT et EXCEPT, l'affichage de plusieurs instructions SELECT peut tre combi1101

SELECT

n pour former un ensemble unique de rsultats. L'oprateur UNION renvoie toutes les lignes qui appartiennent, au moins,
l'un des ensembles de rsultats. L'oprateur INTERSECT renvoie toutes les lignes qui sont dans tous les ensembles de rsultats.
L'oprateur EXCEPT renvoie les lignes qui sont prsentes dans le premier ensemble de rsultats mais pas dans le deuxime.
Dans les trois cas, les lignes dupliques sont limines sauf si ALL est spcifi. Le mot-cl supplmentaire DISTINCT peut
tre ajout pour signifier explicitement que les lignes en doublon sont limines. Notez bien que DISTINCT est l le comportement par dfaut, bien que ALL soit le dfaut pour la commande SELECT. (Voir la section intitule Clause UNION , la
section intitule Clause INTERSECT et la section intitule Clause EXCEPT ci-dessous.)
8. Si la clause ORDER BY est spcifie, les lignes renvoyes sont tries dans l'ordre spcifi. Si ORDER BY n'est pas indiqu, les
lignes sont retournes dans l'ordre qui permet la rponse la plus rapide du systme. (Voir la section intitule Clause ORDER
BY ci-dessous.)
9. Si les clauses LIMIT (ou FETCH FIRST) ou OFFSET sont spcifies, l'instruction SELECT ne renvoie qu'un sous-ensemble
de lignes de rsultats. (Voir la section intitule Clause LIMIT ci-dessous.)
10 Si la clause FOR UPDATE ou FOR SHARE est spcifie, l'instruction SELECT verrouille les lignes slectionnes contre les
. mises jour concurrentes. (Voir la section intitule Clause FOR UPDATE/FOR SHARE ci-dessous.)
Le droit SELECT sur chaque colonne utilise dans une commande SELECT est ncessaire pour lire ses valeurs. L'utilisation de
FOR UPDATE ou de FOR SHARE requiert en plus le droit UPDATE (pour au moins une colonne de chaque table slectionne).

Paramtres
Clause WITH
La clause WITH vous permet de spcifier une ou plusieurs sous-requtes qui peuvent tre utilises par leur nom dans la requte
principale. Les sous-requtes se comportent comme des tables temporaires ou des vues pendant la dure d'excution de la requte
principale. Chaque sous-requte peut tre un ordre SELECT, INSERT, UPDATE ou bien DELETE. Lorsque vous crivez un
ordre de modification de donnes (INSERT, UPDATE ou DELETE) dans une clause WITH, il est habituel d'inclure une clause
RETURNING. C'est la sortie de cette clause RETURNING, et non pas la table sous-jacente que l'ordre modifie, qui donne lieu la
table temporaire lue par la requte principale. Si la clause RETURNING est omise, l'ordre est tout de mme excut, mais il ne produit pas de sortie ; il ne peut donc pas tre rfrenc comme une table par la requte principale.
Un nom (sans qualification de schma) doit tre spcifi pour chaque requte WITH. En option, une liste de noms de colonnes
peut tre spcifi ; si elle est omise, les noms de colonnes sont dduites de la sous-requte.
Si RECURSIVE est spcifi, la sous-requte SELECT peut se rfrencer elle mme. Une sous-requte de ce type doit avoir la
forme
terme_non_rcursif UNION [ ALL | DISTINCT ] terme_rcursif
o l'auto-rfrence rcursive doit apparatre dans la partie droite de l'UNION. Seule une auto-rfrence rcursive est autorise par
requte. Les ordres de modification rcursifs ne sont pas supports, mais vous pouvez utiliser le rsultat d'une commande SELECT rcursive dans un ordre de modification. Voir Section 7.8, Requtes WITH (Common Table Expressions) pour un
exemple.
Un autre effet de RECURSIVE est que les requtes WITH n'ont pas besoin d'tre ordonnes : une requte peut en rfrencer une
autre qui se trouve plus loin dans la liste (toutefois, les rfrences circulaires, ou rcursion mutuelle, ne sont pas implmentes).
Sans RECURSIVE, les requtes WITH ne peuvent rfrencer d'autres requtes WITH sours que si elles sont dclares avant dans
la liste WITH.
Une proprit cl des requtes WITH est qu'elles ne sont values qu'une seule fois par excution de la requte principale, mme si
la requte principale les utilise plus d'une fois. En particulier, vous avez la garantie que les traitements de modification de donnes
sont excuts une seule et unique fois, que la requte principale lise tout ou partie de leur sortie.
Tout se passe comme si la requte principale et les requtes WITH taient toutes excutes en mme temps. Ceci a pour consquence que les effets d'un ordre de modification dans une clause WITH ne peuvent pas tre vues des autres parties de la requte,
sauf en lisant la sortie de RETURNING. Si deux de ces ordres de modifications tentent de modifier la mme ligne, les rsultats
sont imprvisibles.
Voir Section 7.8, Requtes WITH (Common Table Expressions) pour plus d'informations.

Clause FROM
La clause FROM spcifie une ou plusieurs tables source pour le SELECT. Si plusieurs sources sont spcifies, le rsultat est un
produit cartsien (jointure croise) de toutes les sources. Mais habituellement, des conditions de qualification sont ajoutes pour
restreindre les lignes renvoyes un petit sous-ensemble du produit cartsien.
1102

SELECT

La clause FROM peut contenir les lments suivants :


nom_table
Le nom (ventuellement qualifi par le nom du schma) d'une table ou vue existante. Si ONLY est spcifi avant le nom de la
table, seule cette table est parcourue. Dans le cas contraire, la table et toutes ses tables filles (s'il y en a) sont parcourues. En
option, * peut tre ajout aprs le nom de la table pour indiquer explicitement que les tables filles sont inclues.
alias
Un nom de substitution pour l'lment FROM contenant l' alias. Un alias est utilis par brivet ou pour lever toute ambigut
lors d'auto-jointures (la mme table est parcourue plusieurs fois). Quand un alias est fourni, il cache compltement le nom rel
de la table ou fonction ; par exemple, avec FROM truc AS, le reste du SELECT doit faire rfrence cet lment de FROM
par f et non pas par truc. Si un alias est donn, une liste d' alias de colonnes peut aussi tre saisi comme noms de substitution pour diffrentes colonnes de la table.
select
Un sous-SELECT peut apparatre dans la clause FROM. Il agit comme si sa sortie tait transforme en table temporaire pour
la dure de cette seule commande SELECT. Le sous-SELECT doit tre entour de parenthses et un alias doit lui tre fourni.
Une commande VALUES(7) peut aussi tre utilise ici.
requte_with
Une requte WITH est rfrence par l'criture de son nom, exactement comme si le nom de la requte tait un nom de table
(en fait, la requte WITH cache toutes les tables qui auraient le mme nom dans la requte principale. Si ncessaire, vous pouvez accder une table relle du mme nom en prcisant le schma du nom de la table). Un alias peut tre indiqu de la
mme faon que pour une table.
nom_fonction
Des appels de fonctions peuvent apparatre dans la clause FROM. (Cela est particulirement utile pour les fonctions renvoyant
des ensembles de rsultats, mais n'importe quelle fonction peut tre utilise.) Un appel de fonction agit comme si la sortie
tait transforme en table temporaire pour la dure de cette seule commande SELECT. Un alias peut aussi tre utilis. Si un
alias est donn, une liste d' alias de colonnes peut tre ajoute pour fournir des noms de substitution pour un ou plusieurs attributs du type compos de retour de la fonction. Si la fonction a t dfinie comme renvoyant le type de donnes record, alors
un alias ou un mot cl AS doit tre prsent, suivi par une liste de dfinitions de colonnes de la forme ( nom_colonne
type_donnes [, ... ] ). La liste de dfinitions de colonnes doit correspondre au nombre rel et aux types rels des
colonnes renvoyes par la fonction.
type_jointure
Un des lments

[ INNER ] JOIN

LEFT [ OUTER ] JOIN

RIGHT [ OUTER ] JOIN

FULL [ OUTER ] JOIN

CROSS JOIN

Pour les types de jointures INNER et OUTER, une condition de jointure doit tre spcifie, choisir parmi NATURAL, ON
condition_jointure ou USING (colonne_jointure [, ...]). Voir ci-dessous pour la signification. Pour
CROSS JOIN, aucune de ces clauses ne doit apparatre.
Une clause JOIN combine deux lments FROM. Les parenthses peuvent tre utilises pour dterminer l'ordre d'imbrication.
En l'absence de parenthses, les JOIN sont imbriqus de gauche droite. Dans tous les cas, JOIN est plus prioritaire que les
virgules sparant les lments FROM.
CROSS JOIN et INNER JOIN produisent un simple produit cartsien. Le rsultat est identique celui obtenu lorsque les
deux lments sont lists au premier niveau du FROM, mais restreint par la condition de jointure (si elle existe). CROSS
JOIN est quivalent INNER JOIN ON (TRUE), c'est--dire qu'aucune ligne n'est supprime par qualification. Ces types
de jointure sont essentiellement une aide la notation car ils ne font rien de plus qu'un simple FROM et WHERE.
LEFT OUTER JOIN renvoie toutes les lignes du produit cartsien qualifi (c'est--dire toutes les lignes combines qui satisfont la condition de jointure), plus une copie de chaque ligne de la table de gauche pour laquelle il n'y a pas de ligne droite
qui satisfasse la condition de jointure. La ligne de gauche est tendue la largeur complte de la table jointe par insertion de
valeurs NULL pour les colonnes de droite. Seule la condition de la clause JOIN est utilise pour dcider des lignes qui correspondent. Les conditions externes sont appliques aprs coup.
l'inverse, RIGHT OUTER JOIN renvoie toutes les lignes jointes plus une ligne pour chaque ligne de droite sans corres1103

SELECT

pondance (complte par des NULL pour le ct gauche). C'est une simple aide la notation car il est aisment convertible en
LEFT en inversant les entres gauche et droite.
FULL OUTER JOIN renvoie toutes les lignes jointes, plus chaque ligne gauche sans correspondance (tendue par des
NULL droite), plus chaque ligne droite sans correspondance (tendue par des NULL gauche).
ON condition_jointure
condition_jointure est une expression qui retourne une valeur de type boolean (comme une clause WHERE) qui spcifie les lignes d'une jointure devant correspondre.
USING (colonne_jointure [, ...])
Une clause de la forme USING ( a, b, ... ) est un raccourci pour ON table_gauche.a = table_droite.a
AND table_gauche.b = table_droite.b .... De plus, USING implique l'affichage d'une seule paire des colonnes correspondantes dans la sortie de la jointure.
NATURAL
NATURAL est un raccourci pour une liste USING qui mentionne toutes les colonnes de mme nom dans les deux tables.

Clause WHERE
La clause WHERE optionnelle a la forme gnrale
WHERE condition
o condition est une expression dont le rsultat est de type boolean. Toute ligne qui ne satisfait pas cette condition est limine
de la sortie. Une ligne satisfait la condition si elle retourne vrai quand les valeurs relles de la ligne sont substitues toute rfrence de variable.

Clause GROUP BY
La clause GROUP BY optionnelle a la forme gnrale
GROUP BY expression [, ...]
GROUP BY condense en une seule ligne toutes les lignes slectionnes qui partagent les mmes valeurs pour les expressions regroupes. expression peut tre le nom d'une colonne en entre, le nom ou le numro d'une colonne en sortie (lment de la
liste SELECT), ou une expression quelconque forme de valeurs de colonnes en entre. En cas d'ambigut, un nom de GROUP
BY est interprt comme un nom de colonne en entre, non en sortie.
Les fonctions d'agrgat, si utilises, sont calcules pour toutes les lignes composant un groupe, produisant une valeur spare pour
chaque groupe (alors que sans GROUP BY, un agrgat produit une valeur unique calcule pour toutes les lignes slectionnes).
Quand GROUP BY est prsent, les expressions du SELECT ne peuvent faire rfrence qu' des colonnes groupes, sauf
l'intrieur de fonctions d'agrgat, ou bien si la colonne non groupe dpend fonctionnellement des colonnes groupes. En effet, s'il
en tait autrement, il y aurait plus d'une valeur possible pour la colonne non groupe. Une dpendance fonctionnelle existe si les
colonnes groupes (ou un sous-ensemble de ces dernires) sont la cl primaire de la table contenant les colonnes non groupes.

Clause HAVING
La clause optionnelle HAVING a la forme gnrale
HAVING condition
o condition est identique celle spcifie pour la clause WHERE.
HAVING limine les lignes groupes qui ne satisfont pas la condition. HAVING est diffrent de WHERE : WHERE filtre les lignes
individuelles avant l'application de GROUP BY alors que HAVING filtre les lignes groupes cres par GROUP BY. Chaque colonne rfrence dans condition doit faire rfrence sans ambigut une colonne groupe, sauf si la rfrence apparat dans
une fonction d'agrgat.
Mme en l'absence de clause GROUP BY, la prsence de HAVING transforme une requte en requte groupe. Cela correspond au
comportement d'une requte contenant des fonctions d'agrgats mais pas de clause GROUP BY. Les lignes slectionnes ne
forment qu'un groupe, la liste du SELECT et la clause HAVING ne peuvent donc faire rfrence qu' des colonnes l'intrieur de
fonctions d'agrgats. Une telle requte ne produira qu'une seule ligne si la condition HAVING est ralise, aucune dans le cas
contraire.

Clause WINDOW
La clause optionnelle WINDOW a la forme gnrale

1104

SELECT

WINDOW nom_window AS ( dfinition_window ) [, ...]


o nom_window est un nom qui peut tre rfrenc par des clauses OVER ou des dfinitions de window, et dfinition_window est
[ nom_window_existante ]
[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC | USING operateur ] [ NULLS { FIRST | LAST } ] [,
...] ]
[ clause_frame ]
Si un nom_window_existante est spcifi, il doit se rfrer une entre prcdente dans la liste WINDOW ; la nouvelle Window copie sa clause de partitionnement de cette entre, ainsi que sa clause de tri s'il y en a. Dans ce cas, la nouvelle Window ne
peut pas spcifier sa propre clause PARTITION BY, et ne peut spcifier de ORDER BY que si la Window copie n'en a pas. La
nouvelle Window utilise toujours sa propre clause frame ; la Window copie ne doit pas possder de clause frame.
Les lments de la liste PARTITION BY sont interprts peu prs de la mme faon que des lments de la section intitule
Clause GROUP BY , sauf qu'ils sont toujours des expressions simples et jamais le nom ou le numro d'une colonne en sortie.
Une autre diffrence est que ces expressions peuvent contenir des appels des fonctions d' agrgat, ce qui n'est pas autoris dans
une clause GROUP BY classique. Ceci est autoris ici parce que le windowing se produit aprs le regroupement et l' agrgation.
De faon similaire, les lments de la liste ORDER BY sont interprts peu prs de la mme faon que les lments d'un la section intitule Clause ORDER BY , sauf que les expressions sont toujours prises comme de simples expressions et jamais
comme le nom ou le numro d'une colonne en sortie.
La clause clause_frame optionnelle dfinit la frame window pour les fonctions window qui dpendent de la frame (ce n'est
pas le cas de toutes). La frame window est un ensemble de lignes lies chaque ligne de la requte (appele la ligne courante). La
clause_frame peut tre une des clauses suivantes :
[ RANGE | ROWS ] dbut_frame
[ RANGE | ROWS ] BETWEEN dbut_frame AND fin_frame
o dbut_frame et fin_frame peuvent valoir
UNBOUNDED PRECEDING
valeur PRECEDING
CURRENT ROW
valeur FOLLOWING
UNBOUNDED FOLLOWING
Si fin_frame n'est pas prcis, il vaut par dfaut CURRENT ROW. Les restrictions sont les suivantes : dbut_frame ne peut
pas valoir UNBOUNDED FOLLOWING, fin_frame ne peut pas valoir UNBOUNDED PRECEDING, et le choix fin_frame ne
peut apparatre avant le choix dbut_frame -- par exemple RANGE BETWEEN CURRENT ROW AND valeur PRECEDING n'est pas permis.
L'option par dfaut pour la clause frame est RANGE UNBOUNDED PRECEDING, ce qui revient au mme que RANGE BETWEEN
UNBOUNDED PRECEDING AND CURRENT ROW ; il positionne la frame pour qu'il couvre toutes les lignes partir du dbut de
la partition jusqu' la dernire ligne galit avec la ligne courante dans l'ordre dfini par l' ORDER BY (ce qui signifie toutes les
lignes s'il n'y a pas d' ORDER BY). Gnralement, UNBOUNDED PRECEDING signifie que la frame commence la premire
ligne de la partition, et de mme UNBOUNDED FOLLOWING signifie que la frame se termine avec la dernire ligne de la partition
(quel que soit le mode, RANGE ou bien ROWS ). Dans le mode ROWS, CURRENT ROW signifie que la frame commence ou se termine sur la ligne courante ; mais dans le mode RANGE cela signifie que la frame dbute ou se termine sur la premire ou la dernire des lignes galit avec la ligne courante dans l'ordre de la clause ORDER BY. Les valeur PRECEDING et valeur
FOLLOWING sont actuellement seulement permis en mode ROWS. Ils indiquent que la frame dbute ou se termine autant de lignes
avant ou aprs la ligne courante. valeur doit tre une expression entire, ne contenant aucune variable, fonction d' agrgat ni
fonction window. La valeur ne doit tre ni null ni ngative ; mais elle peut tre de zro, ce qui slectionne la ligne courante ellemme.
Attention, les options ROWS peuvent produire des rsultats imprvisibles si l'ordre dfini par l' ORDER BY n'ordonne pas les
lignes de manire unique. Les options RANGE sont conues pour s'assurer que les lignes qui sont galit suivant l'ordre de l' ORDER BY sont traites de la mme manire ; toutes les lignes galit seront ensemble dans la frame ou ensemble hors de la
frame.
L'utilit d'une clause WINDOW est de spcifier le comportement des fonctions window apparaissant dans la clause la section intitule Liste SELECT ou la clause la section intitule Clause ORDER BY de la requte. Ces fonctions peuvent rfrencer les
entres de clauses WINDOW par nom dans leurs clauses OVER. Toutefois, il n'est pas obligatoire qu'une entre de clause WINDOW
1105

SELECT

soit rfrence quelque part ; si elle n'est pas utilise dans la requte, elle est simplement ignore. Il est possible d'utiliser des fonctions window sans aucune clause WINDOW puisqu'une fonction window peut spcifier sa propre dfinition de window directement
dans sa clause OVER. Toutefois, la clause WINDOW conomise de la saisie quand la mme dfinition window est utilise pour plus
d'une fonction window.
Les fonctions window sont dcrites en dtail dans Section 3.5, Fonctions de fentrage , Section 4.2.8, Appels de fonction de
fentrage et Section 7.2.4, Traitement de fonctions Window .

Liste SELECT
La liste SELECT (entre les mots cls SELECT et FROM) spcifie les expressions qui forment les lignes en sortie de l'instruction
SELECT. Il se peut que les expressions fassent rfrence aux colonnes traites dans la clause FROM. En fait, en gnral, elles le
font.
Comme pour une table, chaque colonne de sortie d'un SELECT a un nom. Dans un SELECT simple, ce nom est juste utilis pour
donner un titre la colonne pour l'affichage, mais quand le SELECT est une sous-requte d'une requte plus grande, le nom est
vu par la grande requte comme le nom de colonne de la table virtuelle produite par la sous-requte. Pour indiquer le nom utiliser pour une colonne de sortie, crivez AS nom_de_sortie aprs l'expression de la colonne. (Vous pouvez omettre AS seulement si le nom de colonne souhait n'est pas un mot cl rserv par PostgreSQL (voir Annexe C, Mots-cl SQL). Pour vous
protger contre l'ajout futur d'un mot cl, il est recommand que vous criviez toujours AS ou que vous mettiez le nom de sortie
entre guillemets. Si vous n'indiquez pas de nom de colonne, un nom est choisi automatiquement par PostgreSQL. Si l'expression
de la colonne est une simple rfrence une colonne alors le nom choisi est le mme que le nom de la colonne ; dans des cas plus
complexes, un nom gnr qui ressemblera ?colonneN? est habituellement choisi.
Un nom de colonne de sortie peut tre utilis pour se rfrer la valeur de la colonne dans les clauses ORDER BY et GROUP BY,
mais pas dans la clauseWHERE ou HAVING ; cet endroit, vous devez crire l'expression.
* peut tre utilis, la place d'une expression, dans la liste de sortie comme raccourci pour toutes les colonnes des lignes slectionnes. De plus, nom_table.* peut tre crit comme raccourci pour toutes les colonnes de cette table. Dans ces cas, il est impossible de spcifier de nouveaux noms avec AS ; les noms des colonnes de sorties seront les mme que ceux de la table.

DISTINCT Clause
Si SELECT DISTINCT est spcifi, toutes les lignes en double sont supprimes de l'ensemble de rsultats (une ligne est conserve pour chaque groupe de doublons). SELECT ALL spcifie le contraire : toutes les lignes sont conserves. C'est l'option par dfaut.
SELECT DISTINCT ON ( expression [, ...] ) conserve seulement la premire ligne de chaque ensemble de lignes
pour lesquelles le rsultat de l'expression est identique. Les expressions DISTINCT ON expressions sont interprtes avec les
mmes rgles que pour ORDER BY (voir ci-dessous). Notez que la premire ligne de chaque ensemble est imprvisible,
moins que la clause ORDER BY ne soit utilise, assurant ainsi que la ligne souhaite apparaisse en premier. Par exemple :
SELECT DISTINCT ON (lieu) lieu, heure, rapport
FROM rapport_mto
ORDER BY lieu, heure DESC;
renvoie le rapport mto le plus rcent de chaque endroit. Mais si nous n'avions pas utilis ORDER BY afin de forcer le tri du
temps dans le sens descendant des temps pour chaque endroit, nous aurions rcupr, pour chaque lieu, n'importe quel bulletin de
ce lieu.
La (ou les ) expression(s) DISTINCT ON doivent correspondre l'expression (ou aux expressions) ORDER BY la(les) plus
gauche. La clause ORDER BY contient habituellement des expressions supplmentaires qui dterminent l'ordre des lignes au sein
de chaque groupe DISTINCT ON.

Clause UNION
La clause UNION a la forme gnrale :
instruction_select UNION [ ALL | DISTINCT ] instruction_select
instruction_select est une instruction SELECT sans clause ORDER BY, LIMIT, FOR SHARE ou FOR UPDATE. (ORDER BY et LIMIT peuvent tre attachs une sous-expression si elle est entoure de parenthses. Sans parenthses, ces clauses
s'appliquent au rsultat de l'UNION, non l'expression sa droite.)
L'oprateur UNION calcule l'union ensembliste des lignes renvoyes par les instructions SELECT impliques. Une ligne est dans
l'union de deux ensembles de rsultats si elle apparat dans au moins un des ensembles. Les deux instructions SELECT qui reprsentent les oprandes directes de l'UNION doivent produire le mme nombre de colonnes et les colonnes correspondantes doivent
tre d'un type de donnes compatible.
1106

SELECT

Sauf lorsque l'option ALL est spcifie, il n'y a pas de doublons dans le rsultat de UNION. ALL empche l'limination des lignes
dupliques. UNION ALL est donc significativement plus rapide qu'UNION, et sera prfr. DISTINCT peut ventuellement tre
ajout pour prciser explicitement le comportement par dfaut : l'limination des lignes en double.
Si une instruction SELECT contient plusieurs oprateurs UNION, ils sont valus de gauche droite, sauf si l'utilisation de parenthses impose un comportement diffrent.
Actuellement, FOR UPDATE et FOR SHARE ne peuvent pas tre spcifis pour un rsultat d'UNION ou pour toute entre d'un
UNION.

Clause INTERSECT
La clause INTERSECT a la forme gnrale :
instruction_select INTERSECT [ ALL | DISTINCT ] instruction_select
instruction_select est une instruction SELECT sans clause ORDER BY, LIMIT, FOR UPDATE ou FOR SHARE.
L'oprateur INTERSECT calcule l'intersection des lignes renvoyes par les instructions SELECT impliques. Une ligne est dans
l'intersection des deux ensembles de rsultats si elle apparat dans chacun des deux ensembles.
Le rsultat d'INTERSECT ne contient aucune ligne duplique sauf si l'option ALL est spcifie. Dans ce cas, une ligne duplique
m fois dans la table gauche et n fois dans la table droite apparat min(m,n) fois dans l'ensemble de rsultats. DISTINCT peut ventuellement tre ajout pour prciser explicitement le comportement par dfaut : l'limination des lignes en double.
Si une instruction SELECT contient plusieurs oprateurs INTERSECT, ils sont valus de gauche droite, sauf si l'utilisation de
parenthses impose un comportement diffrent. INTERSECT a une priorit suprieur celle d'UNION. C'est--dire que A UNION
B INTERSECT C est lu comme A UNION (B INTERSECT C).
Actuellement, FOR UPDATE et FOR SHARE ne peuvent pas tre spcifis pour un rsultat d'INTERSECT ou pour une entre
d'INTERSECT.

Clause EXCEPT
La clause EXCEPT a la forme gnrale :
instruction_select EXCEPT [ ALL | DISTINCT ] instruction_select
instruction_select est une instruction SELECT sans clause ORDER BY, LIMIT, FOR UPDATE ou FOR SHARE.
L'oprateur EXCEPT calcule l'ensemble de lignes qui appartiennent au rsultat de l'instruction SELECT de gauche mais pas celui de droite.
Le rsultat d'EXCEPT ne contient aucune ligne duplique sauf si l'option ALL est spcifie. Dans ce cas, une ligne duplique m
fois dans la table gauche et n fois dans la table droite apparat max(m-n,0) fois dans l'ensemble de rsultats. DISTINCT peut
ventuellement tre ajout pour prciser explicitement le comportement par dfaut : l'limination des lignes en double.
Si une instruction SELECT contient plusieurs oprateurs EXCEPT, ils sont valus de gauche droite, sauf si l'utilisation de parenthses impose un comportement diffrent. EXCEPT a la mme priorit qu'UNION.
Actuellement, FOR UPDATE et FOR SHARE ne peuvent pas tre spcifis dans un rsultat EXCEPT ou pour une entre d'un EXCEPT.

Clause ORDER BY
La clause optionnelle ORDER BY a la forme gnrale :
ORDER BY expression [ ASC | DESC | USING oprateur ] [ NULLS { FIRST | LAST } ] [, ...]
La clause ORDER BY impose le tri des lignes de rsultat suivant les expressions spcifies. Si deux lignes sont identiques suivant
l'expression la plus gauche, elles sont compares avec l'expression suivante et ainsi de suite. Si elles sont identiques pour toutes
les expressions de tri, elles sont renvoyes dans un ordre dpendant de l'implantation.
Chaque expression peut tre le nom ou le numro ordinal d'une colonne en sortie (lment de la liste SELECT). Elle peut
aussi tre une expression arbitraire forme partir de valeurs des colonnes.
Le numro ordinal fait rfrence la position ordinale (de gauche droite) de la colonne de rsultat. Cette fonctionnalit permet
de dfinir un ordre sur la base d'une colonne dont le nom n'est pas unique. Ce n'est pas particulirement ncessaire parce qu'il est
toujours possible d'affecter un nom une colonne de rsultat avec la clause AS.
Il est aussi possible d'utiliser des expressions quelconques dans la clause ORDER BY, ce qui inclut des colonnes qui n'apparaissent
pas dans la liste rsultat du SELECT. Ainsi, l'instruction suivante est valide :
1107

SELECT

SELECT nom FROM distributeurs ORDER BY code;


Il y a toutefois une limitation cette fonctionnalit. La clause ORDER BY qui s'applique au rsultat d'une clause UNION, INTERSECT ou EXCEPT ne peut spcifier qu'un nom ou numro de colonne en sortie, pas une expression.
Si une expression ORDER BY est un nom qui correspond la fois celui d'une colonne rsultat et celui d'une colonne en entre,
ORDER BY l'interprte comme le nom de la colonne rsultat. Ce comportement est l'oppos de celui de GROUP BY dans la
mme situation. Cette incohrence est impose par la compatibilit avec le standard SQL.
Un mot cl ASC (ascendant) ou DESC (descendant) peut tre ajout aprs toute expression de la clause ORDER BY. ASC est la valeur utilise par dfaut. Un nom d'oprateur d'ordre spcifique peut galement tre fourni dans la clause USING. Un oprateur de
tri doit tre un membre plus-petit-que ou plus-grand-que de certaines familles d'oprateur B-tree. ASC est habituellement quivalent USING < et DESC USING >. Le crateur d'un type de donnes utilisateur peut dfinir sa guise le tri par dfaut qui
peut alors correspondre des oprateurs de nom diffrent.
Si NULLS LAST est indiqu, les valeurs NULL sont listes aprs toutes les valeurs non NULL si NULLS FIRST est indiqu,
les valeurs NULL apparaissent avant toutes les valeurs non NULL. Si aucune des deux n'est prsente, le comportement par dfaut
est NULLS LAST quand ASC est utilis (de faon explicite ou non) et NULLS FIRST quand DESC est utilis (donc la valeur par
dfaut est d'agir comme si les NULL taient plus grands que les non NULL). Quand USING est indiqu, le tri des NULL par dfaut dpend du fait que l'oprateur est un plus-petit-que ou un plus-grand-que.
Notez que les options de tri s'appliquent seulement l'expression qu'elles suivent. Par exemple, ORDER BY x, y DESC ne signifie pas la mme chose que ORDER BY x DESC, y DESC.
Les chanes de caractres sont tries suivant le collationnement qui s'applique la colonne trie. Ce collationnement est surchargeable si ncessaire en ajoutant une clause COLLATE dans l'expression, par exemple ORDER BY mycolumn COLLATE
"en_US". Pour plus d'informations, voir Section 4.2.10, Expressions de collationnement et Section 22.2, Support des collations .

Clause LIMIT
La clause LIMIT est constitue de deux sous-clauses indpendantes :
LIMIT { nombre | ALL }
OFFSET dbut
nombre spcifie le nombre maximum de lignes renvoyer alors que dbut spcifie le nombre de lignes passer avant de commencer renvoyer des lignes. Lorsque les deux clauses sont spcifies, dbut lignes sont passes avant de commencer compter
les nombre lignes renvoyer.
Si l'expression de compte est value NULL, il est trait comme LIMIT ALL, c'est--dire sans limite. Si dbut est valu
NULL, il est trait comme OFFSET 0.
SQL:2008 a introduit une sytaxe diffrente pour obtenir le mme rsultat. PostgreSQL supporte aussi cette syntaxe.
OFFSET dbut { ROW | ROWS }
FETCH { FIRST | NEXT } [ compte ] { ROW | ROWS } ONLY
Avec cette syntaxe, pour crire tout sauf une simple constant de type entier pour dbut ou compte, vous devez l'entourer de parenthses. Si compte est omis dans une clause FETCH, il vaut 1 par dfaut. ROW et ROWS ainsi que FIRST et NEXT sont des
mots qui n'influencent pas les effets de ces clauses. D'aprs le standard, la clause OFFSET doit venir avant la clause FETCH si les
deux sont prsentes ; PostgreSQL est plus laxiste et autorise un ordre diffrent.
Avec LIMIT, utiliser la clause ORDER BY permet de contraindre l'ordre des lignes de rsultat. Dans le cas contraire, le sousensemble obtenu n'est pas prvisible -- rien ne permet de savoir quel ordre correspondent les lignes retournes. Celui-ci ne sera
pas connu tant qu'ORDER BY n'aura pas t prcis.
Lors de la gnration d'un plan de requte, le planificateur tient compte de LIMIT. Le risque est donc grand d'obtenir des plans
qui diffrent (ordres des lignes diffrents) suivant les valeurs utilises pour LIMIT et OFFSET. Ainsi, slectionner des sousensembles diffrents d'un rsultat partir de valeurs diffrentes de LIMIT/OFFSET aboutit des rsultats incohrents moins
d'avoir fig l'ordre des lignes l'aide de la clause ORDER BY. Ce n'est pas un bogue, mais une consquence du fait que SQL
n'assure pas l'ordre de prsentation des rsultats sans utilisation d'une clause ORDER BY.
Il est mme possible pour des excutions rptes de la mme requte LIMIT de renvoyer diffrents sous-ensembles des lignes
d'une table s'il n'y a pas de clause ORDER BY pour forcer la slection d'un sous-ensemble dterministe. Encore une fois, ce n'est
pas un bogue ; le dterminisme des rsultats n'est tout simplement pas garanti dans un tel cas.

Clause FOR UPDATE/FOR SHARE


1108

SELECT

La clause FOR UPDATE a la forme :


FOR UPDATE [ OF nom_table [, ...] ] [ NOWAIT ]
La clause lie, FOR SHARE, a la forme :
FOR SHARE [ OF nom_table [, ...] ] [ NOWAIT ]
FOR UPDATE verrouille pour modification les lignes rcupres par l'instruction SELECT. Cela les empche d'tre modifies ou
supprimes par les autres transactions jusqu' la fin de la transaction en cours. Les autres transactions qui tentent des UPDATE,
DELETE ou SELECT FOR UPDATE sur ces lignes sont bloques jusqu' la fin de la transaction courante. De plus, si un UPDATE, DELETE ou SELECT FOR UPDATE a dj verrouill une ligne ou un ensemble de lignes partir d'une autre transaction, SELECT FOR UPDATE attend la fin de l'autre transaction puis verrouille et renvoie la ligne modifie (ou aucune ligne si
elle a t supprime). Cependant, au sein d'une transaction REPEATABLE READ ou SERIALIZABLE, une erreur est leve si une
ligne verrouiller chang depuis le dbut de la transaction. Pour plus d'informations, voir Chapitre 13, Contrle d'accs simultan.
FOR SHARE a un comportement similaire. La diffrence se situe dans le type de verrou acquis. Contrairement FOR UPDATE
qui pose un verrou exclusif, FOR SHARE pose un verrou partag sur chaque ligne rcupre. Un verrou partage bloque les instructions UPDATE, DELETE ou SELECT FOR UPDATE des transaction concurrentes accdant ces lignes, mais il n'interdit
pas les SELECT FOR SHARE.
Pour viter l'opration d'attendre la validation des autres transactions, on utilise l'option NOWAIT. SELECT FOR UPDATE
NOWAIT rapporte une erreur si une ligne slectionne ne peut pas tre verrouille immdiatement. Il n'y a pas d'attente. NOWAIT
s'applique seulement au(x) verrou(x) niveau ligne -- le verrou niveau table ROW SHARE est toujours pris de faon ordinaire (voir
Chapitre 13, Contrle d'accs simultan). L'option NOWAIT de LOCK(7) peut toujours tre utilise pour acqurir le verrou niveau
table sans attendre.
Si des tables particulires sont nommes dans les clauses FOR UPDATE et FOR SHARE, alors seules les lignes provenant de ces
tables sont verrouilles ; toute autre table utilise dans le SELECT est simplement lue. Une clause FOR UPDATE ou FOR
SHARE sans liste de tables affecte toute les tables utilises dans l'instruction. Si FOR UPDATE ou FOR SHARE est applique
une vue ou une sous-requte, cela affecte toutes les tables utilises dans la vue ou la sous-requte. Nanmoins, FOR
UPDATE/FOR SHARE ne s'appliquent pas aux requtes WITH rfrences par la cl primaire. Si vous voulez qu'un verrouillage
de lignes intervienne dans une requte WITH, spcifiez FOR UPDATE ou FOR SHARE l'intrieur de la requte WITH.
Plusieurs clauses FOR UPDATE et FOR SHARE peuvent tre donnes si il est ncessaire de spcifier diffrents comportements
de verrouillage pour diffrentes tables. Si la mme table est mentionn (ou affecte implicitement) par les clauses FOR UPDATE
et FOR SHARE, alors elle est traite comme un simple FOR UPDATE. De faon similaire, une table est traite avec NOWAIT si
c'est spcifie sur au moins une des clauses qui l'affectent.
FOR UPDATE et FOR SHARE ncessitent que chaque ligne retourne soit clairement identifiable par une ligne individuelle d'une
table ; ces options ne peuvent, par exemple, pas tre utilises avec des fonctions d'agrgats.
Quand FOR UPDATE ou FOR SHARE apparaissent au niveau le plus lev d'une requte SELECT, les lignes verrouilles sont
exactement celles qui sont renvoyes par la requte ; dans le cas d'une requte avec jointure, les lignes verrouilles sont celles qui
contribuent aux lignes jointes renvoyes. De plus, les lignes qui ont satisfait aux conditions de la requte au moment de la prise de
son instantan sont verrouilles, bien qu'elles ne seront pas retournes si elles ont t modifies aprs la prise du snapshot et ne satisfont plus les conditions de la requte. Si LIMIT est utilis, le verrouillage cesse une fois que suffisamment de lignes ont t renvoyes pour satisfaire la limite (mais notez que les lignes ignores cause de la clause OFFSET seront verrouilles). De la mme
manire, si FOR UPDATE ou FOR SHARE est utilis pour la requte d'un curseur, seules les lignes rellement rcupres ou parcourues par le curseur seront verrouilles.
Si FOR UPDATE ou FOR SHARE apparaissent dans un sous-SELECT, les lignes verrouilles sont celles renvoyes par la sousrequte la requte externe. Cela peut concerner moins de lignes que l'tude de la sous-requte seule pourrait faire penser, parce
que les conditions de la requte externe peuvent tre utilises pour optimiser l'excution de la sous-requte. Par exemple,
SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss WHERE col1 = 5;
verrouillera uniquement le lignes pour lesquelles col1 = 5, mme si cette condition n'est pas crite dans la sous-requte.

Attention
vitez de verrouiller une ligne puis de la modifier aprs un nouveau point de sauvegarde ou aprs un bloc
d'exception PL/pgSQL. L'annulation suivante pourrait causer la perte du verrou. Par exemple :
BEGIN;
1109

SELECT

SELECT * FROM ma_table WHERE cle = 1 FOR UPDATE;


SAVEPOINT s;
UPDATE ma_table SET ... WHERE cle = 1;
ROLLBACK TO s;
Aprs le ROLLBACK, la ligne est rellement dverrouille au lieu de retourner son tat avant le point de sauvegarde. Ceci peut arriver si une ligne verrouille dans la transaction en cours est mise jour ou supprime, ou si un
verrou partag est pass en verrou exclusif : dans tous ces cas, l'tat prcdent du verrou est oubli. Si la transaction
est ensuite annule un tat entre la commande de verrou initiale et la modification qui a suivi, la ligne n'apparatra
plus verrouille. Ceci est une dficience de l'implmentation qui sera corrige dans une prochaine version de PostgreSQL.

Attention
Il est possible qu'une commande SELECT excute au niveau d'isolation READ COMMITTED et utilisant ORDER
BY et FOR UPDATE/SHARE renvoie les lignes dans le dsordre. C'est possible car l' ORDER BY est appliqu en
premier. La commande trie le rsultat, mais peut alors tre bloque le temps d'obtenir un verrou sur une ou plusieurs des lignes. Une fois que le SELECT est dbloqu, des valeurs sur la colonne qui sert ordonner peuvent
avoir t modifies, ce qui entrane ces lignes apparaissant dans le dsordre (bien qu'elles soient dans l'ordre par
rapport aux valeurs d'origine de ces colonnes). Ceci peut tre contourn si besoin en plaant la clause FOR UPDATE/SHARE dans une sous-requte, par exemple
SELECT * FROM (SELECT * FROM matable FOR UPDATE) ss ORDER BY column1;
Notez que cela entrane le verrouillage de toutes les lignes de matable, alors que FOR UPDATE au niveau suprieur
verrouillerait seulement les lignes rellement renvoyes. Cela peut causer une diffrence de performance significative, en particulier si l' ORDER BY est combin avec LIMIT ou d'autres restrictions. Cette technique est donc recommande uniquement si vous vous attendez des mises jour concurrentes sur les colonnes servant
l'ordonnancement et qu'un rsultat strictement ordonn est requis.
Au niveau d'isolation de transactions REPEATABLE READ et SERIALIZABLE, cela causera une erreur de srialisation (avec un SQLSTATE valant '40001'), donc il n'est pas possible de recevoir des lignes non tries avec ces
niveaux d'isolation.

Commande TABLE
La commande
TABLE nom
est compltement quivalente
SELECT * FROM nom
Elle peut tre utilise comme commande principale d'une requte, ou bien comme une variante syntaxique permettant de gagner
de la place dans des parties de requtes complexes.

Exemples
Joindre la table films avec la table distributeurs :
SELECT f.titre, f.did, d.nom, f.date_prod, f.genre
FROM distributeurs d, films f
WHERE f.did = d.did
titre
| did |
nom
| date_prod |
genre
-------------------+-----+--------------+------------+-----------The Third Man
| 101 | British Lion | 1949-12-23 | Drame
The African Queen | 101 | British Lion | 1951-08-11 | Romantique
...
Additionner la colonne longueur de tous les films, grouper les rsultats par genre :
SELECT genre, sum(longueur) AS total FROM films GROUP BY genre;
1110

SELECT

genre
| total
------------+------Action
| 07:34
Comdie
| 02:58
Drame
| 14:28
Musical
| 06:42
Romantique | 04:38
Additionner la colonne longueur de tous les films, grouper les rsultats par genre et afficher les groupes dont les totaux font
moins de cinq heures :
SELECT genre, sum(longueur) AS total
FROM films
GROUP BY genre
HAVING sum(longueur) < interval '5 hours';
genre
| total
------------+------Comedie
| 02:58
Romantique | 04:38
Les deux exemples suivants reprsentent des faons identiques de trier les rsultats individuels en fonction du contenu de la
deuxime colonne (nom) :
SELECT * FROM distributeurs ORDER BY nom;
SELECT * FROM distributeurs ORDER BY 2;
did |
nom
-----+-----------------109 | 20th Century Fox
110 | Bavaria Atelier
101 | British Lion
107 | Columbia
102 | Jean Luc Godard
113 | Luso films
104 | Mosfilm
103 | Paramount
106 | Toho
105 | United Artists
111 | Walt Disney
112 | Warner Bros.
108 | Westward
L'exemple suivant prsente l'union des tables distributeurs et acteurs, restreignant les rsultats ceux de chaque table
dont la premire lettre est un W. Le mot cl ALL est omis, ce qui permet de n'afficher que les lignes distinctes.
distributeurs:
did |
nom
-----+-------------108 | Westward
111 | Walt Disney
112 | Warner Bros.
...

acteurs:
id |
nom
----+---------------1 | Woody Allen
2 | Warren Beatty
3 | Walter Matthau
...

SELECT distributeurs.nom
FROM distributeurs
WHERE distributeurs.nom LIKE 'W%'
UNION
SELECT actors.nom
FROM acteurs
WHERE acteurs.nom LIKE 'W%';
nom
---------------Walt Disney
Walter Matthau
Warner Bros.
Warren Beatty
1111

SELECT

Westward
Woody Allen
L'exemple suivant prsente l'utilisation d'une fonction dans la clause FROM, avec et sans liste de dfinition de colonnes :
CREATE FUNCTION distributeurs(int) RETURNS SETOF distributeurs AS $$
SELECT * FROM distributeurs WHERE did = $1;
$$ LANGUAGE SQL;
SELECT * FROM distributeurs(111);
did |
name
-----+------------111 | Walt Disney
CREATE FUNCTION distributeurs_2(int) RETURNS SETOF record AS $$
SELECT * FROM distributeurs WHERE did = $1;
$$ LANGUAGE SQL;
SELECT * FROM distributeurs_2(111) AS (f1 int, f2 text);
f1 |
f2
-----+------------111 | Walt Disney
Cet exemple montre comment utiliser une clause WITH simple:
WITH t AS (
SELECT random() as x FROM generate_series(1, 3)
)
SELECT * FROM t
UNION ALL
SELECT * FROM t
x
-------------------0.534150459803641
0.520092216785997
0.0735620250925422
0.534150459803641
0.520092216785997
0.0735620250925422
Notez que la requte WITH n'a t value qu'une seule fois, ce qui fait qu'on a deux jeux contenant les mmes trois valeurs.
Cet exemple utilise WITH RECURSIVE pour trouver tous les subordonns (directs ou indirects) de l'employe Marie, et leur niveau de subordination, partir d'une table qui ne donne que les subordonns directs :
WITH RECURSIVE recursion_employes(distance, nom_employe, nom_manager) AS (
SELECT 1, nom_employe, nom_manager
FROM employe
WHERE nom_manager = 'Marie'
UNION ALL
SELECT er.distance + 1, e.nom_employe, e.nom_manager
FROM recursion_employes er, employe e
WHERE er.nom_employe = e.nom_manager
)
SELECT distance, nom_employe FROM recursion_employes;
Notez la forme typique des requtes rcursives : une condition initiale, suivie par UNION, suivis par la partie rcursive de la requte. Assurez-vous que la partie rcursive de la requte finira par ne plus retourner d'enregistrement, sinon la requte bouclera indfiniment (Voir Section 7.8, Requtes WITH (Common Table Expressions) pour plus d'exemples).

Compatibilit
L'instruction SELECT est videmment compatible avec le standard SQL. Mais il y a des extensions et quelques fonctionnalits
manquantes.

Clauses FROM omises


1112

SELECT

PostgreSQL autorise l'omission de la clause FROM. Cela permet par exemple de calculer le rsultat d'expressions simples :
SELECT 2+2;
?column?
---------4
D'autres bases de donnes SQL interdisent ce comportement, sauf introduire une table virtuelle d'une seule ligne sur laquelle
excuter la commande SELECT.
S'il n'y a pas de clause FROM, la requte ne peut pas rfrencer les tables de la base de donnes. La requte suivante est, ainsi, invalide :
SELECT distributors.* WHERE distributors.name = 'Westward';
Les versions antrieures PostgreSQL 8.1 acceptaient les requtes de cette forme en ajoutant une entre implicite la clause
FROM pour chaque table rfrence. Ce n'est plus autoris.

Omettre le mot cl AS
Dans le standard SQL, le mot cl AS peut tre omis devant une colonne de sortie partir du moment o le nouveau nom de colonne est un nom valide de colonne (c'est--dire, diffrent d'un mot cl rserv). PostgreSQL est lgrement plus restrictif : AS
est ncessaire si le nouveau nom de colonne est un mot cl quel qu'il soit, rserv ou non. Il est recommand d'utiliser AS ou des
colonnes de sortie entoures de guillemets, pour viter tout risque de conflit en cas d'ajout futur de mot cl.
Dans les lments de FROM, le standard et PostgreSQL permettent que AS soit omis avant un alias qui n'est pas un mot cl rserv. Mais c'est peu pratique pour les noms de colonnes, causes d'ambiguts syntaxiques.

ONLY et l'hritage
Le standard SQL impose des parenthses autour du nom de table aprs la clause ONLY, comme dans SELECT * FROM ONLY
(tab1), ONLY (tab2) WHERE .... PostgreSQL considre les parenthses comme tant optionnelles.
PostgreSQL autorise une * en fin pour indiquer explicitement le comportement oppos de la clause ONLY (donc inclure les
tables filles). Le standard ne le permet pas.
(Ces points s'appliquent de la mme faon toutes les commandes SQL supportant l'option ONLY.)

Espace logique disponible pour GROUP BY et ORDER BY


Dans le standard SQL-92, une clause ORDER BY ne peut utiliser que les noms ou numros des colonnes en sortie, une clause
GROUP BY que des expressions fondes sur les noms de colonnes en entre. PostgreSQL va plus loin, puisqu'il autorise chacune de ces clauses utiliser galement l'autre possibilit. En cas d'ambigut, c'est l'interprtation du standard qui prvaut. PostgreSQL autorise aussi l'utilisation d'expressions quelconques dans les deux clauses. Les noms apparaissant dans ces expressions
sont toujours considrs comme nom de colonne en entre, pas en tant que nom de colonne du rsultat.
SQL:1999 et suivant utilisent une dfinition lgrement diffrente, pas totalement compatible avec le SQL-92. Nanmoins, dans la
plupart des cas, PostgreSQL interprte une expression ORDER BY ou GROUP BY en suivant la norme SQL:1999.

Dpendances fonctionnelles
PostgreSQL reconnat les dpendances fonctionnelles (qui permettent que les nom des colonnes ne soient pas dans le GROUP
BY) seulement lorsqu'une cl primaire est prsente dans la liste du GROUP BY. Le standard SQL spcifie des configurations supplmentaires qui doivent tre reconnues.

Restrictions sur la clause WINDOW


Le standard SQL fournit des options additionnelles pour la clause_frame des window. PostgreSQL ne supporte ce jour
que les options mentionnes prcdemment.

LIMIT et OFFSET
Les clauses LIMIT et OFFSET sont une syntaxe spcifique PostgreSQL, aussi utilise dans MySQL. La norme SQL:2008
a introduit les clauses OFFSET ... FETCH {FIRST|NEXT}... pour la mme fonctionnalit, comme montr plus haut dans
la section intitule Clause LIMIT . Cette syntaxe est aussi utilise par IBM DB2. (Les applications crites pour Oracle
contournent frquemment le problme par l'utilisation de la colonne auto-gnre rownum pour obtenir les effets de ces clauses,
qui n'est pas disponible sous PostgreSQL,)

1113

SELECT

FOR UPDATE and FOR SHARE


Bien que FOR UPDATE soit prsent dans le standard SQL, le standard ne l'autorise que comme une option de DECLARE CURSOR. PostgreSQL l'autorise dans toute requte SELECT et dans toute sous-requte SELECT, mais c'est une extension. Ni la
variante FOR SHARE, ni l'option NOWAIT n'apparaissent dans le standard.

Ordre de modification de donnes dans un WITH


PostgreSQL permet que les clauses INSERT, UPDATE, et DELETE soient utilises comme requtes WITH. Ceci n'est pas
prsent dans le standard SQL.

Clauses non standard


La clause DISTINCT ON n'est pas dfinie dans le standard SQL.

1114

Nom
SELECT INTO dfinit une nouvelle table partir des rsultats d'une requte

Synopsis
[ WITH [ RECURSIVE ] requte_with [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
* | expression [ [ AS ] nom_en_sortie ] [, ...]
INTO [ TEMPORARY | TEMP | UNLOGGED ] [ TABLE ] nouvelle_table
[ FROM lment_from [, ...] ]
[ WHERE condition ]
[ GROUP BY expression [, ...] ]
[ HAVING condition [, ...] ]
[ WINDOW nom_window AS ( dfinition_window ) [, ...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC | USING oprateur ] [, ...] ]
[ LIMIT { nombre | ALL } ]
[ OFFSET dbut [ ROW | ROWS ] ]
[ FETCH { FIRST | NEXT } [ nombre ] { ROW | ROWS } ONLY ]
[ FOR { UPDATE | SHARE } [ OF nomtable [, ...] ] [ NOWAIT ] [...] ]

Description
SELECT INTO cre une nouvelle table en la remplissant avec des donnes rcupres par une requte. Les donnes ne sont
pas renvoyes au client comme le fait habituellement l'instruction SELECT. Les nouvelles colonnes de la table ont les noms et
les types de donnes associs avec les colonnes en sortie du SELECT.

Paramtres
TEMPORARY ou TEMP
Si spcifi, la table est cre comme une table temporaire. Rfrez-vous CREATE TABLE(7) pour plus de dtails.
UNLOGGED
Si spcifi, la table est cre comme une table non trace dans les journaux de transactions. Voir CREATE TABLE(7) pour
plus de dtails.
new_table
Le nom de la table crer (pouvant tre qualifi par le nom du schma).
Tous les autres paramtres sont dcrits en dtail dans SELECT(7).

Notes
CREATE TABLE AS(7) est fonctionnellement quivalent SELECT INTO. CREATE TABLE AS est la syntaxe recommande car cette forme de SELECT INTO n'est pas disponible dans ECPG ou PL/pgSQL. En effet, ils interprtent la clause INTO
diffremment. De plus, CREATE TABLE AS offre un ensemble de fonctionnalits plus important que celui de SELECT INTO.
Avant PostgreSQL 8.1, la table cre par SELECT INTO incluait des OID par dfaut. Dans PostgreSQL 8.1, ce n'est plus
le cas -- pour inclure des OID dans la nouvelle table, la variable de configuration default_with_oids doit tre active. Autrement,
CREATE TABLE AS peut aussi tre utilis avec la clause WITH OIDS.

Exemples
Cre une nouvelle table films_recent ne contenant que les entres rcentes de la table films:
SELECT * INTO films_recent FROM films WHERE date_prod >= '2002-01-01';

Compatibilit
Le standard SQL utilise SELECT INTO pour reprsenter la slection de valeurs dans des variables scalaires d'un programme
hte plutt que la cration d'une nouvelle table. Ceci est en fait l'utilisation trouve dans ECPG (voir Chapitre 33, ECPG SQL
embarqu en C) et dans PL/pgSQL (voir Chapitre 39, PL/pgSQL - Langage de procdures SQL). L'usage de PostgreSQL de
1115

SELECT INTO

SELECT INTO pour reprsenter une cration de table est historique. Il est prfrable d'utiliser CREATE TABLE AS dans un
nouveau programme.

Voir aussi
CREATE TABLE AS(7)

1116

Nom
SET change un paramtre d'excution

Synopsis
SET [ SESSION | LOCAL ] paramtre_configuration { TO | = } { valeur | 'valeur' |
DEFAULT }
SET [ SESSION | LOCAL ] TIME ZONE { fuseau-horaire | LOCAL | DEFAULT }

Description
La commande SET permet de modifier les paramtres d'excution. Un grand nombre de paramtres d'excution, lists dans
Chapitre 18, Configuration du serveur, peuvent tre modifis la vole avec la commande SET. SET ne modifie que les paramtres utiliss par la session courante.
Certains paramtres ne peuvent tre modifis que par le superutilisateur, d'autres ne peuvent plus tre changs aprs le dmarrage du serveur ou de la session.
Si SET ou SET SESSION sont utiliss dans une transaction abandonne par la suite, les effets de la commande SET disparaissent ds l'annulation de la transaction. Lorsque la transaction englobant la commande est valide, les effets de la commande
persistent jusqu' la fin de la session, moins qu'ils ne soient annuls par une autre commande SET.
Les effets de SET LOCAL ne durent que jusqu' la fin de la transaction en cours, qu'elle soit valide ou non. Dans le cas particulier d'une commande SET suivie par SET LOCAL dans une mme transaction, la valeur de SET LOCAL est utilise jusqu'
la fin de la transaction, et celle de SET prend effet ensuite (si la transaction est valide).
Les effets de SET et SET LOCAL sont aussi annuls par le retour un point de sauvegarde prcdant la commande.
Si SET LOCAL est utilis l'intrieur d'une fonction qui comprend l'option SET pour la mme variable (voir CREATE FUNCTION(7)), les effets de la commande SET LOCAL disparatront la sortie de la fonction ; en fait, la valeur disponible lors de
l'appel de la fonction est restaure de toute faon. Ceci permet l'utilisation de SET LOCAL pour des modifications dynamiques
et rptes d'un paramtre l'intrieur d'une fonction, avec l'intrt d'utiliser l'option SET pour sauvegarder et restaurer la valeur
de l'appelant. Nanmoins, une commande SET standard surcharge toute option SET de la fonction ; son effet persistera sauf en
cas d'annulation.

Note
De PostgreSQL version 8.0 8.2, les effets de SET LOCAL sont annuls suite au relachement d'un point de
sauvegarde prcdent, ou par une sortie avec succs d'un bloc d'exception PL/pgSQL. Ce comportement a t
modifi car il n'tait pas du tout intuitif.

Paramtres
SESSION
Indique que la commande prend effet pour la session courante. C'est la valeur par dfaut lorsque SESSION et LOCAL sont
omis.
LOCAL
Indique que la commande n'est effective que pour la transaction courante. Aprs COMMIT ou ROLLBACK, la valeur de
session redevient effective. Une commande SET LOCAL est sans effet si elle est excute en dehors d'un bloc BEGIN car
la transaction prend immdiatement fin.
paramtre_configuration
Nom d'un paramtre ajustable pendant l'excution. La liste des paramtres disponibles est documente dans Chapitre 18,
Configuration du serveur et ci-dessous.
valeur
Nouvelle valeur du paramtre. Les valeurs peuvent tre indiques sous forme de constantes de chane, d'identifiants, de
nombres ou de listes de ceux-ci, spares par des virgules, de faon appropri pour ce paramtre. DEFAULT peut tre utilis
pour repositionner le paramtre sa valeur par dfaut (c'est--dire quelque soit la valeur qu'il aurait eu si aucun SET n'avait
t excut lors de cette session).
En plus des paramtres de configuration documents dans Chapitre 18, Configuration du serveur, il y en a quelques autres qui ne
1117

SET

peuvent tre initialiss qu'avec la commande SET ou ont une syntaxe spciale.
SCHEMA
SET SCHEMA 'valeur' est un alias pour SET search_path TO valeur. Seul un schma peut tre prcis en utilisant cette syntaxe.
NAMES
SET NAMES valeur est un quivalent de SET client_encoding TO valeur.
SEED
Prcise la valeur interne du gnrateur de nombres alatoires (la fonction random). Les valeurs autorises sont des nombres
virgule flottante entre -1 et 1, qui sont ensuite multiplis par 231-1.
Le gnrateur de nombres alatoires peut aussi tre initialis en appelant la fonction setseed :
SELECT setseed(valeur);
TIME ZONE
SET TIME ZONE valeur est quivalent SET timezone TO valeur. La syntaxe SET TIME ZONE permet
d'utiliser une syntaxe spciale pour indiquer le fuseau horaire. Quelques exemples de valeurs valides :
'PST8PDT'
Le fuseau horaire de Berkeley, Californie.
'Europe/Rome'
Le fuseau horaire de l'Italie.
-7
Le fuseau horaire situ 7 heures l'ouest de l'UTC (quivalent PDT). Les valeurs positives sont l'est de l'UTC.
INTERVAL '-08:00' HOUR TO MINUTE
Le fuseau horaire situ 8 heures l'ouest de l'UTC (quivalent PST).
LOCAL, DEFAULT
Utilise le fuseau horaire local (c'est--dire la valeur timezone par dfaut du serveur ; si cette dernire n'est pas explicitement configure, il utilise la zone par dfaut du systme d'exploitation).
Voir Section 8.5.3, Fuseaux horaires pour de plus amples informations sur les fuseaux horaires.

Notes
La fonction set_config propose des fonctionnalits quivalentes. Voir Section 9.24, Fonctions d'administration systme .
De plus, il est possible de mettre jour (via UPDATE) la vue systme pg_settings pour raliser l'quivalent de SET.

Exemples
Mettre jour le chemin de recherche :
SET search_path TO my_schema, public;
Utiliser le style de date traditionnel POSTGRES avec comme convention de saisie les jours avant les mois :
SET datestyle TO postgres, dmy;
Utiliser le fuseau horaire de Berkeley, Californie :
SET TIME ZONE 'PST8PDT';
Utiliser le fuseau horaire de l'Italie :
SET TIME ZONE 'Europe/Rome';

Compatibilit
SET TIME ZONE tend la syntaxe dfinie dans le standard SQL. Le standard ne permet que des fuseaux horaires numriques
alors que PostgreSQL est plus souple dans les syntaxes acceptes. Toutes les autres fonctionnalits de SET sont des extensions
de PostgreSQL.

Voir aussi
1118

SET

RESET(7), SHOW(7)

1119

Nom
SET CONSTRAINTS initialise le moment de vrification de contrainte de la transaction en cours

Synopsis
SET CONSTRAINTS { ALL | nom [, ...] } { DEFERRED | IMMEDIATE }

Description
SET CONSTRAINTS initialise le comportement de la vrification des contraintes dans la transaction en cours. Les contraintes
IMMEDIATE sont vrifies la fin de chaque instruction. Les contraintes DEFERRED ne sont vrifies qu' la validation de la
transaction. Chaque contrainte a son propre mode IMMEDIATE ou DEFERRED.
la cration, une contrainte se voit donner une des trois caractristiques : DEFERRABLE INITIALLY DEFERRED, DEFERRABLE INITIALLY IMMEDIATE ou NOT DEFERRABLE. La troisime forme est toujours IMMEDIATE et n'est pas affecte par la commande SET CONSTRAINTS. Les deux premires classes commencent chaque transaction dans le mode indiqu
mais leur comportement peut changer l'intrieur d'une transaction par SET CONSTRAINTS.
SET CONSTRAINTS avec une liste de noms de contraintes modifie le mode de ces contraintes (qui doivent toutes tre diffrables). Chaque nom de contrainte peut tre qualifi d'un schma. Le chemin de recherche des schmas est utilis pour trouver le
premier nom correspondant si aucun nom de schma n'a t indiqu. SET CONSTRAINTS ALL modifie le mode de toutes les
contraintes dfrables.
Lorsque SET CONSTRAINTS modifie le mode d'une contrainte de DEFERRED IMMEDIATE, le nouveau mode prend effet
rtroactivement : toute modification de donnes qui aurait t vrifie la fin de la transaction est en fait vrifie lors de
l'excution de la commande SET CONSTRAINTS. Si une contrainte est viole, la commande SET CONSTRAINTS choue
(et ne change pas le mode de contrainte). Du coup, SET CONSTRAINTS peut tre utilise pour forcer la vrification de
contraintes un point spcifique d'une transaction.
Actuellement, seules les contraintes UNIQUE, PRIMARY KEY, REFERENCES (cl trangre) et EXCLUDE sont affectes par
ce paramtre. Les contraintes NOT NULL et CHECK sont toujours vrifies immdiatement quand une ligne est insre ou modifie (pas la fin de l'instruction). Les contraintes uniques et d'exclusion qui n'ont pas t dclares DEFERRABLE sont aussi
vrifies immdiatement.
Le dclenchement des triggers qui sont dclars comme des triggers de contraintes est aussi contrl par ce paramtre -- ils
se dclenchent au mme moment que la contrainte associe devait tre vrifie.

Notes
Comme PostgreSQL ne ncessite pas les noms de contraintes d'tre uniques l'intrieur d'un schma (mais seulement par
tables), il est possible qu'il y ait plus d'une correspondance pour un nom de contrainte spcifi. Dans ce cas, SET
CONSTRAINTS agira sur toutes les correspondances. Pour un nom sans qualification de schma, une fois qu'une ou plusieurs
correspondances ont t trouves dans les schmas du chemin de recherche, les autres schmas du chemin ne sont pas tests.
Cette commande altre seulement le comportement des contraintes l'intrieur de la transaction en cours. Du coup, si vous excutez cette commande en dehors d'un bloc de transaction (pair BEGIN/COMMIT), elle ne semble pas avoir d'effet.

Compatibilit
Cette commande est compatible avec le comportement dfini par le standard SQL en dehors du fait que, dans PostgreSQL, il
ne s'applique pas aux contraintes NOT NULL et CHECK. De plus, PostgreSQL vrifie les contraintes uniques non dferrables
immdiatement, pas la fin de l'instruction comme le standard le suggre.

1120

Nom
SET ROLE initialise l'identifiant utilisateur courant de la session en cours

Synopsis
SET [ SESSION | LOCAL ] ROLE nom_rle
SET [ SESSION | LOCAL ] ROLE NONE
RESET ROLE

Description
Cette commande positionne l'identifiant utilisateur courant suivant la session SQL en cours nom_rle. Le nom du rle peut
tre un identifiant ou une chane littrale. Aprs SET ROLE, la vrification des droits sur les commandes SQL est identique
ce qu'elle serait si le rle nomm s'tait lui-mme connect.
Il est obligatoire que l'utilisateur de la session courante soit membre du rle nom_rle (si l'utilisateur de la session est superutilisateur, tous les rles sont utilisables).
Les modificateurs SESSION et LOCAL agissent de la mme faon que pour la commande SET(7).
Les formes NONE et RESET rinitialisent l'identifiant de l'utilisateur la valeur de session. Ces formes peuvent tre excutes
par tout utilisateur.

Notes
L'utilisation de cette commande permet d'tendre ou de restreindre les privilges d'un utilisateur. Si le rle de l'utilisateur de la
session comprend l'attribut INHERITS, alors il acquiert automatiquement les droits de chaque rle qu'il peut prendre par la
commande SET ROLE ; dans ce cas, SET ROLE supprime tous les droits affects directement l'utilisateur de la session et les
autres droits des rles dont il est membre, ne lui laissant que les droits disponibles sur le rle nomm. A l'oppos, si le rle session de l'utilisateur dispose de l'attribut NOINHERITS, SET ROLE supprime les droits affects directement l'utilisateur session et les remplace par les privilges du rle nomm.
En particulier, quand un utilisateur choisit un rle autre que superutilisateur via SET ROLE, il perd les droits superutilisateur.
SET ROLE a des effets comparables SET SESSION AUTHORIZATION(7) mais la vrification des droits diffre. De plus,
SET SESSION AUTHORIZATION dtermine les rles autoriss dans les commandes SET ROLE ultrieures alors que SET
ROLE ne modifie pas les rles accessibles par un futur SET ROLE.
SET ROLE ne traite pas les variables de session indiqu par les paramtres du rle (et configurs avec ALTER ROLE(7) ; cela
ne survient qu' la connexion.
SET ROLE ne peut pas tre utilis dans une fonction SECURITY DEFINER.

Exemples
SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+-------------peter
| peter
SET ROLE 'paul';
SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+-------------peter
| paul

Compatibilit
PostgreSQL autorise la syntaxe identifiant ("nom_role") alors que le SQL standard impose une chane littrale pour le
nom du rle. SQL n'autorise pas cette commande lors d'une transaction ; PostgreSQL n'est pas aussi restrictif, rien ne justifie
cette interdiction. Les modificateurs SESSION et LOCAL sont des extensions PostgreSQL tout comme la syntaxe RESET.

1121

SET ROLE

Voir aussi
SET SESSION AUTHORIZATION(7)

1122

Nom
SET SESSION AUTHORIZATION Initialise l'identifiant de session de l'utilisateur et l'identifiant de l'utilisateur actuel de la
session en cours

Synopsis
SET [ SESSION | LOCAL ] SESSION AUTHORIZATION nom_utilisateur
SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT
RESET SESSION AUTHORIZATION

Description
Cette commande positionne l'identifiant de session de l'utilisateur et celui de l'utilisateur courant pour la session SQL en cours
nom_utilisateur. Le nom de l'utilisateur peut tre un identifiant ou une chane littrale. En utilisant cette commande, il est
possible, par exemple, de devenir temporairement un utilisateur non privilgi et de redevenir plus tard superutilisateur.
L'identifiant de session de l'utilisateur est initialement positionn au nom de l'utilisateur (ventuellement authentifi) fourni par
le client. L'identifiant de l'utilisateur courant est habituellement identique l'identifiant de session de l'utilisateur mais il peut
tre temporairement modifi par le contexte de fonctions SECURITY DEFINER ou de mcanismes similaires ; il peut aussi
tre chang par SET ROLE(7). L'identifiant de l'utilisateur courant est essentiel la vrification des permissions.
L'identifiant de session de l'utilisateur ne peut tre chang que si l'utilisateur de session initial (l'utilisateur authentifi) dispose
des privilges superutilisateur. Dans le cas contraire, la commande n'est accepte que si elle fournit le nom de l'utilisateur authentifi.
Les modificateurs SESSION et LOCAL agissent de la mme faon que la commande standard SET(7).
Les formes DEFAULT et RESET rinitialisent les identifiants courant et de session de l'utilisateur ceux de l'utilisateur originellement authentifi. Tout utilisateur peut les excuter.

Notes
SET SESSION AUTHORIZATION ne peut pas tre utilis dans une fonction SECURITY DEFINER.

Exemples
SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+-------------peter
| peter
SET SESSION AUTHORIZATION 'paul';
SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+-------------paul
| paul

Compatibilit
Le standard SQL autorise l'apparition de quelques autres expressions la place de nom_utilisateur. Dans la pratique, ces
expressions ne sont pas importantes. PostgreSQL autorise la syntaxe de l'identifiant ("nom_utilisateur") alors que
SQL ne le permet pas. SQL n'autorise pas l'excution de cette commande au cours d'une transaction ; PostgreSQL n'impose
pas cette restriction parce qu'il n'y a pas lieu de le faire. Les modificateurs SESSION et LOCAL sont des extensions
PostgreSQL tout comme la syntaxe RESET.
Le standard laisse la dfinition des droits ncessaires l'excution de cette commande l'implantation.

Voir aussi
SET ROLE(7)

1123

Nom
SET TRANSACTION initialise les caractristiques de la transaction actuelle

Synopsis
SET TRANSACTION mode_transaction [, ...]
SET SESSION CHARACTERISTICS AS TRANSACTION mode_transaction [, ...]
o mode_transaction fait
partie de :
ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ
UNCOMMITTED }
READ WRITE | READ ONLY
[ NOT ] DEFERRABLE

Description
La commande SET TRANSACTION initialise les caractristiques de la transaction courante. Elle est sans effet sur les transactions suivantes. SET SESSION CHARACTERISTICS positionne les caractristiques par dfaut pour toutes les transactions
venir d'une session. Ces valeurs peuvent ensuite tre surcharges par SET TRANSACTION pour une transaction particulire.
Les caractristiques de transaction disponibles sont le niveau d'isolation, le mode d'accs de la transaction (lecture/criture ou
lecture seule) et le mode diffrable.
Le niveau d'isolation dtermine les donnes que la transaction peut voir quand d'autres transactions fonctionnent concurrentiellement :
READ COMMITTED
Une instruction ne peut voir que les lignes valides avant qu'elle ne commence. C'est la valeur par dfaut.
REPEATABLE READ
Toute instruction de la transaction en cours ne peut voir que les lignes valides avant que la premire requte ou instruction
de modification de donnes soit excute dans cette transaction.
SERIALIZABLE
Toutes les requtes de la transaction en cours peuvent seulement voir les lignes valides avant l'excution de la premire requte ou instruction de modification de donnes de cette transaction. Si un ensemble de lectures et critures parmi les transactions srialisables concurrentes crait une situation impossible obtenir avec une excution en srie (une la fois) de ces
transactions, l'une d'entre elles sera annule avec un tat SQLSTATE serialization_failure.
Le standard SQL dfinit un niveau supplmentaire, READ UNCOMMITTED. Dans PostgreSQL, READ UNCOMMITTED est
trait comme READ COMMITTED.
Le niveau d'isolation de la transaction ne peut plus tre modifi aprs l'excution de la premire requte ou instruction de modification de donnes (SELECT, INSERT, DELETE, UPDATE, FETCH ou COPY) d'une transaction. Voir Chapitre 13,
Contrle d'accs simultan pour plus d'informations sur l'isolation et le contrle de concurrence.
La mthode d'accs de la transaction dtermine si elle est en lecture/criture ou en lecture seule. Lecture/criture est la valeur
par dfaut. Quand une transaction est en lecture seule, les commandes SQL suivantes sont interdites : INSERT, UPDATE, DELETE et COPY FROM si la table modifie n'est pas temporaire ; toutes les commandes CREATE, ALTER et DROP ; COMMENT,
GRANT, REVOKE, TRUNCATE ; EXPLAIN ANALYZE et EXECUTE si la commande excute figure parmi celles listes plus
haut. C'est une notion de haut niveau de lecture seule qui n'interdit pas toutes les critures sur disque.
La proprit DEFERRABLE d'une transaction n'a pas d'effet tant que la transaction est aussi SERIALIZABLE et READ ONLY.
Quand toutes ces proprits sont configures pour une transaction, la transaction pourrait bloquer lors de la premire acquisition
de son image de la base, aprs quoi il est possible de fonctionner sans la surcharge normale d'une transaction SERIALIZABLE
et sans risque de contribuer ou d'tre annul par un chec de srialisation. Ce mode convient bien l'excution de longs rapports
ou la cration de sauvegardes.

Notes
Si SET TRANSACTION est excut sans START TRANSACTION ou BEGIN pralable, il est sans effet car la transaction
se termine immdiatement.
Il est possible de se dispenser de SET TRANSACTION en spcifiant le mode_transaction dsir dans BEGIN ou
1124

SET TRANSACTION

START TRANSACTION.
Les modes de transaction par dfaut d'une session peuvent aussi tre configurs en initialisant les paramtres de configuration default_transaction_isolation, default_transaction_read_only et default_transaction_deferrable. (En fait, SET SESSION CHARACTERISTICS est un quivalent verbeux de la configuration de ces variables avec SET.) Les valeurs par dfaut peuvent ainsi tre
initialises dans le fichier de configuration, via ALTER DATABASE, etc. Chapitre 18, Configuration du serveur fournit de plus
amples informations.

Compatibilit
Les deux commandes sont dfinies dans le standard SQL. SERIALIZABLE y est le niveau d'isolation par dfaut de la transaction.
Dans PostgreSQL, la valeur par dfaut est habituellement READ COMMITTED, mais elle peut tre modifie comme cela est
mentionn ci-dessus.
Dans le standard SQL, il existe une autre caractristique de transaction pouvant tre configure avec ces commandes : la taille de
l'aire de diagnostique. Ce concept n'est valable que pour le SQL embarqu et, de fait, n'est pas implant dans le serveur PostgreSQL.
L'option DEFERRABLE de transaction_mode est une extension de PostgreSQL.
Le standard SQL requiert des virgules entre chaque mode_transaction mais, pour des raisons historiques, PostgreSQL autorise l'omission des virgules.

1125

Nom
SHOW affiche la valeur d'un paramtre d'excution

Synopsis
SHOW nom
SHOW ALL

Description
SHOW affiche la configuration courante des paramtres d'excution. Ces variables peuvent tre initialises l'aide de
l'instruction SET, par le fichier de configuration postgresql.conf, par la variable d'environnement PGOPTIONS (lors de
l'utilisation de libpq ou d'une application fonde sur libpq), ou l'aide d'options en ligne de commande lors du dmarrage de
postgres. Voir Chapitre 18, Configuration du serveur pour plus de dtails.

Paramtres
nom
Le nom d'un paramtre d'excution. Les paramtres disponibles sont documents dans Chapitre 18, Configuration du serveur et sur la page de rfrence SET(7). De plus, il existe quelques paramtres qui peuvent tre affichs mais ne sont pas
initialisables :
SERVER_VERSION
Affiche le numro de version du serveur.
SERVER_ENCODING
Affiche l'encodage des caractres ct serveur. ce jour, ce paramtre peut tre affich mais pas initialis parce que
l'encodage est dtermin au moment de la cration de la base de donnes.
LC_COLLATE
Affiche la locale de la base de donnes pour le tri de texte. ce jour, ce paramtre est affichable mais pas initialis parce
que la configuration est dtermine lors de la cration de la base de donnes.
LC_CTYPE
Affiche la locale de la base de donnes pour la classification des caractres. ce jour, ce paramtre peut tre affich mais
pas initialis parce que la configuration est dtermine lors de la cration de la base de donnes.
IS_SUPERUSER
Vrai si le rle courant a des droits de super-utilisateur.
ALL
Affiche les valeurs de tous les paramtres de configuration avec leur description.

Notes
La fonction current_setting affiche les mmes informations. Voir Section 9.24, Fonctions d'administration systme .
De plus, la vue systme pg_settings propose la mme information.

Exemples
Affiche la configuration courante du paramtre datestyle :
SHOW datestyle;
datestyle
----------ISO, MDY
(1 row)
Affiche la configuration courante du paramtre geqo :
SHOW geqo;
geqo
-----on
1126

SHOW

(1 row)
Affiche tous les paramtres :
name
| setting |
description
-------------------------+---------+------------------------------------------------allow_system_table_mods | off
| Allows modifications of the structure of ...
.
.
.
xmloption
| content | Sets whether XML data in implicit parsing ...
zero_damaged_pages
| off
| Continues processing past damaged page headers.
(196 rows)

Compatibilit
La commande SHOW est une extension PostgreSQL.

Voir aussi
SET(7), RESET(7)

1127

Nom
START TRANSACTION dbute un bloc de transaction

Synopsis
START TRANSACTION [ mode_transaction [, ...] ]
o mode_transaction fait
partie de :
ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ
UNCOMMITTED }
READ WRITE | READ ONLY
[ NOT ] DEFERRABLE

Description
Cette commande dbute un nouveau bloc de transaction. Si le niveau d'isolation, le mode lecture/criture ou le mode diffrable
est spcifi, la nouvelle transaction adopte ces caractristiques, comme si SET TRANSACTION(7) avait t excut. Cette
commande est identique la commande BEGIN(7).

Paramtres
Pour obtenir la signification des paramtres de cette instruction, on pourra se rfrer SET TRANSACTION(7).

Compatibilit
Le standard SQL n'impose pas de lancer START TRANSACTION pour commencer un bloc de transaction : toute commande
SQL dbute implicitement un bloc. On peut considrer que PostgreSQL excute implicitement un COMMIT aprs chaque
commande non prcde de START TRANSACTION (ou BEGIN). Ce comportement est d'ailleurs souvent appel
autocommit . D'autres systmes de bases de donnes relationnelles offrent une fonctionnalit de validation automatique.
L'option DEFERRABLE de transaction_mode est une extension de PostgreSQL.
Le standard SQL impose des virgules entre les modes_transaction successifs mais, pour des raisons historiques, PostgreSQL autorise l'omission des virgules.
Voir aussi la section de compatibilit de SET TRANSACTION(7).

Voir aussi
BEGIN(7), COMMIT(7), ROLLBACK(7), SAVEPOINT(7), SET TRANSACTION(7)

1128

Nom
TRUNCATE vide une table ou un ensemble de tables

Synopsis
TRUNCATE [ TABLE ] [ ONLY ] nom [ * ] [, ... ]
[ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]

Description
La commande TRUNCATE supprime rapidement toutes les lignes d'un ensemble de tables. Elle a le mme effet qu'un DELETE non qualifi sur chaque table, mais comme elle ne parcourt par la table, elle est plus rapide. De plus, elle rcupre immdiatement l'espace disque, vitant ainsi une opration VACUUM. Cette commande est particulirement utile pour les tables volumineuses.

Paramtres
nom
Le nom d'une table vider (pouvant tre qualifi par le schma). Si la clause ONLY est prcise avant le nom de la table,
seule cette table est tronque. Dans le cas contraire, la table et toutes ses tables filles (si elle en a) sont tronques. En option,
* peut tre ajout aprs le nom de la table pour indiquer explicitement que les tables filles sont inclues.
RESTART IDENTITY
Redmarre les squences intgres aux colonnes des tables tronques.
CONTINUE IDENTITY
Ne change pas la valeur des squences. C'est la valeur par dfaut.
CASCADE
Vide toutes les tables qui ont des rfrences de cls trangres sur une des tables nommes et sur toute table ajoute au
groupe cause du CASCADE.
RESTRICT
Refuse le vidage si une des tables a des rfrences de cls trangres sur une table qui ne sont pas listes dans la commande.
Cette option est active par dfaut.

Notes
Vous devez avoir le droit TRUNCATE sur la table que vous voulez tronquer.
TRUNCATE ncessite un verrou d'accs exclusif (ACCESS EXCLUSIVE) sur chaque table qu'il traite, ce qui bloque toutes les
autres oprations en parallle sur cette table. Quand RESTART IDENTITY est spcifi, toutes les squences qui doivent tre
rinitialises ont un verrou exclusif. Si un accs concurrent est ncessaire, alors la commande DELETE doit tre utilise.
TRUNCATE ne peut pas tre utilis sur une table rfrence par d'autres tables au travers de cls trangres, sauf si ces tables
sont aussi comprises dans la commande. Dans le cas contraire, la vrification ncessiterait des parcours complets de tables, ce
qui n'est pas le but de la commande TRUNCATE. L'option CASCADE est utilisable pour inclure automatiquement toutes les
tables dpendantes -- faites attention lorsque vous utilisez cette option parce que vous pourriez perdre des donnes que vous auriez souhaitez conserver !
TRUNCATE ne dclenchera aucun trigger ON DELETE qui pourrait exister sur les tables. Par contre, il dclenchera les triggers ON TRUNCATE. Si des triggers ON TRUNCATE sont dfinis sur certaines des tables, alors tous les triggers BEFORE
TRUNCATE sont dclenchs avant que le tronquage n'intervienne, et tous les triggers AFTER TRUNCATE sont dclenchs aprs
la ralisation du dernier tronquage et toutes les squences sont rinitialises. Les triggers se dclencheront dans l'ordre de traitement des tables (tout d'abord celles listes dans la commande, puis celles ajoutes cause des cascades).
Quand RESTART IDENTITY est spcifi, les oprations ALTER SEQUENCE RESTART impliques sont aussi ralises de
faon transactionnelles. Autrement dit, elles seront annules si la transaction n'est pas valide. C'est le contraire du comportement normal de ALTER SEQUENCE RESTART. Faites attention au fait que si des oprations supplmentaires sur les squences impliques est faite avant l'annulation de la transaction, les effets de ces oprations sur les squences seront aussi annuls mais pas les effets sur currval() ; autrement dit, aprs la transaction, currval() continuera reflter la dernire valeur
de la squence obtenue au sein de la transaction choue, mme si la squence elle-mme pourrait ne plus tre en adquation
avec cela. C'est similaire au comportement habituel de currval() aprs une transaction choue.
1129

TRUNCATE

TRUNCATE est compatible avec le systme des transactions. Les donnes seront toujours disponibles si la transaction est annule.

Avertissement
Les oprations sur les squences (ALTER SEQUENCE RESTART) ralises en consquence de l'utilisation de
l'option RESTART IDENTITY sont non transactionnelles et ne seront pas annules en cas d'chec. Pour minimiser
les risques, ces oprations sont ralises seulement aprs que tout le reste du travail de TRUNCATE ne soit termin. Nanmoins, il y a toujours un risque si TRUNCATE est excut dans un bloc de transaction qui est annul ultrieurement. Par exemple, avec :
BEGIN;
TRUNCATE TABLE foo RESTART IDENTITY;
COPY foo FROM ...;
COMMIT;
Si le COPY choue, les donnes de la table seront restaures mais les squences seront laisses avec des valeurs
probablement infrieures celles qu'elles avaient avant, ce qui pourrait amener des checs de cls dupliques ou
d'autres problmes dans les transactions suivantes. Si cela peut devenir un problme, il est bien mieux d'viter
d'utiliser RESTART IDENTITY, et d'accepter que le nouveau contenu de la table aura des numros de squence
bien suprieur l'ancien.

Exemples
Vider les tables grossetable et grandetable :
TRUNCATE grossetable, grandetable;
La mme chose, en rinitialisant les gnrateurs des squences associes :
TRUNCATE bigtable, fattable RESTART IDENTITY;
Vide la table uneautretable, et cascade cela toutes les tables qui rfrencent uneautretable via des contraintes de cls
trangres :
TRUNCATE uneautretable CASCADE;

Compatibilit
Le standard SQL:2008 inclut une commande TRUNCATE avec la syntaxe TRUNCATE TABLE nom_table. Les clauses
CONTINUE IDENTITY/RESTART IDENTITY font aussi partie du standard mais ont une signification lgrement diffrente,
quoique en rapport. Certains des comportements de concurrence de cette commande sont laisss au choix de l'implmentation par
le standard, donc les notes ci-dessus doivent tre comprises et compares avec les autres implmentations si ncessaire.

1130

Nom
UNLISTEN arrte l'coute d'une notification

Synopsis
UNLISTEN { canal | * }

Description
UNLISTEN est utilis pour supprimer un abonnement aux vnements NOTIFY. UNLISTEN annule tout abonnement pour la
session PostgreSQL en cours sur le canal de notification nomm canal. Le caractre gnrique * annule tous les abonnements de la session en cours.
NOTIFY(7) contient une discussion plus complte de l'utilisation de LISTEN et de NOTIFY.

Paramtres
canal
Le nom d'un canal de notification (un identificateur quelconque).
*
Tous les abonnements de cette session sont annuls.

Notes
Il est possible de se dsabonner de quelque chose pour lequel il n'y a pas d'abonnement ; aucun message d'avertissement ou
d'erreur n'est alors retourn.
la fin de chaque session, UNLISTEN * est excut automatiquement.
Une transaction qui a excut UNLISTEN ne peut pas tre prpare pour une validation en deux phases.

Exemples
Pour s'abonner :
LISTEN virtual;
NOTIFY virtual;
Asynchronous notification "virtual" received from server process with PID 8448.
Une fois que UNLISTEN a t excut, les messages NOTIFY suivants sont ignors :
UNLISTEN virtual;
NOTIFY virtual;
-- aucun vnement NOTIFY n'est reu

Compatibilit
Il n'y a pas de commande UNLISTEN dans le standard SQL.

Voir aussi
LISTEN(7), NOTIFY(7)

1131

Nom
UPDATE mettre jour les lignes d'une table

Synopsis
[ WITH [ RECURSIVE ] requte_with [, ...] ]
UPDATE [ ONLY ] table [ * ] [ [ AS ] alias ]
SET { colonne = { expression | DEFAULT } |
( colonne [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]
[ FROM liste_from ]
[ WHERE condition | WHERE CURRENT OF cursor_name ]
[ RETURNING * | expression_sortie [ [ AS ] nom_sortie ] [, ...] ]

Description
UPDATE modifie les valeurs des colonnes spcifies pour toutes les lignes qui satisfont la condition. Seules les colonnes modifier doivent tre mentionnes dans la clause SET ; les autres colonnes conservent leur valeur.
Il existe deux faons de modifier le contenu d'une table partir d'informations contenues dans d'autres tables de la base de donnes : l'aide de sous-requtes ou en spcifiant des tables supplmentaires dans la clause FROM. Le contexte permet de dcider
de la technique la plus approprie.
La clause RETURNING optionnelle fait que UPDATE calcule et renvoie le(s) valeur(s) base(s) sur chaque ligne en cours de
mise jour. Toute expression utilisant les colonnes de la table et/ou les colonnes d'autres tables mentionnes dans FROM peut
tre calcule. La syntaxe de la liste RETURNING est identique celle de la commande SELECT.
L'utilisateur doit possder le droit UPDATE sur la table, ou au moins sur les colonnes listes pour la mise jour. Vous devez
aussi avoir le droit SELECT sur toutes les colonnes dont les valeurs sont lues dans les expressions ou condition.

Paramtres
requte_with
La clause WITH vous permet de spcifier une ou plusieurs sous-requtes qui peuvent tre rfrences par nom dans la requteUPDATE. Voir Section 7.8, Requtes WITH (Common Table Expressions) et SELECT(7) pour les dtails.
table
Le nom de la table mettre jour (ventuellement qualifi du nom du schma). Si ONLY est indiqu avant le nom de la
table, les lignes modifies ne concernent que la table nomme. Si ONLY n'est pas indique, les lignes modifies font partie
de la table nomme et de ses tables filles. En option, * peut tre ajout aprs le nom de la table pour indiquer explicitement
que les tables filles doivent tre inclues.
alias
Un nom de substitution pour la table cible. Quand un alias est fourni, il cache compltement le nom rel de la table. Par
exemple, avec UPDATE foo AS f, le reste de l'instruction UPDATE doit rfrencer la table avec f et non plus foo.
colonne
Le nom d'une colonne dans table. Le nom de la colonne peut tre qualifi avec un nom de sous-champ ou un indice de tableau, si ncessaire. Ne pas inclure le nom de la table dans la spcification d'une colonne cible -- par exemple, UPDATE
tab SET tab.col = 1 est invalide.
expression
Une expression affecter la colonne. L'expression peut utiliser les anciennes valeurs de cette colonne et d'autres colonnes
de la table.
DEFAULT
Rinitialise la colonne sa valeur par dfaut (qui vaut NULL si aucune expression par dfaut ne lui a t affecte).
liste_from
Une liste d'expressions de tables, qui permet aux colonnes des autres tables d'apparatre dans la condition WHERE et dans les
expressions de mise jour. Cela est similaire la liste de tables pouvant tre spcifie dans la section intitule Clause
FROM d'une instruction SELECT. La table cible ne doit pas apparatre dans liste_from, sauf en cas d'auto-jointure
(auquel cas elle doit apparatre avec un alias dans liste_from).
condition
Une expression qui renvoie une valeur de type boolean. Seules les lignes pour lesquelles cette expression renvoie true
1132

UPDATE

sont mises jour.


nom_curseur
Le nom du curseur utiliser dans une condition WHERE CURRENT OF. La ligne mettre jour est la dernire rcupre
partir de ce curseur. Le curseur doit tre une requte sans regroupement sur la table cible de l'UPDATE. Notez que WHERE
CURRENT OF ne peut pas tre spcifi avec une condition boolenne. Voir DECLARE(7) pour plus d'informations sur
l'utilisation des curseurs avec WHERE CURRENT OF.
expression_sortie
Une expression calculer et renvoye par la commande UPDATE aprs chaque mise jour de ligne. L'expression peut utiliser tout nom de colonne de la table ou des tables listes dans le FROM. Indiquez * pour que toutes les colonnes soient renvoyes.
nom_sortie
Un nom utiliser pour une colonne renvoye.

Sorties
En cas de succs, une commande UPDATE renvoie un message de la forme
UPDATE total
total est le nombre de lignes mises jour. S'il vaut 0, c'est qu'aucune ligne ne correspondait condition (ce qui n'est pas
considr comme une erreur).

Notes
Lorsqu'une clause FROM est prcise, la table cible est jointe aux tables mentionnes dans liste_from, et chaque ligne en sortie
de la jointure reprsente une opration de mise jour pour la table cible. Lors de l'utilisation de FROM, il faut s'assurer que la jointure produit au plus une ligne en sortie par ligne modifier. En d'autres termes, une ligne cible ne doit pas tre jointe plus d'une
ligne des autres tables. Le cas chant, seule une ligne de jointure est utilise pour mettre jour la ligne cible, mais il n'est pas
possible de prdire laquelle.
cause de ce manque de dterminisme, il est plus sr de ne rfrencer les autres tables qu' l'intrieur de sous-requtes. Mme si
c'est plus difficile lire et souvent plus lent que l'utilisation d'une jointure.
Si la commande UPDATE contient une clause RETURNING, le rsultat sera similaire celui d'une instruction SELECT contenant les colonnes et les valeurs dfinies dans la liste RETURNING, partir de la liste des lignes mises jour par la commande,
comme la possibilit d'utiliser la clause WITH avec la commande UPDATE.

Exemples
Changer le mot Drame en Dramatique dans la colonne genre de la table films :
UPDATE films SET genre = 'Dramatique' WHERE genre = 'Drame';
Ajuster les entres de temprature et rinitialiser la prcipitation sa valeur par dfaut dans une ligne de la table temps :
UPDATE temps SET temp_basse = temp_basse+1, temp_haute = temp_basse+15, prcp = DEFAULT
WHERE ville = 'San Francisco' AND date = '2005-07-03';
Raliser la mme opration et renvoyer les lignes mises jour :
UPDATE temps SET temp_basse = temp_basse+1, temp_haute = temp_basse+15, prcp = DEFAULT
WHERE ville = 'San Francisco' AND date = '2003-07-03'
RETURNING temp_basse, temp_haute, prcp;
Utiliser une autre syntaxe pour faire la mme mise jour :
UPDATE temps SET (temp_basse, temp_haute, prcp) = (temp_basse+1, temp_basse+15,
DEFAULT)
WHERE ville = 'San Francisco' AND date = '2003-07-03';
Incrmenter le total des ventes de la personne qui gre le compte d'Acme Corporation, l'aide de la clause FROM :
UPDATE employes SET total_ventes = total_ventes + 1 FROM comptes
WHERE compte.nom = 'Acme Corporation'
AND employes.id = compte.vendeur;

1133

UPDATE

Raliser la mme opration en utilisant une sous-requte dans la clause WHERE :


UPDATE employes SET total_ventes = total_ventes + 1 WHERE id =
(SELECT vendeur FROM comptes WHERE nom = 'Acme Corporation');
Tenter d'insrer un nouvel lment dans le stock avec sa quantit. Si l'lment existe dj, mettre jour le total du stock de
l'lment. Les points de sauvegarde sont utiliss pour ne pas avoir annuler l'intgralit de la transaction en cas d'erreur :
BEGIN;
-- autres oprations
SAVEPOINT sp1;
INSERT INTO vins VALUES('Chateau Lafite 2003', '24');
-- A supposer que l'instruction ci-dessus choue du fait d'une violation de cl
-- unique, les commandes suivantes sont excutes :
ROLLBACK TO sp1;
UPDATE vins SET stock = stock + 24 WHERE nomvin = 'Chateau Lafite 2003';
-- continuer avec les autres oprations, et finir
COMMIT;
Modifier la colonne genre de la table films dans la ligne o le curseur c_films est actuellement positionn :
UPDATE films SET genre = 'Dramatic' WHERE CURRENT OF c_films;

Compatibilit
Cette commande est conforme au standard SQL, l'exception des clauses FROM et RETURNING qui sont des extensions PostgreSQL.
D'aprs le standard, la syntaxe de la liste de colonnes permet qu'une liste de colonnes soit affecte une expression de ligne
comme une sous-slection :
UPDATE comptes SET (nom_contact, prenom_contact) =
(SELECT nom, prenom FROM commerciaux
WHERE commerciaux.id = comptes.vendeur_id);
Ceci n'est pas encore implment -- la source doit tre une liste d'expressions indpendantes.
D'autres systmes de bases de donnes offrent l'option FROM dans laquelle la table cible est suppose tre nouveau indique dans
le FROM. PostgreSQL n'interprte pas la clause FROM ainsi. Il est important d'en tenir compte lors du portage d'applications qui
utilisent cette extension.

1134

Nom
VACUUM rcupre l'espace inutilis et, optionnellement, analyse une base

Synopsis
VACUUM
...] )
VACUUM
VACUUM

[
]
[
[

( { FULL | FREEZE | VERBOSE | ANALYZE } [, ...] ) ] [ table [ (colonne [,


]
FULL ] [ FREEZE ] [ VERBOSE ] [ table ]
FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table [ (colonne [, ...] ) ] ]

Description
VACUUM rcupre l'espace de stockage occup par des lignes mortes. Lors des oprations normales de PostgreSQL, les
lignes supprimes ou rendues obsoltes par une mise jour ne sont pas physiquement supprimes de leur table. Elles restent prsentes jusqu' ce qu'un VACUUM soit lanc. C'est pourquoi, il est ncessaire de faire un VACUUM rgulirement, spcialement sur les tables frquemment mises jour.
Sans paramtre, VACUUM traite toutes les tables de la base de donnes courante pour lequel l'utilisateur connect dispose du
droit d'excution du VACUUM. Avec un paramtre, VACUUM ne traite que cette table.
VACUUM ANALYZE fait un VACUUM, puis un ANALYZE sur chaque table slectionne. C'est une combinaison pratique
pour les scripts de maintenance de routine. Voir ANALYZE(7) pour avoir plus de dtails sur ce qu'il traite.
Le VACUUM standard (sans FULL) rcupre simplement l'espace et le rend disponible pour une rutilisation. Cette forme de la
commande peut oprer en parallle avec les oprations normales de lecture et d'criture de la table, car elle n'utilise pas de verrou exclusif. Nanmoins, l'espace rcupr n'est pas renvoy au systme de fichiers dans la plupart des cas ; il est conserv pour
tre rutilis dans la mme table. VACUUM FULL r-crit le contenu complet de la table dans un nouveau fichier sur disque
sans perte d'espace, permettant l'espace inutilis d'tre retourn au systme d'exploitation. Cette forme est bien plus lente et ncessite un verrou exclusif sur chaque table le temps de son traitement.
Quand la liste d'options est entoure de parenthses, les options peuvent tre crites dans n'importe quel ordre. Sans parenthses,
les options doivent tre crit dans l'ordre exact dcrit ci-dessus. La syntaxe avec parenthse a t ajoute ds la version 9.0 de
PostgreSQL ; la syntaxe sans parenthse est maintenant considre comme obsolte.

Paramtres
FULL
Choisit un vacuum full , qui rcupre plus d'espace, mais est beaucoup plus long et prend un verrou exclusif sur la table.
Cette mthode requiert aussi un espace disque supplmentaire car il crit une nouvelle copie de la table et ne supprime
l'ancienne copie qu' la fin de l'opration. Habituellement, cela doit seulement tre utilis quand une quantit importante
d'espace doit tre rcupre de la table.
FREEZE
Choisit un gel agressif des lignes. Indiquer FREEZE est quivalent raliser un VACUUM avec le paramtre vacuum_freeze_min_age configur zro.
VERBOSE
Affiche un rapport dtaill de l'activit de vacuum sur chaque table.
ANALYZE
Met jour les statistiques utilises par l'optimiseur pour dterminer la mthode la plus efficace pour excuter une requte.
table
Le nom (optionnellement qualifi par le nom d'un schma) d'une table traiter par vacuum. Par dfaut, toutes les tables de
la base de donnes courante sont traites.
colonne
Le nom d'une colonne spcifique analyser. Par dfaut, toutes les colonnes. Si une liste de colonnes est spcifie, ANALYZE en est dduit.

Sorties
Lorsque VERBOSE est prcis, VACUUM indique sa progression par des messages indiquant la table en cours de traitement.
Diffrentes statistiques sur les tables sont aussi affiches.
1135

VACUUM

Notes
Pour excuter un VACUUM sur une table, vous devez habituellement tre le propritaire de la table ou un superutilisateur. Nanmoins, les propritaires de la base de donnes sont autoriss excuter VACUUM sur toutes les tables de leurs bases de donnes,
sauf sur les catalogues partags. Cette restriction signifie qu'un vrai VACUUM sur une base complte ne peut se faire que par un
superutilisateur.) VACUUM ignorera toutes les tables pour lesquelles l'utilisateur n'a pas le droit d'excuter un VACUUM.
VACUUM ne peut pas tre excut l'intrieur d'un bloc de transactions.
Pour les tables ayant des index GIN, VACUUM (sous n'importe quelle forme) termine aussi toutes les insertions d'index en attente, en dplaant les entres d'index aux bons endroits dans la structure d'index GIN principale. Voir Section 54.3.1,
Technique GIN de mise jour rapide pour les dtails.
Nous recommandons que les bases de donnes actives de production soient traites par vacuum frquemment (au moins toutes les
nuits), pour supprimer les lignes mortes. Aprs avoir ajout ou supprim un grand nombre de lignes, il peut tre utile de faire un
VACUUM ANALYZE sur la table affecte. Cela met les catalogues systme jour de tous les changements rcents et permet
l'optimiseur de requtes de PostgreSQL de faire de meilleurs choix lors de l'optimisation des requtes.
L'option FULL n'est pas recommande en usage normal, mais elle peut tre utile dans certains cas. Par exemple, si vous avez supprim ou mis jour l'essentiel des lignes d'une table et si vous voulez que la table diminue physiquement sur le disque pour
n'occuper que l'espace rellement ncessaire et pour que les parcours de table soient plus rapides. Gnralement, VACUUM
FULL rduit plus la table qu'un simple VACUUM.
VACUUM peut engendrer une augmentation substantielle du trafic en entres/sorties pouvant causer des performances diminues
pour les autres sessions actives. Du coup, il est quelque fois conseill d'utiliser la fonctionnalit du dlai du vacuum bas sur le
cot. Voir Chapitre 17, Configuration du serveur et mise en place pour des informations supplmentaires.
PostgreSQL inclut un autovacuum qui peut automatiser la maintenance par VACUUM. Pour plus d'informations sur le VACUUM automatique et manuel, voir Section 23.1, Nettoyages rguliers .

Exemples
Ce qui suit est un exemple de lancement de VACUUM sur une table de la base de donnes regression.
regression=# VACUUM (VERBOSE, ANALYZE) onek;
INFO: vacuuming "public.onek"
INFO: index "onek_unique1" now contains 1000 tuples in 14 pages
DETAIL: 3000 index tuples were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.01s/0.08u sec elapsed 0.18 sec.
INFO: index "onek_unique2" now contains 1000 tuples in 16 pages
DETAIL: 3000 index tuples were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.00s/0.07u sec elapsed 0.23 sec.
INFO: index "onek_hundred" now contains 1000 tuples in 13 pages
DETAIL: 3000 index tuples were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.01s/0.08u sec elapsed 0.17 sec.
INFO: index "onek_stringu1" now contains 1000 tuples in 48 pages
DETAIL: 3000 index tuples were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.01s/0.09u sec elapsed 0.59 sec.
INFO: "onek": removed 3000 tuples in 108 pages
DETAIL: CPU 0.01s/0.06u sec elapsed 0.07 sec.
INFO: "onek": found 3000 removable, 1000 nonremovable tuples in 143 pages
DETAIL: 0 dead tuples cannot be removed yet.
There were 0 unused item pointers.
0 pages are entirely empty.
CPU 0.07s/0.39u sec elapsed 1.56 sec.
INFO: analyzing "public.onek"
INFO: "onek": 36 pages, 1000 rows sampled, 1000 estimated total rows
VACUUM

Compatibilit
Il n'y a pas de commande VACUUM dans le standard SQL.

Voir aussi
1136

VACUUM

vacuumdb(1), Section 18.4.3, Report du VACUUM en fonction de son cot , Section 23.1.5, Le dmon auto-vacuum

1137

Nom
VALUES calcule un ensemble de lignes

Synopsis
VALUES ( expression [, ...] ) [, ...]
[ ORDER BY expression_de_tri [ ASC | DESC | USING operateur ] [, ...] ]
[ LIMIT { nombre | ALL } ]
[ OFFSET debut ] [ ROW | ROWS ] ]
[ FETCH { FIRST | NEXT } [ nombre ] { ROW | ROWS } ONLY ]

Description
VALUES calcule une valeur de ligne ou un ensemble de valeurs de lignes spcifies par des expressions. C'est gnralement
utilis pour gnrer une table statique l'intrieur d'une commande plus large mais elle peut aussi tre utilise sparment.
Quand plus d'une ligne est indique, toutes les lignes doivent avoir le mme nombre d'lments. Les types de donnes des colonnes de la table rsultante sont dtermins en combinant les types explicites et les types infrs des expressions apparaissant
dans cette colonne, en utilisant les mmes rgles que pour l'UNION (voir Section 10.5, Constructions UNION, CASE et
constructions relatives ).
l'intrieur de grosses commandes, VALUES est autoris au niveau de la syntaxe partout o la commande SELECT l'est.
Comme la grammaire traite cette commande comme un SELECT, il est possible d'utiliser les clauses ORDER BY, LIMIT (ou
de faon quivalente FETCH FIRST) et OFFSET avec une commande VALUES.

Paramtres
expression
Une constante ou une expression calculer et insrer l'emplacement indiqu dans la table rsultante (ensemble de
lignes). Dans une liste VALUES apparaissant en haut d'une commande INSERT, une expression peut tre remplace
par DEFAULT pour demander l'insertion de la valeur par dfaut de la colonne de destination. DEFAULT ne peut pas tre utilis quand VALUES apparat dans d'autres contextes.
expression_de_tri
Une expression ou un entier indiquant comment trier les lignes de rsultat. Cette expression peut faire rfrence aux colonnes de VALUES en tant que column1, column2, etc. Pour plus de dtails, voir la section intitule Clause ORDER
BY .
operateur
Un oprateur de tri. Pour plus de dtails, voir la section intitule Clause ORDER BY .
nombre
Le nombre maximum de lignes renvoyer. Pour plus de dtails, voir la section intitule Clause LIMIT .
debut
Le nombre de lignes chapper avant de commencer renvoyer des lignes. Pour plus de dtails, la section intitule
Clause LIMIT .

Notes
vitez les listes VALUES comprenant un trs grand nombre de lignes car vous pourriez rencontrer des problmes comme un
manque de mmoire et/ou des performances pauvres. Un VALUES apparaissant dans un INSERT est un cas spcial (parce que
le type des colonnes est trouv partir de la table cible du INSERT et n'a donc pas besoin d'tre devin en parcourant la liste
VALUES), du coup il peut grer des listes plus importantes que dans d'autres contextes.

Exemples
Une simple commande VALUES :
VALUES (1, 'un'), (2, 'deux'), (3, 'trois');
Ceci renverra une table statique comprenant deux colonnes et trois lignes. En fait, c'est quivalent :
1138

VALUES

SELECT 1 AS column1, 'un' AS column2


UNION ALL
SELECT 2, 'deux'
UNION ALL
SELECT 3, 'trois';
Plus gnralement, VALUES est utilis dans une commande SQL plus importante. L'utilisation la plus frquente est dans un INSERT :
INSERT INTO films (code, titee, did, date_prod, genre)
VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drame');
Dans le contexte de la commande INSERT, les entres d'une liste VALUES peuvent tre DEFAULT pour indiquer que la valeur
par dfaut de la colonne cible doit tre utilise :
INSERT INTO films VALUES
('UA502', 'Bananas', 105, DEFAULT, 'Comdie', '82 minutes'),
('T_601', 'Yojimbo', 106, DEFAULT, 'Drame', DEFAULT);
VALUES peut aussi tre utilis l o un sous-SELECT peut tre crit, par exemple dans une clause FROM :
SELECT f.*
FROM films f, (VALUES('MGM', 'Horreur'), ('UA', 'Sci-Fi')) AS t (studio, genre)
WHERE f.studio = t.studio AND f.genre = t.genre;
UPDATE employes SET salaire = salaire * v.augmentation
FROM (VALUES(1, 200000, 1.2), (2, 400000, 1.4)) AS v (no_dep, cible, augmentation)
WHERE employees.no_dep = v.no_dep AND employees.ventes >= v.cible;
Notez qu'une clause AS est requise quand VALUES est utilis dans une clause FROM, par exemple dans un SELECT. Il n'est pas
ncessaire de spcifier les noms de toutes les colonnes dans une clause AS c'est une bonne pratique (les noms des colonnes par dfaut pour VALUES sont column1, column2, etc dans PostgreSQL mais ces noms pourraient tre diffrents dans d'autres
SGBD).
Quand VALUES est utilis dans INSERT, les valeurs sont toutes automatiquement converties dans le type de donnes de la colonne destination correspondante. Quand elle est utilise dans d'autres contextes, il pourrait tre ncessaire de spcifier le bon type
de donnes. Si les entres sont toutes des constantes litrales entre guillemets, convertir la premire est suffisante pour dterminer
le type de toutes :
SELECT * FROM machines
WHERE adresse_ip IN (VALUES('192.168.0.1'::inet), ('192.168.0.10'), ('192.168.1.43'));

Astuce
Pour de simples tests IN, il est prfrable de se baser sur des listes de valeurs pour IN que d'crire une requte VALUES comme indique ci-dessus. La mthode des listes de valeurs simples requiert moins d'criture et est souvent
plus efficace.

Compatibilit
VALUES est conforme au standard SQL. Les clauses LIMIT et OFFSET sont des extensions PostgreSQL ; voir aussi SELECT(7).

Voir aussi
INSERT(7), SELECT(7)

1139

Applications client de PostgreSQL


Cette partie contient les informations de rfrence concernant les applications client et les outils de PostgreSQL. Ces commandes ne sont pas toutes destines l'ensemble des utilisateurs. Certaines ncessitent des privilges spcifiques. La caractristique commune toutes ces applications est leur fonctionnement sur toute machine, indpendemment du serveur sur lequel se
trouve le serveur de base de donnes.

1140

Nom
clusterdb Grouper une base de donnes PostgreSQL

Synopsis
clusterdb [options_connexion...] [[--verbose] | [-v]] [--table | -t table ] [nom_bd]
clusterdb [options_connexion...] [[--verbose] | [-v]] [[--all] | [-a]]

Description
clusterdb est un outil de regroupage de tables au sein d'une base de donnes PostgreSQL. Il trouve les tables prcdemment
groupes et les groupe nouveau sur l'index utilis lors du groupement initial. Les tables qui n'ont jamais t groupes ne sont
pas affectes.
clusterdb est un enrobage de la commande SQL CLUSTER(7). Il n'y a pas de diffrence relle entre le groupage de bases par cet
outil ou par d'autres mthodes d'accs au serveur.

Options
clusterdb accepte les arguments suivants en ligne de commande :
-a, --all
Grouper toutes les bases de donnes.
[-d] nom_bd, [--dbname=]nom_bd
Le nom de la base de donnes grouper. Si ni ce nom, ni l'option -a (ou --all) ne sont prciss, le nom de la base de
donnes est lu partir de la variable d'environnement PGDATABASE. Si cette dernire n'est pas initialise, le nom de
l'utilisateur spcifi pour la connexion est utilis.
-e, --echo
Les commandes engendres par clusterdb et envoyes au serveur sont affiches.
-q, --quiet
Aucun message de progression n'est affich.
-t table, --table=table
Seule la table table est groupe.
-v, --verbose
Affiche des informations dtailles lors du traitement.
-V, --version
Affiche la version de clusterdb puis quitte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de clusterdb, puis quitte
clusterdb accepte aussi les arguments suivants en ligne de commande pour les paramtres de connexion :
-h hte, --host hte
Le nom de la machine hte sur laquelle le serveur fonctionne. Si la valeur commence par une barre oblique (slash), elle est
utilise comme rpertoire du socket de domaine Unix.
-p port, --port=port
Le port TCP ou l'extension du fichier du socket local de domaine Unix sur lequel le serveur attend les connexions.
-U nomutilisateur, --username=nomutilisateur
Le nom de l'utilisateur utilis pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut
tre utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force clusterdb demander un mot de passe avant la connexion une base de donnes.
1141

clusterdb

Cette option n'est jamais obligatoire car clusterdb demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, clusterdb perdra une tentative de connexion pour trouver que le serveur veut un
mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.

Environnement
PGDATABASE, PGHOST, PGPORT, PGUSER
Paramtres de connexion par dfaut.
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
En cas de difficult, voir CLUSTER(7) et psql(1) qui prsentent les problmes et messages d'erreur ventuels. Le serveur de bases
de donnes doit fonctionner sur l'hte cible. De plus, toutes les configurations de connexion par dfaut et variables
d'environnement utilises par la bibliothque client libpq s'appliquent.

Exemples
Grouper la base de donnes test :
$ clusterdb test
Grouper la seule table foo de la base de donnes nomme xyzzy :
$ clusterdb --table foo xyzzy

Voir aussi
CLUSTER(7)

1142

Nom
createdb Crer une nouvelle base de donnes PostgreSQL

Synopsis
createdb [option_connexion...] [option...] [nombase] [description]

Description
createdb cre une nouvelle base de donnes.
Normalement, l'utilisateur de la base de donnes qui excute cette commande devient le propritaire de la nouvelle base de donnes. Nanmoins, un propritaire diffrent peut tre spcifi via l'option -O, sous rserve que l'utilisateur qui lance la commande
ait les droits appropris.
createdb est un enrobage de la commande SQL CREATE DATABASE(7). Il n'y a pas de relle diffrence entre la cration de
bases de donnes par cet outil ou l'aide d'autres mthodes d'accs au serveur.

Options
createdb accepte les arguments suivants en ligne de commande :
nombase
Le nom de la base de donnes crer. Le nom doit tre unique parmi toutes les bases de donnes PostgreSQL de ce
groupe. La valeur par dfaut est le nom de l'utilisateur courant.
description
Le commentaire associer la base de donnes cre.
-D tablespace, --tablespace=tablespace
Le tablespace par dfaut de la base de donnes.
-e, --echo
Les commandes engendres par createdb et envoyes au serveur sont affiches.
-E locale, --encoding=locale
L'encodage des caractres utiliser dans la base de donnes. Les jeux de caractres supports par le serveur PostgreSQL
sont dcrits dans Section 22.3.1, Jeux de caractres supports .
-l locale, --locale=locale
Indique la locale utiliser dans cette base de donnes. C'est quivalent prciser la fois --lc-collate et -lc-ctype.
--lc-collate=locale
Indique le paramtre LC_COLLATE utilis pour cette base de donnes.
--lc-ctype=locale
Indique le paramtre LC_CTYPE utilis pour cette base de donnes.
-O propritaire, --owner=propritaire
Le propritaire de la base de donnes.
-T modle, --template=modle
La base de donnes modle.
-V, --version
Affiche la version de createdb puis quitte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de createdb, puis quitte
Les options -D, -l, -E, -O et -T correspondent aux options de la commande SQL sous-jacente CREATE DATABASE(7),
consulter pour plus d'informations sur ces options.
createdb accepte aussi les arguments suivants en ligne de commande, pour les paramtres de connexion :
-h hte, --host=hte
1143

createdb

Le nom de l'hte sur lequel le serveur est en cours d'excution. Si la valeur commence avec un slash (NDT : barre oblique, /),
elle est utilise comme rpertoire du socket de domaine Unix.
-p port, --port=port
Le port TCP ou l'extension du fichier socket de domaine Unix local sur lequel le serveur attend les connexions.
-U nomutilisateur, --username=nomutilisateur
Le nom de l'utilisateur utilis pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut tre
utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force createdb demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais obligatoire car createdb demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, createdb perdra une tentative de connexion pour trouver que le serveur veut un mot
de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.

Environnement
PGDATABASE
S'il est configur, prcise le nom de la base de donnes crer. Peut-tre surcharg sur la ligne de commande.
PGHOST, PGPORT, PGUSER
Paramtres de connexion par dfaut. PGUSER dtermine aussi le nom de la base de donnes crer si ce dernier n'est pas spcifi sur la ligne de commande ou par PGDATABASE.
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
En cas de difficult, on peut se rfrer CREATE DATABASE(7) et psql(1) qui prsentent les problmes ventuels et les messages d'erreurs. Le serveur de bases de donnes doit tre en cours d'excution sur l'hte cible. De plus, tous les paramtres de
connexion et variables d'environnement par dfaut utiliss par la bibliothque d'interface libpq s'appliquent.

Exemples
Crer la base de donnes demo sur le serveur de bases de donnes par dfaut :
$ createdb demo
Crer la base de donnes demo sur le serveur hberg sur l'hte eden, port 5000, en utilisant l'encodage LATIN1 avec affichage
de la commande engendre :
$ createdb -p 5000 -h eden -E LATIN1 -e demo
CREATE DATABASE "demo" ENCODING 'LATIN1'

Voir aussi
dropdb(1), CREATE DATABASE(7)

1144

Nom
createlang Installer un langage procdural sous PostgreSQL

Synopsis
createlang [options_connexion...] nom_langage [nom_bd]
createlang [options_connexion...] [--list] | [-l] nom_bd

Description
createlang permet d'ajouter un langage de programmation une base de donnes PostgreSQL.
createlang n'est qu'un enrobage de la commande SQL CREATE EXTENSION(7).

Attention
createlang est obsolte et pourrait tre supprim dans une version future de PostgreSQL. L'utilisation directe de
la commande CREATE EXTENSION est recommande la place.

Options
createlang accepte les arguments suivants en ligne de commande :
nom_langage
Le nom du langage de programmation procdurale installer.
[-d] nom_nd, [--dbname=]nom_bd
La base de donnes laquelle ajouter le langage. Par dfaut, celle de mme nom que l'utilisateur systme.
-e, --echo
Les commandes SQL excutes sont affiches.
-l, --list
La liste de langages installs sur la base de donnes cible est affiche.
-V, --version
Affiche la version de createlang puis quitte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de createlang, puis quitte
createlang accepte aussi les arguments suivants en ligne de commande pour les paramtres de connexion :
-h hte, --host=hte
Le nom de l'hte de la machine sur laquelle le serveur fonctionne. Si la valeur commence par un slash (/), elle est utilise
comme rpertoire du socket de domaine Unix.
-p port, --port=port
Le port TCP ou l'extension du fichier du socket local de domaine Unix sur lequel le serveur attend les connexions.
-U nomutilisateur, --username=nomutilisateur
Le nom de l'utilisateur utilis pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut
tre utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force createlang demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais obligatoire car createlang demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, createlang perdra une tentative de connexion pour trouver que le serveur veut
un mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.

1145

createlang

Environnement
PGDATABASE, PGHOST, PGPORT, PGUSER
Paramtres de connexion par dfaut
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
La plupart des messages d'erreur s'expliquent d'eux-mmes. Dans le cas contraire, createlang peut tre lance avec l'option -echo afin d'obtenir les commandes SQL examiner. De plus, tout paramtre de connexion par dfaut et toute variable
d'environnement utilis par la bibliothque libpq s'appliqueront.

Notes
droplang(1) est utilis pour supprimer un langage.

Exemples
Installer le langage pltcl dans la base de donnes template1 :
$ createlang pltcl template1
Installer un langage dans template1 l'installe automatiquement dans les bases de donnes cres ultrieurement.

Voir aussi
droplang(1), CREATE EXTENSION(7), CREATE LANGUAGE(7), Variables d'environnement (Section 31.13, Variables
d'environnement )

1146

Nom
createuser Dfinir un nouveau compte utilisateur PostgreSQL

Synopsis
createuser [option_connexion...] [option...] [nom_utilisateur]

Description
createuser cre un nouvel utilisateur PostgreSQL (ou, plus prcisment, un rle). Seuls les superutilisateurs et les utilisateurs
disposant du droit CREATEROLE peuvent crer de nouveaux utilisateurs. createuser ne peut de ce fait tre invoqu que par un
utilisateur pouvant se connecter en superutilisateur ou en utilisateur ayant le droit CREATEROLE.
Pour crer un superutilisateur, il est impratif de se connecter en superutilisateur ; la simple connexion en utilisateur disposant
du droit CREATEROLE n'est pas suffisante. tre superutilisateur implique la capacit d'outrepasser toutes les vrifications de
droits d'accs la base de donnes ; les privilges de superutilisateur ne peuvent pas tre accords la lgre.
createuser est un enrobage de la commande SQL CREATE ROLE(7). Il n'y a pas de diffrence relle entre la cration
d'utilisateurs par cet outil ou au travers d'autres mthodes d'accs au serveur.

Options
createuser accepte les arguments suivant en ligne de commande
nom_utilisateur
Le nom de l'utilisateur crer. Ce nom doit tre diffrent de tout rle de l'instance courante de PostgreSQL.
-c numro, --connection-limit=numro
Configure le nombre maximum de connexions simultanes pour le nouvel utilisateur. Par dfaut, il n'y a pas de limite.
-d, --createdb
Le nouvel utilisateur est autoris crer des bases de donnes.
-D, --no-createdb
Le nouvel utilisateur n'est pas autoris crer des bases de donnes. Cela correspond au comportement par dfaut.
-e, --echo
Les commandes engendree par createuser et envoyes au serveur sont affiches.
-E, --encrypted
Le mot de passe de l'utilisateur est stock chiffr dans la base. Si cette option n'est pas prcise, la gestion par dfaut des
mots de passe est utilise.
-i, --all
Le nouveau rle hrite automatiquement des droits des rles dont il est membre. Comportement par dfaut.
-I, --no-all
Le nouveau rle n'hrite pas automatiquement des droits des rles dont il est membre.
-l, --login
Le nouvel utilisateur est autoris se connecter (son nom peut tre utilis comme identifiant initial de session). Comportement par dfaut.
-L, --no-login
Le nouvel utilisateur n'est pas autoris se connecter. (Un rle sans droit de connexion est toujours utile pour grer les
droits de la base de donnes.)
-N, --unencrypted
Le mot de passe de l'utilisateur n'est pas stock chiffr. Si cette option n'est pas prcise, la gestion par dfaut des mots de
passe est utilise.
-P, --pwprompt
L'utilisation de cette option impose createuser d'afficher une invite pour la saisie du mot de passe du nouvel utilisateur.
Cela n'a pas d'utilit si l'authentification par mot de passe n'est pas envisage.
-r, --createrole
Le nouvel utilisateur est autoris crer de nouveaux rles (il possde le privilge CREATEROLE).
1147

createuser

-R, --no-createrole
Le nouvel utilisateur n'est pas autoris crer de nouveaux rles. Cela correspond au comportement par dfaut.
-s, --superuser
Le nouvel utilisateur a les privilges superutilisateur.
-S, --no-superuser
Le nouvel utilisateur n'a pas les privilges superutilisateur. Cela correspond au comportement par dfaut.
Le nom, ou toute autre information manquante non fournie sur la ligne de commande, est automatiquement demande.
createuser accepte aussi les arguments suivant en ligne de commande pour les paramtres de connexion :
-h hte, --host=hte
Le nom de l'hte sur lequel le serveur est en cours d'excution. Si la valeur commence avec un slash (/), elle est utilise
comme rpertoire du socket de domaine Unix.
-p port, --port=port
Le port TCP ou l'extension du fichier socket de domaine Unix sur lequel le serveur attend des connexions.
-U nomutilisateur, --username=nomutilisateur
Nom de l'utilisateur utilis pour la connexion (pas celui crer).
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut tre
utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force createuser demander un mot de passe (pour la connexion au serveur, pas pour le mot de passe du nouvel utilisateur).
Cette option n'est jamais obligatoire car createuser demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, createuser perdra une tentative de connexion pour trouver que le serveur veut un
mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.

Environnement
PGHOST, PGPORT, PGUSER
Paramtres de connexion par dfaut
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
En cas de problmes, on peut consulter CREATE ROLE(7) et psql(1) qui fournissent des informations sur les problmes potentiels et les messages d'erreur. Le serveur de la base de donnes doit tre en cours d'excution sur l'hte cible. De plus, tout paramtrage de connexion par dfaut et toute variable d'environnement utilise par le client de la bibliothque libpq s'applique.

Exemples
Crer un utilisateur joe sur le serveur de bases de donnes par dfaut :
$ createuser joe
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n
Crer le mme utilisateur, joe, sur le serveur eden, port 5000, sans interaction, avec affichage de la commande sous-jacente :
$ createuser -h eden -p 5000 -S -D -R -e joe
CREATE ROLE joe NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;
Crer l'utilisateur joe, superutilisateur, et lui affecter immdiatement un mot de passe :
$ createuser -P -s -e joe
Enter password for new role: xyzzy
1148

createuser

Enter it again: xyzzy


CREATE ROLE joe PASSWORD 'xyzzy' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;
CREATE ROLE
Dans l'exemple ci-dessus, le nouveau mot de passe n'est pas affich lorsqu'il est saisi. Il ne l'est ici que pour plus de claret.
Comme vous le voyez, le mot de passe est chiffr avant d'tre envoy au client. Si l'option --unencrypted est utilis, le mot
de passe apparatra dans la commande affiche (et aussi dans les journaux applicatifs et certainement ailleurs), donc vous ne devez pas utiliser -e dans ce cas, surtout si quelqu'un d'autre voit votre cran ce moment.

Voir aussi
dropuser(1), CREATE ROLE(7)

1149

Nom
dropdb Supprimer une base de donnes PostgreSQL

Synopsis
dropdb [option_connexion...] [option...] nom_bd

Description
dropdb dtruit une base de donnes PostgreSQL. L'utilisateur qui excute cette commande doit tre superutilisateur ou le propritaire de la base de donnes.
dropdb est un enrobage de la commande SQL DROP DATABASE(7). Il n'y a aucune diffrence relle entre la suppression de
bases de donnes avec cet outil et celles qui utilisent d'autres mthodes d'accs au serveur.

Options
dropdb accepte les arguments suivants en ligne de commande :
nom_bd
Le nom de la base de donnes supprimer.
-e, --echo
Les commandes engendres et envoyes au serveur par dropdb sont affiches.
-i, --interactive
Une confirmation pralable toute destruction est exige.
-V, --version
Affiche la version de dropdb puis quitte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de dropdb, puis quitte
dropdb accepte aussi les arguments suivants en ligne de commande pour les paramtres de connexion :
-h hte, --host=hte
Le nom d'hte de la machine sur laquelle le serveur fonctionne. Si la valeur dbute par une barre oblique (/ ou slash), elle
est utilise comme rpertoire de la socket de domaine Unix.
-p port, --port=port
Le port TCP ou l'extension du fichier de la socket locale de domaine Unix sur laquelle le serveur attend les connexions.
-U nomutilisateur, --username=nomutilisateur
Le nom de l'utilisateur utilis pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut
tre utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force dropdb demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais obligatoire car dropdb demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, dropdb perdra une tentative de connexion pour trouver que le serveur veut un
mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.

Environnement
PGHOST, PGPORT, PGUSER
Paramtres de connexion par dfaut
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la biblio1150

dropdb

thque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
En cas de difficults, il peut tre utile de consulter DROP DATABASE(7) et psql(1), sections prsentant les problmes ventuels
et les messages d'erreur.
Le serveur de base de donnes doit fonctionner sur le serveur cible. Les paramtres de connexion ventuels et les variables
d'environnement utiliss par la bibliothque cliente libpq s'appliquent.

Exemples
Dtruire la base de donnes demo sur le serveur de bases de donnes par dfaut :
$ dropdb demo
Dtruire la base de donnes demo en utilisant le serveur hberg sur l'hte eden, qui coute sur le port 5000, avec demande de
confirmation et affichage de la commande sous-jacente :
$ dropdb -p 5000 -h eden -i -e demo
Database "demo" will be permanently deleted.
Are you sure? (y/n) y
DROP DATABASE demo;

Voir aussi
createdb(1), DROP DATABASE(7)

1151

Nom
droplang Supprimer un langage procdural

Synopsis
droplang [option_connexion...] nom_langage [nom_bd]
droplang [option_connexion...] [--list] | [-l] nom_db

Description
droplang est un outil permettant de supprimer un langage procdural existant partir d'une base de donnes PostgreSQL.
droplang est un script appelant directement la commande SQL DROP EXTENSION(7).

Attention
droplang est obsolte et pourrait tre supprim dans une version future de PostgreSQL. L'utilisation directe de
la commande DROP EXTENSION est recommande la place.

Options
droplang accepte les arguments en ligne de commande :
nom_langage
Le nom du langage de programmation supprimer.
[-d] nom_bd, [--dbname=] nom_bd
La base de donnes qui contient le langage supprimer. Par dfaut, le nom de la base est quivalent celui du nom de
l'utilisateur systme qui lance la commande.
-e, --echo
Les commandes SQL excutes sont affiches.
-l, --list
La liste des langages installs sur la base de donnes cible est affich.
-V, --version
Affiche la version de droplang puis quitte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de droplang, puis quitte
droplang accepte aussi les arguments suivants sur la ligne de commande pour les paramtres de connexion :
-h hte, --host=hte
Le nom d'hte de la machine sur lequel le serveur fonctionne. Si la valeur commence par une barre oblique (/ ou slash), elle
est utilise comme rpertoire du socket de domaine Unix.
-p port, --port=port
Le port TCP ou l'extension du fichier de la socket de domaine Unix sur lequel le serveur coute les connexions.
-U nomutilisateur, --username=nomutilisateur
Le nom de l'utilisateur utilis pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut
tre utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force droplang demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais obligatoire car droplang demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, droplang perdra une tentative de connexion pour trouver que le serveur veut un
1152

droplang

mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.

Environnement
PGDATABASE, PGHOST, PGPORT, PGUSER
Paramtres de connexion par dfaut
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
La plupart des messages d'erreurs sont explicites. Dans le cas contraire, on peut utiliser droplang avec l'option --echo et regarder
la commande SQL correspondante pour obtenir plus de dtails. De plus, tout paramtre de connexion par dfaut et toute variable
d'environnement utilis par la bibliothque libpq s'appliqueront.

Notes
createlang(1) est utilis pour ajouter un langage.

Exemples
Supprimer le langage pltcl :
$ droplang pltcl nomdb

Voir aussi
createlang(1), DROP EXTENSION(7), DROP LANGUAGE(7)

1153

Nom
dropuser Supprimer un compte utilisateur PostgreSQL

Synopsis
dropuser [option_connexion...] [option...] [nomutilisateur]

Description
dropuser supprime un utilisateur. Seuls les superutilisateurs et les utilisateurs disposant du droit CREATEROLE peuvent supprimer des utilisateurs (seul un superutilisateur peut supprimer un superutilisateur).
dropuser est un enrobage de la commande SQL DROP ROLE(7). Il n'y a pas de diffrence relle entre la suppression des utilisateurs l'aide de cet outil ou l'aide d'autres mthodes d'accs au serveur.

Options
dropuser accepte les arguments suivants en ligne de commande :
nomutilisateur
Le nom de l'utilisateur PostgreSQL supprimer. Un nom est demand s'il n'est pas fourni sur la ligne de commande.
-e, --echo
Les commandes engendres et envoyes au serveur par dropuser sont affiches.
-i, --interactive
Une confirmation est demande avant la suppression effective de l'utilisateur.
-V, --version
Affiche la version de dropuser puis quitte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de dropuser, puis quitte
dropuser accepte aussi les arguments suivants en ligne de commande pour les paramtres de connexion :
-h hte, --host=hte
Le nom d'hte de la machine sur lequel le serveur fonctionne. Si la valeur commence par une barre oblique (/ ou slash), elle
est utilise comme rpertoire du socket de domaine Unix.
-p port, --port=port
Le port TCP ou l'extension du fichier du socket local de domaine Unix sur lequel le serveur attend les connexions.
-U nomutilisateur, --username=nomutilisateur
Le nom de l'utilisateur utilis pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut
tre utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force dropuser demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais obligatoire car dropuser demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, dropuser perdra une tentative de connexion pour trouver que le serveur veut un
mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.

Environnement
PGDATABASE, PGHOST, PGPORT, PGUSER
Paramtres de connexion par dfaut.
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la biblio1154

dropuser

thque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
En cas de difficults, il peut tre utile de consulter DROP ROLE(7) et psql(1), sections prsentant les problmes ventuels et les
messages d'erreur.
Le serveur de base de donnes doit fonctionner sur le serveur cible. Les paramtres de connexion ventuels et les variables
d'environnement utiliss par la bibliothque cliente libpq s'appliquent.

Exemples
Supprimer l'utilisateur joe de la base de donnes par dfaut :
$ dropuser joe
Supprimer l'utilisateur joe sur le serveur hberg sur l'hte eden, qui coute sur le port 5000, avec demande de confirmation et
affichage de la commande sous-jacente :
$ dropuser -p 5000 -h eden -i -e joe
Role "joe" will be permanently removed.
Are you sure? (y/n) y
DROP ROLE joe;

Voir aussi
createuser(1), DROP ROLE(7)

1155

Nom
ecpg Prprocesseur C pour le SQL embarqu

Synopsis
ecpg [option...] fichier...

Description
ecpg est le prprocesseur du SQL embarqu pour les programmes crits en C. Il convertit des programmes crits en C contenant
des instructions SQL embarqu en code C normal. Pour se faire, les appels au SQL sont remplacs par des appels spciaux de
fonctions. Les fichiers en sortie peuvent tre traits par n'importe quel compilateur C.
ecpg convertit chaque fichier en entre, donn sur la ligne de commande, en un fichier C correspondant. Les fichiers en entre
ont de prfrence l'extension .pgc, auquel cas l'extension est remplace par .c pour former le nom du fichier de sortie. Si
l'extension du fichier en entre n'est pas .pgc, alors le nom de fichier en sortie est obtenu en ajoutant .c au nom complet du fichier. Le nom de fichier en sortie peut aussi tre surcharg en utilisant l'option -o.
Cette page de rfrence ne dcrit pas le langage SQL embarqu. Voir Chapitre 33, ECPG SQL embarqu en C pour plus
d'informations sur ce thme.

Options
ecpg accepte les arguments suivants en ligne de commande :
-c
Engendre automatiquement du code C partir de code SQL. Actuellement, cela fonctionne pour EXEC SQL TYPE.
-C mode
Initialise un mode de compatibilit. mode peut tre INFORMIX ou INFORMIX_SE.
-D symbol
Dfinit un symbole du prprocesseur C.
-i
Les fichiers d'en-tte du systme sont galement analyss.
-I rpertoire
Spcifie un chemin d'inclusion supplmentaire, utilis pour trouver les fichiers inclus via EXEC SQL INCLUDE. Par dfaut, il s'agit de . (rpertoire courant), /usr/local/include, du rpertoire de fichiers enttes de PostgreSQL dfini
la compilation (par dfaut : /usr/local/pgsql/include), puis de /usr/include, dans cet ordre.
-o nom_fichier
Indique le nom du fichier de sortie, nom_fichier, utilis par ecpg.
-r option
Slectionne un comportement en excution. option peut avoir une des valeurs suivantes :
no_indicator
Ne pas utiliser d'indicateurs mais utiliser la place des valeurs spciales pour reprsenter les valeurs NULL. Historiquement, certaines bases de donnes utilisent cette approche.
prepare
Prparer toutes les instructions avant de les utiliser. Libecpg conservera un cache d'instructions prpares et rutilisera une
instruction si elle est de nouveau excute. Si le cache est plein, libecpg librera l'instruction la moins utilise.
questionmarks
Autoriser les points d'interrogation comme marqueur pour des raisons de compatibilit. C'tait la valeur par dfaut il y a
longtemps.
-t
Active la validation automatique (autocommit) des transactions. Dans ce mode, chaque commande SQL est valide automatiquement, sauf si elle est l'intrieur d'un bloc de transaction explicite. Dans le mode par dfaut, les commandes ne sont
valides qu' l'excution de EXEC SQL COMMIT.
-v
Affiche des informations supplmentaires dont la version et le chemin des enttes.
1156

ecpg

--version
Affiche la version de ecpg et quitte.
--help
Affiche l'aide sur les arguments en ligne de commande de ecpg et quitte.

Notes
Lors de la compilation de fichiers C prtraits, le compilateur a besoin de trouver les fichiers d'en-tte ECPG dans le rpertoire des
enttes de PostgreSQL. De ce fait, il faut gnralement utiliser l'option -I lors de l'appel du compilateur (c'est--dire I/usr/local/pgsql/include).
Les programmes C qui utilisent du SQL embarqu doivent tre lis avec la bibliothque libecpg. Cela peut peut tre effectu,
par exemple, en utilisant les options de l'diteur de liens -L/usr/local/pgsql/lib -lecpg.
La valeur relle des rpertoires, fonction de l'installation, peut tre obtenue par l'utilisation de la commande pg_config(1).

Exemples
Soit un fichier source C contenant du SQL embarqu nomm prog1.pgc. Il peut tre transform en programme excutable
l'aide des commandes suivantes :
ecpg prog1.pgc
cc -I/usr/local/pgsql/include -c prog1.c
cc -o prog1 prog1.o -L/usr/local/pgsql/lib -lecpg

1157

Nom
pg_basebackup ralise une sauvegarde de base d'une instance PostgreSQL

Synopsis
pg_basebackup [option...]

Description
pg_basebackup est utilis pour prendre une sauvegarde de base d'une instance PostgreSQL en cours d'excution. Elles se font
sans affecter les autres clients du serveur de bases de donnes et peuvent tre utilises pour une restauration jusqu' un certain
point dans le temps (voir Section 24.3, Archivage continu et rcupration d'un instantan (PITR) ) ou comme le point de dpart d'un serveur en standby, par exemple avec la rplication en flux (voir Section 25.2, Serveurs de Standby par transfert de
journaux ).
pg_basebackup fait une copie binaire des fichiers de l'instance en s'assurant que le systme est mis automatiquement en mode
sauvegarde puis en est sorti. Les sauvegardes sont toujours faites sur l'ensemble de l'instance, il n'est donc pas possible de sauvegarder une base individuelle ou des objets d'une base. Pour les sauvegardes de ce type, un outil comme pg_dump(1) doit tre utilis.
La sauvegarde se fait via une connexion PostgreSQL standard et utilise le protocole de rplication. La connexion doit se faire
avec un utilisateur dot de l'attribut REPLICATION (voir Section 20.2, Attributs des rles ), et l'utilisateur doit avoir les
droits explicites de connexion dans pg_hba.conf. Le serveur doit aussi tre configur avec un max_wal_senders suffisamment lev pour laisser au moins une connexion disponible pour la sauvegarde.
Plusieurs commandes pg_basebackup peuvent tre excutes en mme temps mais il est prfrable pour les performances de
n'en faire qu'une seule et de copier le rsultat.

Options
Les options suivantes en ligne de commande contrlent l'emplacement et le format de la sortie.
-D rpertoire, --pgdata=rpertoire
Rpertoire o sera crit la sortie.
Quand la sauvegarde est en mode tar et que le rpertoire est spcifi avec un tiret (-), le fichier tar sera crit sur stdout.
Ce paramtre est requis.
-F format, --format=format
Slectionne le format de sortie. format peut valoir :
p, plain
crit des fichiers standards, avec le mme emplacement que le rpertoire des donnes et les tablespaces d'origine. Quand
l'instance n'a pas de tablespace supplmentaire, toute la base de donnes sera place dans le rpertoire cible. Si l'instance
contient des tablespaces supplmentaires, le rpertoire principal des donnes sera plac dans le rpertoire cible mais les
autres tablespaces seront placs dans le mme chemin absolu que celui d'origine.
C'est le format par dfaut.
t, tar
crit des fichiers tar dans le rpertoire cible. Le rpertoire principal de donnes sera crit sous la forme d'un fichier nomm
base.tar et tous les autres tablespaces seront nomms d'aprs l'OID du tablespace.
Si la valeur - (tiret) est indique comme rpertoire cible, le contenu du tar sera crit sur la sortie standard, ce qui est intressant pour une compression directe via un tube. Ceci est seulement possible si l'instance n'a pas de tablespace supplmentaire.
-x, --xlog
Inclut les journaux de transactions requis (fichiers WAL) dans la sauvegarde. Cela incluera toutes les transactions intervenues pendant la sauvegarde. Si cette option est prcise, il est possible de lancer un postmaster directement sur le rpertoire
extrait sans avoir besoin de consulter les archives des journaux, ce qui rend la sauvegarde compltement autonome.

1158

pg_basebackup

Note
Les journaux de transactions sont rcuprs la fin de la sauvegarde. Du coup, il est ncessaire que le paramtre wal_keep_segments soit suffisamment lev pour que les journaux ne soient pas supprims avant la fin
de la sauvegarde. Si le journal a t renomm avant qu'il ne soit transfr, la sauvegarde chouera et sera inutilisable.
-z, --gzip
Active la compression gzip de l'archive tar en sortie, avec le niveau de compression par dfaut. La compression est disponible
seulement lors de l'utilisation du format tar.
-Z niveau, --compress=niveau
Active la compression gzip du fichier tar en sortie, et prcise le niveau de compression (de 1 9, 9 correspondant la
meilleure compression). La compression est seulement disponible lors de l'utilisation du format tar.
Les options suivantes en ligne de commande contrlent la gnration de la sauvegarde et l'excution du programme.
-c fast|spread, --checkpoint=fast|spread
Configure le mode du checkpoint rapide (fast) ou en attente (spread, la valeur par dfaut).
-l label, --label=label
Configure le label de la sauvegarde. Sans indication, une valeur par dfaut, pg_basebackup base backup sera utilise.
-P, --progress
Active l'indicateur de progression. Activer cette option donnera un rapport de progression approximatif lors de la sauvegarde.
Comme la base de donnes peut changer pendant la sauvegarde, ceci est seulement une approximation et pourrait ne pas se
terminer exactement 100%. En particulier, lorsque les journaux de transactions sont inclus dans la sauvegarde, la quantit
totale de donnes ne peut pas tre estime l'avance et, dans ce cas, la taille cible estime va augmenter quand il dpasse
l'estimation totale sans les journaux de transactions.
Quand cette option est active, le serveur commencera par calculer la taille totale des bases de donnes, puis enverra leur
contenu. Du coup, cela peut rendre la sauvegarde plus longue, en particulier plus longue avant l'envoi de la premire donne.
-v, --verbose
Active le mode verbeux, qui affichera les tapes supplmentaires pendant le dmarrage et l'arrt ainsi que le nom de fichier
exact qui est en cours de traitement si le rapport de progression est aussi activ.
Les options suivantes en ligne de commande contrlent les paramtres de connexion la base de donnes.
-h hte, --host=hte
Indique le nom d'hte de la machine sur laquelle le serveur de bases de donnes est excut. Si la valeur commence par une
barre oblique (/), elle est utilise comme rpertoire pour le socket de domaine Unix. La valeur par dfaut est fournie par la variable d'environnement PGHOST, si elle est initialise. Dans le cas contraire, une connexion sur la socket de domaine Unix est
tente.
-p port, --port=port
Indique le port TCP ou l'extension du fichier local de socket de domaine Unix sur lequel le serveur coute les connexions. La
valeur par dfaut est fournie par la variable d'environnement PGPORT, si elle est initialise. Dans le cas contraire, il s'agit de
la valeur fournie la compilation.
-U nomutilisateur, --username=nomutilisateur
Le nom d'utilisateur utilis pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut tre
utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force pg_basebackup demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais ncessaire car pg_basebackup demande automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, pg_basebackup perd une tentative de connexion pour tester si le serveur demande
un mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.
D'autres paramtres, moins utiliss, sont aussi disponibles :
1159

pg_basebackup

-V, --version
Affiche la version de pg_basebackup puis quitte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de pg_basebackup, puis quitte

Environnement
Cet outil, comme la plupart des outils PostgreSQL, utilise les variables d'environnement supportes par libpq (voir Section 31.13, Variables d'environnement ).

Notes
La sauvegarde incluera tous les fichiers du rpertoire de donnes et des tablespaces, ceci incluant les fichiers de configuration et
tout fichier supplmentaire plac dans le rpertoire par d'autres personnes. Seuls les fichiers et rpertoires standards sont autoriss
dans le rpertoire des donnes, pas de liens symboliques ou de fichiers priphriques spciaux.
De la faon dont PostgreSQL gre les tablespaces, le chemin de chaque tablespace supplmentaire doit tre identique quand une
sauvegarde est restaure. Nanmoins, le rpertoire principal de donnes est relocalisable.

Exemples
Pour crer une sauvegarde de base du serveur mon_sgbd et l'enregistrer dans le rpertoire local /usr/local/pgsql/data :
$ pg_basebackup -h mon_sgbd -D /usr/local/pgsql/data
Pour crer une sauvegarde du serveur local avec un fichier tar compress pour chaque tablespace, et stocker le tout dans le rpertoire sauvegarde, tout en affichant la progression pendant l'excution :
$ pg_basebackup -D sauvegarde -Ft -z -P
Pour crer une sauvegarde d'une base de donnes locale avec un seul tablespace et la compresser avec bzip2 :
$ pg_basebackup -D - -Ft | bzip2 > backup.tar.bz2
(cette commande chouera s'il existe plusieurs tablespaces pour cette instance)

Voir aussi
pg_dump(1)

1160

Nom
pg_config rcuprer des informations sur la version installe de PostgreSQL

Synopsis
pg_config [option...]

Description
L'outil pg_config affiche les paramtres de configuration de la version installe de PostgreSQL. Il peut, par exemple, d'tre
utilis par des paquets logiciels qui souhaitent s'interfacer avec PostgreSQL pour faciliter la recherche des fichiers d'enttes
requis et des bibliothques.

Options
Pour utiliser pg_config, une ou plusieurs des options suivantes doivent tre fournies :
--bindir
Afficher l'emplacement des excutables utilisateur. Par exemple, pour trouver le programme psql. C'est aussi normalement
l'emplacement du programme pg_config.
--docdir
Afficher l'emplacement des fichiers de documentation.
--htmldir
Affiche l'emplacement des fichiers de documentation HTML.
--includedir
Afficher l'emplacement des fichiers d'enttes C des interfaces clientes.
--pkgincludedir
Afficher l'emplacement des autres fichiers d'entte C.
--includedir-server
Afficher l'emplacement des fichiers d'enttes C pour la programmation du serveur.
--libdir
Afficher l'emplacement des bibliothques.
--pkglibdir
Afficher l'emplacement des modules chargeables dynamiquement ou celui que le serveur peut parcourir pour les trouver.
(D'autres fichiers de donnes dpendant de l'architecture peuvent aussi tre installs dans ce rpertoire.)
--localedir
Afficher l'emplacement des fichiers de support de la locale (c'est une chane vide si le support de la locale n'a pas t configur lors de la construction de PostgreSQL).
--mandir
Afficher l'emplacement des pages de manuel.
--sharedir
Afficher l'emplacement des fichiers de support qui ne dpendent pas de l'architecture.
--sysconfdir
Afficher l'emplacement des fichiers de configuration du systme.
--pgxs
Afficher l'emplacement des fichiers makefile d'extensions.
--configure
Afficher les options passes au script configure lors de la configuration de PostgreSQL en vue de sa construction. Cela peut tre utilis pour reproduire une configuration identique ou pour trouver les options avec lesquelles un paquet binaire
a t construit. (Nanmoins, les paquets binaires contiennent souvent des correctifs personnaliss par le vendeur.) Voir aussi
les exemples ci-dessous.
--cc
Afficher la valeur de la macro CC utilise lors de la construction de PostgreSQL. Cela affiche le compilateur C utilis.
1161

pg_config

--cppflags
Afficher la valeur de la macro CPPFLAGS utilise lors de la construction de PostgreSQL. Cela affiche les options du compilateur C ncessaires pour l'excution du prprocesseur (typiquement, les options -I).
--cflags
Afficher la valeur de la macro CFLAGS utilise lors de la construction de PostgreSQL. Cela affiche les options du compilateur C.
--cflags_sl
Afficher la valeur de la macro CFLAGS_SL utilise lors de la construction de PostgreSQL. Cela affiche les options supplmentaires du compilateur C utilises pour construire les bibliothques partages.
--ldflags
Afficher la valeur de la macro LDFLAGS utilise lors de la construction de PostgreSQL. Cela affiche les options de
l'diteur de liens.
--ldflags_ex
Afficher la valeur de la variable LDFLAGS_EX utilise lors de la construction de PostgreSQL. Cela affiche les options de
l'diteur de liens uniquement pour la construction des excutables.
--ldflags_sl
Afficher la valeur de la macro LDFLAGS_SL utilise lors de la construction de PostgreSQL. Cela affiche les options de
l'diteur de liens utilises pour construire seulement les bibliothques partages.
--libs
Afficher la valeur de la macro LIBS utilise lors de la construction de PostgreSQL. Elle contient habituellement les options
-l pour les bibliothques externes auxquelles PostgreSQL est li.
--version
Afficher la version de PostgreSQL.
Si plusieurs options sont donnes, l'information est affiche dans cet ordre, un lment par ligne. Si aucune option n'est donne,
toutes les informations disponibles sont affiches avec des tiquettes.

Notes
L'option --includedir-server est apparue dans PostgreSQL 7.2. Dans les versions prcdentes, les fichiers d'enttes du
serveur taient installs au mme endroit que les enttes client, qui pouvaient tre rcuprs avec l'option --includedir. Pour
que le paquet gre les deux cas, la nouvelle option est tente en premier, et le code de sortie est test pour savoir si la commande a
russi.
Les options --docdir, --pkgincludedir, --localedir, --mandir, --sharedir, --sysconfdir, --cc, -cppflags, --cflags, --cflags_sl, --ldflags, --ldflags_sl et --libs sont apparues avec PostgreSQL 8.1.
L'option --htmldir n'est disponible qu' partir de PostgreSQL 8.4. The option --ldflags_ex was added in
PostgreSQL 9.0.
Dans les versions antrieures PostgreSQL 7.1, avant que pg_config ne soit disponible, il n'existait aucune mthode de rcupration de ces informations de configuration.

Exemple
Reproduire la configuration de construction de l'installation actuelle de PostgreSQL :
eval ./configure `pg_config --configure`
La sortie de pg_config --configure contient les guillemets du shell de sorte que les arguments contenant des espaces
soient reprsents correctement. Du coup, il est ncessaire d'utiliser eval pour obtenir des rsultats corrects.

1162

Nom
pg_dump sauvegarder une base de donnes PostgreSQL dans un script ou tout autre fichier d'archive

Synopsis
pg_dump [option_connexion...] [option...] [nom_base]

Description
pg_dump est un outil de sauvegarde d'une base de donnes PostgreSQL. Les sauvegardes ralises sont cohrentes, mme
lors d'accs concurrents la base de donnes. pg_dump ne bloque pas l'accs des autres utilisateurs (ni en lecture ni en criture).
Les extractions peuvent tre ralises sous la forme de scripts ou de fichiers d'archive. Les scripts sont au format texte et
contiennent les commandes SQL ncessaires la reconstruction de la base de donnes dans l'tat o elle tait au moment de la
sauvegarde. La restauration s'effectue en chargeant ces scrits avec psql(1). Ces scripts permettent de reconstruire la base de donnes sur d'autres machines et d'autres architectures, et mme, au prix de quelques modifications, sur d'autres bases de donnes
SQL.
La reconstruction de la base de donnes partir d'autres formats de fichiers archive est obtenue avec pg_restore(1). pg_restore
permet, partir de ces formats, de slectionner les lments restaurer, voire de les rordonner avant restauration. Les fichiers
d'archive sont conus pour tre portables au travers d'architectures diffrentes.
Utilis avec un des formats de fichier d'archive et combin avec pg_restore, pg_dump fournit un mcanisme d'archivage et de
transfert flexible. pg_dump peut tre utilis pour sauvegarder une base de donnes dans son intgralit ; pg_restore peut alors
tre utilis pour examiner l'archive et/ou slectionner les parties de la base de donnes restaurer. Le format de fichier de sortie
le plus flexible est le format personnalis (custom en anglais, -Fc). Compress par dfaut, il permet de slectionner et rordonner les lments archivs.
Lors de l'excution de pg_dump, il est utile de surveiller les messages d'avertissement (affichs sur la sortie erreur standard), en
particulier en ce qui concerne les limitations indiques ci-dessous.

Options
Les options suivantes de la ligne de commande contrlent le contenu et le format de la sortie.
nom_base
Le nom de la base de donnes sauvegarder. En l'absence de prcision, la variable d'environnement PGDATABASE est utilise. Si cette variable n'est pas positionne, le nom de l'utilisateur de la connexion est utilis.
-a, --data-only
Seules les donnes sont sauvegardes, pas le schma (dfinition des donnes).
Cette option n'a d'intrt que pour le format texte. Pour les formats archive, l'option peut tre prcise lors de l'appel de
pg_restore.
-b, --blobs
Inclut les objets larges dans la sauvegarde. C'est le comportement par dfaut, sauf si une des options suivantes est ajoute :
--schema, --table ou --schema-only. L'option -b n'est utile que pour ajouter les objets larges aux sauvegardes
slectives.
-c, --clean
Les commandes de nettoyage (suppression) des objets de la base sont crites avant les commandes de cration. (La restauration peut gnrer des erreurs sans gravit.)
Cette option n'a d'intrt que pour le format texte. Pour les formats archive, l'option est prcise l'appel de pg_restore.
-C, --create
La sortie dbute par une commande de cration de la base de donnes et de connexion cette base. Peu importe, dans ce
cas, la base de donnes laquelle la connexion est faite avant la restauration.
Cette option n'a d'intrt que pour le format texte. Pour les formats archive, l'option est prcise l'appel de pg_restore.
-f file, --file=file
La sortie est redirige vers le fichier indiqu. Ce paramtre peut tre omis pour les sorties en mode fichier, dans ce cas la
sortie standard sera utilise. Par contre, il doit tre fourni pour le format 'directory' (rpertoire), o il spcifie le rpertoire
cible plutt qu'un fichier. Dans ce cas, le rpertoire est cr par pg_dump et ne doit pas exister auparavant.
1163

pg_dump

-E codage, --encoding=codage
La sauvegarde est cre dans l'encodage indiqu. Par dfaut, la sauvegarde utilise celui de la base de donnes. Le mme rsultat peut tre obtenu en positionnant la variable d'environnement PGCLIENTENCODING avec le codage dsir pour la sauvegarde.
-F format, --format=format
Le format de la sortie. format correspond un des lments suivants :
p
fichier de scripts SQL en texte simple (dfaut) ;
c
archive personnalise utilisable par pg_restore. Avec le format de sortie rpertoire, c'est le format le plus souple, car il permet
la slection manuelle et le rordonnancement des objets archivs au moment de la restauration. Ce format est aussi compress
par dfaut. default.
d, directory
Produire une archive au format rpertoire utilisable en entre de de pg_restore. Cela crera un rpertoire avec un fichier pour
chaque table et blob export, ainsi qu'un fichier appel Table of Contents (Table des matires) dcrivant les objets exports
dans un format machine que pg_restore peut lire. Une archive au format rpertoire peut tre manipule avec des outils Unix
standard; par exemple, les fichiers d'une archive non-compresse peuvent tre compresss avec l'outil gzip. Ce format est
compress par dfaut.
t
archive tar utilisable par pg_restore. Le format tar est compatible avec le format rpertoire; l'extraction d'une archive au format tar produit une archive au format rpertoire valide. Toutefois, le format tar ne supporte pas la compression et a une limite
de 8Go sur la taille des tables individuelles. Par ailleurs, l'ordre de restauration des donnes des tables ne peut pas tre chang
au moment de la restauration.
-i, --ignore-version
Une option obsolte qui est maintenant ignore.
-n schma, --schema=schma
Sauvegarde uniquement les schmas correspondant schema ; la slection se fait la fois sur le schma et sur les objets
qu'il contient. Quand cette option n'est pas indique, tous les schmas non systme de la base cible sont sauvegards. Plusieurs schmas peuvent tre indiqus en utilisant plusieurs fois l'option -n. De plus, le paramtre schma est interprt
comme un modle selon les rgles utilises par les commandes \d de psql (voir la section intitule motifs ). Du coup, plusieurs schmas peuvent tre slectionns en utilisant des caractres joker dans le modle. Lors de l'utilisation de ces caractres, il faut faire attention placer le modle entre guillemets, si ncessaire, pour empcher le shell de remplacer les jokers;
see la section intitule Exemples .

Note
Quand -n est indiqu, pg_dump ne sauvegarde aucun autre objet de la base que ceux dont les schmas slectionns dpendent. Du coup, il n'est pas garanti que la sauvegarde d'un schma puisse tre restaure avec succs dans une base vide.

Note
Les objets qui ne font pas partie du schma comme les objets larges ne sont pas sauvegards quand -n est prcis. Ils peuvent tre rajouter avec l'option --blobs.
-N schma, --exclude-schema=schma
Ne sauvegarde pas les schmas correspondant au modle schma. Le modle est interprt selon les mme rgles que -n. N peut aussi tre indiqu plus d'une fois pour exclure des schmas correspondant des modles diffrents.
Quand les options -n et -N sont indiques, seuls sont sauvegards les schmas qui correspondent au moins une option -n
et aucune option -N. Si -N apparat sans -n, alors les schmas correspondant -N sont exclus de ce qui est une sauvegarde
normale.
-o, --oids
Les identifiants d'objets (OID) sont sauvegards comme donnes des tables. Cette option est utilise dans le cas d'applications
utilisant des rfrences aux colonnes OID (dans une contrainte de cl trangre, par exemple). Elle ne devrait pas tre utilise
dans les autres cas.
-O, --no-owner
1164

pg_dump

Les commandes d'initialisation des possessions des objets au regard de la base de donnes originale ne sont pas produites. Par
dfaut, pg_dump engendre des instructions ALTER OWNER ou SET SESSION AUTHORIZATION pour fixer ces possessions. Ces instructions chouent lorsque le script n'est pas lanc par un superutilisateur (ou par l'utilisateur qui possde tous
les objets de ce script). L'option -O est utilise pour crer un script qui puisse tre restaur par n'importe quel utilisateur. En
revanche, c'est cet utilisateur qui devient propritaire de tous les objets.
Cette option n'a d'intrt que pour le format texte. Pour les formats archive, l'option est prcise l'appel de pg_restore.
-R, --no-reconnect
Cette option, obsolte, est toujours accepte pour des raisons de compatibilit ascendante.
-s, --schema-only
Seule la dfinition des objets (le schma) est sauvegarde, pas les donnes.
-S nomutilisateur, --superuser=nomutilisateur
Le nom du superutilisateur utiliser lors de la dsactivation des dclencheurs. Cela n'a d'intrt que si l'option -disable-triggers est prcise. (En rgle gnrale, il est prfrable de ne pas utiliser cette option et de lancer le script
produit en tant que superutilisateur.)
-t table, --table=table
Sauvegarde uniquement les tables (ou vues ou squences or tables distantes) correspondant table. Plusieurs tables sont slectionnables en utilisant plusieurs fois l'option -t. De plus, le paramtre table est interprt comme un modle suivant les
rgles utilises par les commandes \d de psql (voir la section intitule motifs ). Du coup, plusieurs tables peuvent tre slectionnes en utilisant des caractres joker dans le modle. Lors de l'utilisation de ces caractres, il faut faire attention placer le modle entre guillemets, si ncessaire, pour empcher le shell de remplacer les jokers; see la section intitule
Exemples .
Les options -n et -N n'ont aucun effet quand l'option -t est utilise car les tables slectionnes par -t sont sauvegardes
quelle que soit la valeur des options relatives aux schmas. Les objets qui ne sont pas des tables ne sont pas sauvegards.

Note
Quand -t est indiqu, pg_dump ne sauvegarde aucun autre objet de la base dont la (ou les) table(s) slectionne(s) pourrai(en)t dpendre. Du coup, il n'est pas garanti que la sauvegarde spcifique d'une table puisse tre
restaure avec succs dans une base vide.

Note
Le comportement de l'option -t n'est pas entirement compatible avec les versions de PostgreSQL antrieures la 8.2. Auparavant, crire -t tab sauvegardait toutes les tables nommes tab, mais maintenant,
seules sont sauvegardes celles qui sont visibles dans le chemin de recherche des objets. Pour retrouver
l'ancien comportement, il faut crire -t '*.tab'. De plus, il faut crire quelque chose comme -t
sch.tab pour slectionner une table dans un schma particulier plutt que l'ancienne syntaxe -n sch -t
tab.
-T table, --exclude-table=table
Ne sauvegarde pas les tables correspondant au modle table. Le modle est interprt selon les mme rgles que -t. -T
peut aussi tre indiqu plusieurs pour exclure des tables correspondant des modles diffrents.
Quand les options -t et -T sont indiques, seules sont sauvegardes les tables qui correspondent au moins une option -t et
aucune option -T. Si -T apparat sans -t, alors les tables correspondant -T sont exclues de ce qui est une sauvegarde
normale.
-v, --verbose
Mode verbeux. pg_dump affiche des commentaires dtaills sur les objets et les heures de dbut et de fin dans le fichier de
sauvegarde. Des messages de progression sont galement affichs sur la sortie d'erreur standard.
-V, --version
Affiche la version de pg_dump puis quitte.
-x, --no-privileges, --no-acl
Les droits d'accs (commandes grant/revoke) ne sont pas sauvegards.
-Z 0..9, --compress=0..9
Indique le niveau de compression utiliser. Zro signifie sans compression. Pour le format d'archive personnalis, cela signifie la compression des segments individuels des donnes des tables. Par dfaut, la compression se fait un niveau modr.
Pour le format texte, indiquer une valeur diffrente de zro implique une compression du fichier complet, comme s'il tait
1165

pg_dump

pass gzip ; mais par dfaut, la sortie n'est pas compresse. Le format d'archive tar ne supporte pas du tout la compression.
--binary-upgrade
Cette option est destine tre utilise pour une mise jour en ligne. Son utilisation dans d'autres buts n'est ni recommande
ni supporte. Le comportement de cette option peut changer dans les futures versions sans avertissement.
--column-inserts, --attribute-inserts
Extraire les donnes en tant que commandes INSERT avec des noms de colonnes explicites (INSERT INTO table
(colonne, ...) VALUES ...). Ceci rendra la restauration trs lente ; c'est surtout utile pour crer des extractions qui
puissent tre charges dans des bases de donnes autres que PostgreSQL.
--disable-dollar-quoting
Cette option dsactive l'utilisation du caractre dollar comme dlimiteur de corps de fonctions, et force leur dlimitation en
tant que chane SQL standard.
--disable-triggers
Cette option ne s'applique que dans le cas d'une extraction de donnes seules. Ceci demande pg_dump d'inclure des commandes pour dsactiver temporairement les triggers sur les tables cibles pendant que les donnes sont recharges. Utilisez ceci si, sur les tables, vous avez des contraintes d'intgrit ou des triggers que vous ne voulez pas invoquer pendant le rechargement.
l'heure actuelle, les commandes mises pour --disable-triggers doivent tre excutes en tant que superutilisateur.
Par consquent, vous devez aussi spcifier un nom de superutilisateur avec -S, ou prfrablement faire attention lancer le
script rsultat en tant que superutilisateur.
Cette option n'a de sens que pour le format texte simple. Pour les formats d'archive, vous pouvez spcifier cette option quand
vous appelez pg_restore.
--inserts
Extraire les donnes en tant que commandes INSERT (plutt que COPY). Ceci rendra la restauration trs lente ; c'est surtout
utile pour crer des extractions qui puissent tre charges dans des bases de donnes autres que PostgreSQL. Notez que la
restauration peut chouer compltement si vous avez chang l'ordre des colonnes. L'option --column-inserts est plus
sre, mais encore plus lente.
--lock-wait-timeout=expiration
Ne pas attendre indfiniment l'acquisition de verrous partags sur table au dmarrage de l'extraction. chouer la place s'il est
impossible de verrouiller une table dans le temps d'expiration indiqu. L'expiration peut tre spcifie dans tous les formats accepts par SET statement_timeout, les valeurs autorises dpendant de la version du serveur sur laquelle vous faites
l'extraction, mais une valeur entire en millisecondes est accepte par toutes les versions depuis la 7.3. Cette option est ignore si vous exportez d'une version antrieure la 7.3.
--no-security-labels
Ne sauvegarde pas les labels de scurit.
--no-tablespaces
Ne pas gnrer de commandes pour crer des tablespace, ni slectionner de tablespace pour les objets. Avec cette option, tous
les objets seront crs dans le tablespace par dfaut durant la restauration.
Cette option n'a de sens que pour le format texte simple. Pour les formats d'archive, vous pouvez spcifier cette option quand
vous appelez pg_restore.
--no-unlogged-table-data
Ne pas exporter le contenu des tables non journalises (unlogged). Cette option n'a aucun effet sur le fait que la dfinition
(schma) des tables soit exporte ou non; seul l'export des donnes de la table est supprim. Les donnes des tables non journalises sont toujours exclues lors d'une sauvegarde partir d'un serveur en standby.
--quote-all-identifiers
Force la mise entre guillemets de tous les identifiants. Ceci peut tre utile si vous exportez votre base en vue d'une migration
dans une nouvelle version qui aurait introduit de nouveaux mots cls.
--serializable-deferrable
Utiliser une transaction srialisable pour l'export, pour garantir que l'instantan utilis est cohrent avec les tats futurs
de la base; mais ceci est effectu par l'attente d'un point dans le flux des transactions auquel aucune anomalie ne puisse tre
prsente, afin qu'il n'y ait aucun risque que l'export choue ou cause l'annulation d'une autre transaction pour erreur de
srialisation. Voyez Chapitre 13, Contrle d'accs simultan pour davantage d'informations sur l'isolation des transactions et le contrle d'accs concurrent.
Cette option est inutile pour un dump qui ne sera utilis qu'en cas de rcupration aprs sinistre. Elle pourrait tre utile pour
un dump utilis pour charger une copie de la base pour du reporting ou toute autre activit en lecture seule tandis que la base
originale continue tre mise jour. Sans cela, le dump serait dans un tat incohrent avec l'excution srielle des transac1166

pg_dump

tions qui auront t finalement valides. Par exemple, si un traitement de type batch est excut, un batch pourrait apparatre
comme termin dans le dump sans que tous les lments du batch n'apparaissent.
Cette option ne fera aucune diffrence si aucune transaction en lecture-criture n'est active au lancement de pg_dupm. Si des
transactions en lecture-criture sont actives, le dmarrage du dump pourrait tre retard pour une dure indtermine. Une fois
qu'il sera dmarr, la performance est identique celle d'un dump sans cette option.
--use-set-session-authorization
mettre des commandes SQL standard SET SESSION AUTHORIZATION la place de commandes ALTER OWNER
pour dterminer l'appartenance d'objet. Ceci rend l'extraction davantage compatible avec les standards, mais, suivant
l'historique des objets de l'extraction, peut ne pas se restaurer correctement. Par ailleurs, une extraction utilisant SET SESSION AUTHORIZATION ncessitera certainement des droits superutilisateur pour se restaurer correctement, alors que ALTER OWNER ncessite des droits moins levs.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de pg_dump, puis quitte
Les options de ligne de commande suivantes grent les paramtres de connexion :
-h hte, --host hte
Le nom d'hte de la machine sur laquelle le serveur de bases de donnes est excut. Si la valeur commence par une barre
oblique (/), elle est utilise comme rpertoire pour le socket de domaine Unix. La valeur par dfaut est fournie par la variable
d'environnement PGHOST, si elle est initialise. Dans le cas contraire, une connexion sur la socket de domaine Unix est tente.
-p port, --port port
Le port TCP ou le fichier local de socket de domaine Unix sur lequel le serveur coute les connexions. La valeur par dfaut
est fournie par la variable d'environnement PGPORT, si elle est initialise. Dans le cas contraire, il s'agit de la valeur fournie
la compilation.
-U nomutilisateur, --username nomutilisateur
Le nom d'utilisateur utilis pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut tre
utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force pg_dump demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais ncessaire car pg_dump demande automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, pg_dump perd une tentative de connexion pour tester si le serveur demande un mot de
passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.
--role=nomrole
Spcifie un rle utiliser pour crer l'extraction. Avec cette option, pg_dump met une commande SET ROLE nomrole
aprs s'tre connect la base. C'est utile quand l'utilisateur authentifi (indiqu par -U) n'a pas les droits dont pg_dump a besoin, mais peut basculer vers un rle qui les a. Certaines installations ont une politique qui est contre se connecter directement
en tant que superutilisateur, et l'utilisation de cette option permet que les extractions soient faites sans violer cette politique.

Environnement
PGDATABASE, PGHOST, PGOPTIONS, PGPORT, PGUSER
Paramtres de connexion par dfaut.
Cet outil, comme la plupart des autres outils PostgreSQL, utilise les variables d'environnement supportes par la bibliothque
libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
pg_dump excute intrinsquement des instructions SELECT. Si des problmes apparaissent l'excution de pg_dump, psql(1)
peut tre utilis pour s'assurer qu'il est possible de slectionner des informations dans la base de donnes. De plus, tout paramtre
de connexion par dfaut et toute variable d'environnement utilis par la bibliothque libpq s'appliquent.
L'activit gnre par pg_dump dans la base de donnes est normalement collecte par le collecteur de statistiques. Si c'est gnant,
1167

pg_dump

vous pouvez positionner le paramtre track_counts false via PGOPTIONS ou la commande ALTER USER.

Notes
Si des ajouts locaux la base template1 ont t effectus, il est impratif de s'assurer que la sortie de pg_dump est effectivement restaure dans une base vide ; dans le cas contraire, il est fort probable que la duplication des dfinitions des objets ajouts
engendre des erreurs. Pour obtenir une base vide de tout ajout local, on utilise template0 la place de template1 comme
modle. Par exemple :
CREATE DATABASE foo WITH TEMPLATE template0;
Quand une sauvegarde des seules donnes est slectionne et que l'option --disable-triggers est utilise, pg_dump engendre des commandes de dsactivation des dclencheurs sur les tables utilisateur avant l'insertion des donnes, puis aprs coup,
des commandes de ractivation aprs l'insertion. Si la restauration est interrompue, il se peut que les catalogues systmes
conservent cette position.
Les fichiers d'une archive tar sont limits une taille infrieure 8 Go. (C'est une limitation inhrente au format des fichiers tar.)
Ce format ne peut donc pas tre utilis si la reprsentation textuelle d'une table dpasse cette taille. La taille totale d'une archive tar
et de tout autre format de sortie n'est pas limite, sauf peut-tre par le systme d'exploitation.
Le fichier de sauvegarde produit par pg_dump ne contient pas les statistiques utilises par l'optimiseur pour la planification des requtes. Il est donc conseill, pour assurer des performances optimales, de lancer ANALYZE aprs la restauration d'une sauvegarde ; voir Section 23.1.3, Maintenir les statistiques du planificateur et Section 23.1.5, Le dmon auto-vacuum pour plus
d'informations. Le fichier de sauvegarde ne contient pas non plus de commandes ALTER DATABASE ... SET ; ces paramtres
sont sauvegards par pg_dumpall(1), avec les utilisateurs et les paramtres globaux l'installation.
Parce que pg_dump est utilis pour transfrer des donnes vers des nouvelles versions de PostgreSQL, la sortie de pg_dump devra pouvoir se charger dans les versions du serveur PostgreSQL plus rcentes que la version de pg_dump. pg_dump peut aussi
extraire des donnes de serveurs PostgreSQL plus anciens que sa propre version. ( l'heure actuelle, les versions de serveurs
supportes vont jusqu' la 7.0.) Toutefois, pg_dump ne peut pas raliser d'extraction de serveurs PostgreSQL plus rcents que sa
propre version majeure ; il refusera mme d'essayer, plutt que de risquer de fournir une extraction invalide. Par ailleurs, il n'est
pas garanti que la sortie de pg_dump puisse tre charge dans un serveur d'une version majeure plus ancienne -- pas mme si
l'extraction a t faite partir d'un serveur dans cette version. Charger un fichier d'extraction dans un serveur de version plus ancienne pourra requrir une dition manuelle du fichier pour supprimer les syntaxe incomprises de l'ancien serveur.

Exemples
Sauvegarder une base appele ma_base dans un script SQL :
$ pg_dump ma_base > base.sql
To dump a database into a directory-format archive:
$ pg_dump -Fd mydb -f dumpdir
Charger ce script dans une base nouvellement cre et nomme nouvelle_base:
$ psql -d nouvelle_base -f base.sql
Sauvegarder une base dans un fichier au format personnalis :
$ pg_dump -Fc ma_base > base.dump
Charger un fichier d'archive dans une nouvelle base nomme nouvelle_base :
$ pg_restore -d nouvelle_base base.dump
Sauvegarder la table nomme mytab :
$ pg_dump -t ma_table ma_base > base.sql
Sauvegarder toutes les tables du schma detroit et dont le nom commence par emp sauf la table nomme
traces_employes :
$ pg_dump -t 'detroit.emp*' -T detroit.traces_employes ma_base > base.sql
Sauvegarder tous les schmas dont le nom commence par est ou ouest et se termine par gsm, en excluant les schmas dont le
1168

pg_dump

nom contient le mot test :


$ pg_dump -n 'est*gsm' -n 'ouest*gsm' -N '*test*' ma_base > base.sql
Idem mais en utilisant des expressions rationnelles dans les options :
$ pg_dump -n '(est|ouest)*gsm' -N '*test*' ma_base > base.sql
Sauvegarder tous les objets de la base sauf les tables dont le nom commence par ts_ :
$ pg_dump -T 'ts_*' ma_base > base.sql
Pour indiquer un nom qui comporte des majuscules dans les options -t et assimiles, il faut ajouter des guillemets doubles ; sinon
le nom est converti en minuscules (voirla section intitule motifs ). Les guillemets doubles sont interprts par le shell et
doivent dont tre placs entre guillemets. Du coup, pour sauvegarder une seule table dont le nom comporte des majuscules, on utilise une commande du style :
$ pg_dump -t '"NomAMajuscule"' ma_base > ma_base.sql

Voir aussi
pg_dumpall(1), pg_restore(1), psql(1)

1169

Nom
pg_dumpall extraire une grappe de bases de donnes PostgreSQL dans un fichier de script

Synopsis
pg_dumpall [option_connexion...] [option...]

Description
pg_dumpall est un outil d'extraction ( sauvegarde ) de toutes les bases de donnes PostgreSQL d'une grappe vers un fichier
script. Celui-ci contient les commandes SQL utilisables pour restaurer les bases de donnes avec psql(1). Cela est obtenu en appelant pg_dump(1) pour chaque base de donnes de la grappe. pg_dumpall sauvegarde aussi les objets globaux, communs
toutes les bases de donnes. (pg_dump ne sauvegarde pas ces objets.) Cela inclut aussi les informations concernant les utilisateurs et groupes des bases de donnes, ainsi que les tablespaces et les proprits telles que les droits d'accs s'y appliquant.
Puisque pg_dumpall lit les tables de toutes les bases de donnes, il est prfrable d'avoir les droits de superutilisateur de la base
de donnes pour obtenir une sauvegarde complte. De plus, il faut dtenir des droits superutilisateur pour excuter le script produit, afin de pouvoir crer les utilisateurs, les groupes et les bases de donnes.
Le script SQL est crit sur la sortie standard. Utilisez l'option [-f|fichier] ou les oprateurs shell pour la rediriger vers un fichier.
pg_dumpall se connecte plusieurs fois au serveur PostgreSQL (une fois par base de donnes). Si l'authentification par mot de
passe est utilis, un mot de passe est demand chaque tentative de connexion. Il est intressant de disposer d'un fichier
~/.pgpass dans de tels cas. Voir Section 31.14, Fichier de mots de passe pour plus d'informations.

Options
Les options suivantes, en ligne de commande, contrlent le contenu et le format de la sortie.
-a, --data-only
Seules les donnessont sauvegardes, pas le schma (dfinition des donnes).
-c, --clean
Les commandes SQL de nettoyage (suppression) des bases de donnes avant leur recration sont incluses. Des commandes
DROP sont galement ajoutes pour les rles et les tablespaces.
-f nomfichier, --file=nomfichier
Envoie le rsultat dans le fichier indiqu. Si cette option n'est pas utilise, la sortie standard est utilise.
-g, --globals-only
Seuls les objets globaux sont sauvegards (rles et tablespaces), pas les bases de donnes.
-i, --ignore-version
Une option obsolte qui est maintenant ignore.
pg_dumpall peut grer des bases de donnes de versions prcdentes de PostgreSQL, mais les trs anciennes versions ne
sont plus supportes (avant la 7.0). Cette option peut tre utilise pour surcharger la vrification de la version (si
pg_dumpall choue, il ne faudra pas nier avoir t averti).
-o, --oids
Les identifiants des objets (OID) sont sauvegards comme faisant partie des donnes de chaque table. Cette option est utilise si l'application rfrence les colonnes OID (par exemple, dans une contrainte de cl trangre). Sinon, cette option ne
doit pas tre utilise.
-O, --no-owner
Les commandes permettant de positionner les propritaires des objets ceux de la base de donnes originale. Par dfaut,
pg_dumpall lance les instructions ALTER OWNER ou SET SESSION AUTHORIZATION pour configurer le propritaire des lments crs. Ces instructions chouent lorsque le script est lanc par un utilisateur ne disposant pas des droits de
superutilisateur (ou ne possdant pas les droits du propritaire de tous les objets compris dans ce script). Pour que ce qui devient alors propritaire de tous les objets crs, l'option -O doit tre utilise.
-r, --roles-only
Sauvegarde seulement les rles, pas les bases ni les tablespaces.
-s, --schema-only
Seules les dfinitions des objets (schma), sans les donnes, sont sauvegardes.
1170

pg_dumpall

-S username, --superuser=username
Prcise le nom du superutilisateur utiliser pour la dsactivation des dclencheurs. Cela n'a d'intrt que lorsque -disable-triggers est utilis. (Il est en gnral prfrable de ne pas utiliser cette option et de lancer le script rsultant
en tant que superutilisateur.)
-t, --tablespaces-only
Sauvegarde seulement les tablespaces, pas les bases ni les rles.
-v, --verbose
Indique l'utilisation du mode verbeux. Ainsi pg_dumpall affiche les heures de dmarrage/arrt dans le fichier de sauvegarde et
les messages de progression sur la sortie standard. Il active galement le mode verbeux dans pg_dump.
-V, --version
Affiche la version de pg_dumpall puis quitte.
-x, --no-privileges, --no-acl
Les droits d'accs (commandes grant/revoke) ne sont pas sauvegards.
--binary-upgrade
Cette option est destine tre utilise pour une mise jour en ligne. Son utilisation dans d'autres buts n'est ni recommande
ni supporte. Le comportement de cette option peut changer dans les versions futures sans avertissement.
--column-inserts, --attribute-inserts
Extraire les donnes en tant que commandes INSERT avec des noms de colonnes explicites (INSERT INTO table
(colonne, ...) VALUES ...). Ceci rendra la restauration trs lente ; c'est surtout utile pour crer des extractions qui
puissent tre charges dans des bases de donnes autres que PostgreSQL.
--disable-dollar-quoting
L'utilisation du dollar comme guillemet dans le corps des fonctions est dsactive. Celles-ci sont mises entre guillemets en accord avec la syntaxe du standard SQL.
--disable-triggers
Cette option n'est utile que lors de la cration d'une sauvegarde des seules donnes. pg_dumpall inclut les commandes de
dsactivation temporaire des dclencheurs sur les tables cibles pendant le rechargement des donnes. Cette option est utile
lorsqu'il existe des vrifications d'intgrit rfrentielle ou des dclencheurs sur les tables qu'on ne souhaite pas voir appels
lors du rechargement des donnes.
Actuellement, les commandes mises par --disable-triggers ncessitent d'tre lances par un superutilisateur. Il est
donc impratif de prciser le nom du superutilisateur avec -S ou, prfrentiellement, de lancer le script rsultant en tant que
superutilisateur.
--inserts
Extraire les donnes en tant que commandes INSERT (plutt que COPY). Ceci rendra la restauration trs lente ; c'est surtout
utile pour crer des extractions qui puissent tre charges dans des bases de donnes autres que PostgreSQL. Notez que la
restauration peut chouer compltement si vous avez chang l'ordre des colonnes. L'option --column-inserts est plus
sre, mais encore plus lente.
--lock-wait-timeout=expiration
Ne pas attendre indfiniment l'acquisition de verrous partags sur table au dmarrage de l'extraction. chouer la place s'il est
impossible de verrouiller une table dans le temps d'expiration spcifi. L'expiration peut tre indique dans tous les formats accepts par SET statement_timeout, les valeurs autorises dpendant de la version du serveur sur laquelle vous faites
l'extraction, mais une valeur entire en millisecondes est accepte par toutes les versions depuis la 7.3. Cette option est ignore si vous exportez d'une version antrieure la 7.3.
--no-tablespaces
Ne pas gnrer de commandes pour crer des tablespace, ni slectionner de tablespace pour les objets. Avec cette option, tous
les objets seront crs dans le tablespace par dfaut durant la restauration.
--no-security-labels
Ne sauvegarde pas les labels de scurit.
--no-unlogged-table-data
Ne sauvegarde pas le contenu des tables non traces dans les journaux de transactions. Cette option n'a pas d'effet sur la sauvegarde des dfinitions de table ; il supprime seulement la sauvegarde des donnes des tables.
--quote-all-identifiers
Force la mise entre guillemets de tous les identifiants. Cela peut tre utile lors de la sauvegarde d'une base de donnes pour
migration vers une version future qui pourraient avoir introduit des mots-cls supplmentaires.
--use-set-session-authorization
1171

pg_dumpall

Les commandes SET SESSION AUTHORIZATION du standard SQL sont affiches la place des commandes ALTER
OWNER pour prciser le propritaire de l'objet. Cela amliore la compatibilit de la sauvegarde vis--vis des standard. Toutefois, du fait de l'ordre d'apparition des objets dans la sauvegarde, la restauration peut ne pas tre correcte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de pg_dumpall, puis quitte
Les options suivantes en ligne de commande contrlent les paramtres de connexion la base de donnes.
-h hte, --host=hte
Prcise le nom d'hte de la machine sur laquelle le serveur de bases de donnes est en cours d'excution. Si la valeur commence avec un slash, elle est utilise comme rpertoire du socket de domaine Unix. La valeur par dfaut est prise partir de la
variable d'environnement PGHOST, si elle est initialise, sinon une connexion socket de domaine Unix est tente.
-l dbname, --database=dbname
Spcifie le nom de la base o se connecter pour la sauvegarde des gobjets globaux et pour dcouvrir les bases qui devraient
tre sauvegardes. Si cette option n'est pas utilise, la base postgres est utilis et, si elle n'est pas, template1 sera utilise.
-p port, --port=port
Prcise le port TCP ou l'extension du fichier socket de domaine Unix local sur lequel le serveur est en coute des connexions.
La valeur par dfaut est la variable d'environnement PGPORT, si elle est initialise, ou la valeur utilise lors de la compilation.
-U nomutilisateur, --username=nomutilisateur
Utilisateur utilis pour initier la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut tre
utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force pg_dumpall demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais obligatoire car pg_dumpall demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, pg_dumpall perdra une tentative de connexion pour trouver que le serveur veut
un mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.
Notez que le mot de passe sera demand pour chaque base de donnes sauvegarder. Habituellement, il est prfrable de
configurer un fichier ~/.pgpass pour que de s'en tenir une saisie manuelle du mot de passe.
--role=nomrole
Spcifie un rle utiliser pour crer l'extraction. Avec cette option, pg_dumpall met une commande SET ROLE nomrole
aprs s'tre connect la base. C'est utile quand l'utilisateur authentifi (indiqu par -U) n'a pas les droits dont pg_dumpall a
besoin, mais peut basculer vers un rle qui les a. Certaines installations ont une politique qui est contre se connecter directement en tant que superutilisateur, et l'utilisation de cette option permet que les extractions soient faites sans violer cette politique.

Environnement
PGHOST, PGOPTIONS, PGPORT, PGUSER
Paramtres de connexion par dfaut
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Notes
Comme pg_dumpall appelle pg_dump en interne, certains messages de diagnostique se rfrent en fait pg_dump.
Une fois la restauration effectue, il est conseill de lancer ANALYZE sur chaque base de donnes, de faon ce que l'optimiseur
dispose de statistiques utiles. vacuumdb -a -z peut galement tre utilis pour analyser toutes les bases de donnes.
pg_dumpall requiert que tous les tablespaces ncessaires existent avant la restauration. Dans le cas contraire, la cration de la base
chouera pour une base qui ne se trouve pas dans l'emplacement par dfaut.

1172

pg_dumpall

Exemples
Sauvegarder toutes les bases de donnes :
$ pg_dumpall > db.out
Pour recharger les bases de donnes partir de ce fichier, vous pouvez utiliser :
$ psql -f db.out postgres
(La base de donnes utilise pour la connexion initiale n'a pas d'importance ici car le fichier de script cr par pg_dumpall contient
les commandes ncessaires la cration et la connexion aux bases de donnes sauvegardes.)

Voir aussi
Vrifier pg_dump(1) pour des dtails sur les conditions d'erreur possibles.

1173

Nom
pg_restore restaure une base de donnes PostgreSQL partir d'un fichier d'archive cr par pg_dump

Synopsis
pg_restore [option_connexion...] [option...] [nom_fichier]

Description
pg_restore est un outil pour restaurer une base de donnes PostgreSQL partir d'une archive cre par pg_dump(1) dans un
des formats non textuel. Il lance les commandes ncessaires pour reconstruire la base de donnes dans l'tat o elle tait au moment de sa sauvegarde. Les fichiers d'archive permettent aussi pg_restore d'tre slectif sur ce qui est restaur ou mme de rordonner les lments restaurer. Les fichiers d'archive sont conus pour tre portables entre les architectures.
pg_restore peut oprer dans deux modes. Si un nom de base de donnes est spcifi, pg_restore se connecte cette base de donnes et restaure le contenu de l'archive directement dans la base de donnes. Sinon, un script contenant les commandes SQL ncessaires pour reconstruire la base de donnes est cr et crit dans un fichier ou sur la sortie standard. La sortie du script est
quivalente celles cres par le format en texte plein de pg_dump. Quelques-unes des options contrlant la sortie sont du coup
analogues aux options de pg_dump.
De toute vidence, pg_restore ne peut pas restaurer l'information qui ne se trouve pas dans le fichier d'archive. Par exemple, si
l'archive a t ralise en utilisant l'option donnant les donnes sauvegardes par des commandes INSERT , pg_restore ne
sera pas capable de charger les donnes en utilisant des instructions COPY.

Options
pg_restore accepte les arguments suivants en ligne de commande.
nom_fichier
Spcifie l'emplacement du fichier d'archive (ou du rpertoire pour une archive au format directory ) restaurer. S'il n'est
pas spcifi, l'entre standard est utilise.
-a, --data-only
Restaure seulement les donnes, pas les schmas (dfinitions des donnes).
-c, --clean
Nettoie (supprime) les objets de la base de donnes avant de les crer.
-C, --create
Cre la base de donnes avant de la restaurer. (Quand cette option est utilise, la base de donnes nomme avec -d est utilise seulement pour lancer la commande initiale CREATE DATABASE. Toutes les donnes sont restaures dans le nom de
la base de donnes qui apparat dans l'archive.)
-d nom_base, --dbname=nom_base
Se connecte la base de donnes nom_base et restaure directement dans la base de donnes.
-e, --exit-on-error
Quitte si une erreur est rencontre lors de l'envoi des commandes SQL la base de donnes. La valeur par dfaut est de
continuer et d'afficher le nombre d'erreurs la fin de la restauration.
-f nom_fichier, --file=filename
Spcifie le fichier en sortie pour le script gnr ou pour la liste lorsqu'elle est utilise avec -l. Par dfaut, il s'agit de la
sortie standard.
-F format, --format=format
Spcifie le format de l'archive. Il n'est pas ncessaire de le spcifier car pg_restore dtermine le format automatiquement. Si
spcifi, il peut tre un des suivants :
c, custom
L'archive est dans le format personnalis de pg_dump.
d, directory
L'archive est un rpertoire (directory).
t, tar
L'archive est une archive tar.
1174

pg_restore

-i, --ignore-version
Une option obsolte qui est maintenant ignore.
-I index, --index=index
Restaure uniquement la dfinition des index nomms.
-j nombre-de-jobs, --jobs=nombre-de-jobs
Excute les parties les plus consommatrices en temps de pg_restore -- celles des chargements de donnes, crations d'index et
crations de contraintes -- en utilisant plusieurs jobs concurrents. Cette option peut rduire de beaucoup le temps pour restaurer une grosse base de donnes pour un serveur fonctionnant sur une machine multi-processeus.
Chaque job est un processus ou un thread, suivant le systme d'exploitation, et utilise une connexion spare au serveur.
La valeur optimale pour cette option dpend de la configuration matrielle du serveur, du client et du rseau. Les facteurs incluent le nombre de curs CPU et la configuration disque. Un bon moyen pour commencer est le nombre de curs CPU du
serveur, mais une valeur plus grande que a peut amener des temps de restauration encore meilleurs dans de nombreux cas.
Bien sr, les valeurs trop hautes apporteront des performances en baisse.
Seul le format d'archivage personnalis est support avec cette option. Le fichier en entre doit tre un fichier standard (pas un
tube par exemple). Cette option est ignore lors de la cration d'un script plutt qu'une connexion la base de donnes. De
plus, plusieurs jobs ne peuvent pas tre utiliss ensemble si vous voulez l'option --single-transaction.
-l, --list
Liste le contenu de l'archive. Le rsultat de cette opration peut tre utilis en entre de l'option -L. Notez que, si vous utilisez
des options de filtre telles que -n ou -t avec l'option -l, elles restreignent les lments lists.
-L fichier_liste, --use-list=fichier_liste
Restaure seulement les objets qui sont lists dans le fichier fichier_liste, et les restaure dans l'ordre o elles apparaissent dans le fichier. Notez que, si des options de filtre comme -n et -t sont utilises avec -L, elles ajouteront cette restriction aux lments restaurs.
fichier_liste est normalement cr en ditant la sortie d'une prcdente opration -l. Les lignes peuvent tre dplaces
ou supprimes, et peuvent aussi tre mise en commentaire en ajoutant un point-virgule (;) au dbut de la ligne. Voir cidessous pour des exemples.
-n nom_schema, --schema=nom_schema
Restaure seulement les objets qui sont dans le schma nomm. Elle peut tre combine avec l'option -t pour ne restaurer
qu'une seule table.
-O, --no-owner
Ne pas donner les commandes initialisant les propritaires des objets pour correspondre la base de donnes originale. Par
dfaut, pg_restore lance des instructions ALTER OWNER ou SET SESSION AUTHORIZATION pour configurer le propritaire des lments du schma cr. Ces instructions chouent sauf si la connexion initiale la base de donnes est ralise
par un superutilisateur (ou le mme utilisateur que le propritaire des objets du script). Avec -O, tout nom d'utilisateur peut
tre utilis pour la connexion initiale et cet utilisateur est le propritaire des objets crs.
-P nom_fonction(argtype [, ...]), --function=nom_fonction(argtype [, ...])
Restaure seulement la fonction nomme. Faites attention peler le nom de la fonction et les arguments exactement comme
ils apparaissent dans la table des matires du fichier de sauvegarde.
-r, --no-reconnect
Cette option est obsolte mais est toujours accepte pour des raisons de compatibilit ascendante.
-s, --schema-only
Restaure uniquement le schma (dfinition des donnes), et non pas les donnes elles-mme (contenu de la table). Les valeurs
actuelles des squences ne seront pas restaures. ne pas confondre avec l'option --schema qui utilise le mot schma avec
une autre signification).
-S nom_utilisateur, --superuser=nom_utilisateur
Spcifie le nom d'utilisateur du superutilisateur utiliser pour dsactiver les dclencheurs. Ceci est seulement ncessaire si -disable-triggers est utilis.
-t table, --table=table
Restaure uniquement la dfinition et/ou les donnes de la table nomme. Ceci est combinable avec l'option -n pour spcifier
un schma.
-T trigger, --trigger=trigger
Restaure uniquement le dclencheur nomm.
-v, --verbose
1175

pg_restore

Spcifie le mode verbeux.


-V, --version
Affiche la version de pg_restore, puis quitte.
-x, --no-privileges, --no-acl
Empche la restauration des droits d'accs (commandes grant/revoke).
-1, --single-transaction
Excute la restauration en une seule transaction (autrement dit, toutes les commandes de restauration sont places entre un
BEGIN et un COMMIT). Ceci assure l'utilisateur que soit toutes les commandes russissent, soit aucun changement n'est appliqu. Cette option implique --exit-on-error.
--disable-triggers
Cette option n'est pertinente que lors d'une restauration des donnes seules. Elle demande pg_restore d'excuter des commandes pour dsactiver temporairement les dclencheurs sur les tables cibles pendant que les donnes sont recharges. Utilisez ceci si vous avez des vrifications d'intgrit rfrentielle sur les tables que vous ne voulez pas appeler lors du rechargement des donnes.
Actuellement, les commandes mises pour --disable-triggers doivent tre excutes par un superutilisateur. Donc,
vous devriez aussi spcifier un nom de superutilisateur avec -S ou, de prfrence, lancer pg_restore en tant que superutilisateur PostgreSQL.
--no-data-for-failed-tables
Par dfaut, les donnes de la table sont restaures mme si la commande de cration de cette table a chou (par exemple
parce qu'elle existe dj). Avec cette option, les donnes de cette table seront ignores. Ce comportement est utile si la base
cible contient dj des donnes pour cette table. Par exemple, les tables supplmentaires des extensions de PostgreSQL
comme PostGIS pourraient avoir dj t cres et remplies sur la base cible ; indiquer cette option empche l'ajout de donnes dupliques ou obsoltes.
Cette option est seulement efficace lors de la restauration directe d'une base, pas lors de la ralisation d'une sortie de script
SQL.
--no-security-labels
Ne rcupre pas les commandes de restauration des labels de scurit, mme si l'archive les contient.
--no-tablespaces
Ne slectionne pas les tablespaces. Avec cette option, tous les objets seront crs dans le tablespace par dfaut lors de la restauration.
--use-set-session-authorization
Affiche les commandes SET SESSION AUTHORIZATION du standard SQL la place des commandes ALTER OWNER
pour dterminer le propritaire de l'objet. Ceci rend la sauvegarde plus compatible avec les standards mais, suivant
l'historique des objets dans la sauvegarde, pourrait restaurer correctement.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de pg_restore, puis quitte.
pg_restore accepte aussi les arguments suivants en ligne de commande pour les paramtres de connexion :
-h hte, --host=hte
Spcifie le nom d'hte de la machine sur lequel le serveur est en cours d'excution. Si la valeur commence par un slash, elle
est utilise comme rpertoire du socket de domaine Unix. La valeur par dfaut est prise dans la variable d'environnement
PGHOST, si elle est initialise, sinon une connexion socket de domaine Unix est tente.
-p port, --port=port
Spcifie le port TCP ou l'extension du fichier socket de domaine Unix sur lequel le serveur coute les connexions. Par dfaut,
l'outil utilise la variable d'environnement PGPORT, si elle est configure, sinon il utilise la valeur indique la compilation.
-U nom_utilisateur, --username=nom_utilisateur
Se connecte en tant que cet utilisateur
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut tre
utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force pg_restore demander un mot de passe avant la connexion une base de donnes.
1176

pg_restore

Cette option n'est jamais obligatoire car pg_restore demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, pg_restore perdra une tentative de connexion pour trouver que le serveur veut un
mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.
--role=nom_rle
Indique un nom de rle utilis pour la restauration. Cette option fait que pg_restore excute un SET ROLE nom_rle aprs
connexion la base de donnes. C'est utile quand l'utilisateur authentifi (indiqu par l'option -U) n'a pas les droits demands
par pg_restore, mais peut devenir le rle qui a les droits requis. Certains installations ont une politique contre la connexion en
super-utilisateur directement, et utilisent cette option pour permettre aux restaurations de se faire sans violer cette rgle.

Environnement
PGHOST, PGOPTIONS, PGPORT, PGUSER
Paramtres de connexion par dfaut
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
Quand une connexion directe la base de donnes est spcifie avec l'option -d, pg_restore excute en interne des instructions
SQL. Si vous avez des problmes en excutant pg_restore, assurez-vous d'tre capable de slectionner des informations partir de
la base de donnes en utilisant, par exemple partir de psql(1). De plus, tout paramtre de connexion par dfaut et toute variable
d'environnement utilis par la bibliothque libpq s'appliqueront.

Notes
Si votre installation dispose d'ajouts locaux la base de donnes template1, faites attention charger la sortie de pg_restore
dans une base de donnes rellement vide ; sinon, vous avez des risques d'obtenir des erreurs des aux dfinitions dupliques des
objets ajouts. Pour crer une base de donnes vide sans ajout local, copiez partir de template0, et non pas de template1,
par exemple :
CREATE DATABASE foo WITH TEMPLATE template0;
Les limitations de pg_restore sont dtailles ci-dessous.

Lors de la restauration des donnes dans une table pr-existante et que l'option --disable-triggers est utilise,
pg_restore met des commandes pour dsactiver les dclencheurs sur les tables utilisateur avant d'insrer les donnes, puis
met les commandes pour les ractiver aprs l'insertion des donnes. Si la restauration est stoppe en plein milieu, les catalogues systme pourraient tre abandonns dans le mauvais tat.

pg_restore ne peut pas restaurer les large objects de faon slective, par exemple seulement ceux d'une table prcise. Si
une archive contient des large objects , alors tous les large objects seront restaures (ou aucun s'ils sont exclus avec
l'option -L, l'option -t ou encore d'autres options.

Voir aussi la documentation de pg_dump(1) pour les dtails sur les limitations de pg_dump.
Une fois la restauration termine, il est conseill de lancer ANALYZE sur chaque table restaure de faon ce que l'optimiseur
dispose de statistiques utiles ; voir Section 23.1.3, Maintenir les statistiques du planificateur et Section 23.1.5, Le dmon auto-vacuum pour plus d'informations.

Exemples
Supposons que nous avons sauvegard une base nomme ma_base dans un fichier de sauvegarde au format personnalis :
$ pg_dump -Fc ma_base > ma_base.dump
Pour supprimer la base et la re-crer partir de la sauvegarde :
$ dropdb ma_base
$ pg_restore -C -d postgres ma_base.dump
La base nomme avec l'option -d peut tre toute base de donnes existante dans le cluster ; pg_restore l'utilise seulement pour
1177

pg_restore

excuter la commande CREATE DATABASE pour ma_base. Avec -C, les donnes sont toujours restaures dans le nom de la
base qui apparat dans le fichier de sauvegarde.
Pour charger la sauvegarde dans une nouvelle base nomme nouvelle_base :
$ createdb -T template0 newdb
$ pg_restore -d newdb db.dump
Notez que nous n'utilisons pas -C et que nous nous sommes connects directement sur la base restaurer. De plus, notez que nous
clonons la nouvelle base partir de template0 et non pas de template1, pour s'assurer qu'elle est vide.
Pour rordonner les lments de la base de donnes, il est tout d'abord ncessaire de sauvegarder la table des matires de
l'archive :
$ pg_restore -l ma_base.dump > ma_base.liste
Le fichier de liste consiste en un en-tte et d'une ligne par lment, par exemple :
;
; Archive created at Mon Sep 14 13:55:39 2009
;
dbname: DBDEMOS
;
TOC Entries: 81
;
Compression: 9
;
Dump Version: 1.10-0
;
Format: CUSTOM
;
Integer: 4 bytes
;
Offset: 8 bytes
;
Dumped from database version: 8.3.5
;
Dumped by pg_dump version: 8.3.8
;
;
; Selected TOC Entries:
;
3; 2615 2200 SCHEMA - public pasha
1861; 0 0 COMMENT - SCHEMA public pasha
1862; 0 0 ACL - public pasha
317; 1247 17715 TYPE public composite pasha
319; 1247 25899 DOMAIN public domain0 pasha
Les points virgules commencent un commentaire et les numros au dbut des lignes se rfrent l'ID d'archive interne affecte
chaque lment.
Les lignes dans le fichier peuvent tre commentes, supprimes et rordonnes. Par exemple :
10; 145433 TABLE map_resolutions postgres
;2; 145344 TABLE species postgres
;4; 145359 TABLE nt_header postgres
6; 145402 TABLE species_records postgres
;8; 145416 TABLE ss_old postgres
peut tre utilis en entre de pg_restore et ne restaure que les lments 10 et 6 dans cet ordre :
$ pg_restore -L mabase.liste mabase.fichier

Voir aussi
pg_dump(1), pg_dumpall(1), psql(1)

1178

Nom
psql terminal interactif PostgreSQL

Synopsis
psql [option...] [nombase [nomutilisateur]]

Description
psql est une interface en mode texte pour PostgreSQL. Il vous permet de saisir des requtes de faon interactive, de les excuter sur PostgreSQL et de voir les rsultats de ces requtes. Alternativement, les entres peuvent tres lues partir d'un fichier.
De plus, il fournit un certain nombre de mta-commandes et plusieurs fonctionnalits style shell pour faciliter l'criture des
scripts et automatiser un nombre vari de tches.

Options
-a, --echo-all
Affiche toutes les lignes en entre sur la sortie standard lorsqu'elles sont lues. Ceci est plus utile dans le traitement de scripts
que dans le mode interactif. C'est quivalent initialiser la variable ECHO all.
-A, --no-align
Bascule dans le mode d'affichage non align. (Le mode d'affichage par dfaut est align.)
-c commande, --command=commande
Indique que psql doit excuter une chane de commande, commande, puis s'arrter. Cette option est utile dans les scripts
shell. Les fichiers de dmarrage (psqlrc et ~/.psqlrc) sont ignors avec cette option.
commande doit tre soit une chane de commandes compltement analysable par le serveur (c'est--dire qui ne contient aucune des fonctionnalits spcifiques de psql), soit une seule commande antislash. Du coup, vous ne pouvez pas mixer les
commandes SQL et les mta-commandes psql avec cette option. Pour russir ceci, vous pouvez envoyer la chane dans un
tube vers psql, par exemple : echo "\x \\ SELECT * FROM foo;" | psql. (\\ est la mta-commande sparateur.)
Si la chane de commandes contient plusieurs commandes SQL, elles sont traites dans une seule transaction sauf si des
commandes BEGIN/COMMIT explicites sont inclues dans la chane pour la diviser en plusieurs transactions. Ceci est diffrent du comportement adopt quand la mme chane est envoye dans l'entre standard de psql. De plus, seul le rsultat de
la dernire commande SQL est renvoy.
cause de ces comportements historiques, placer plus d'une commande dans la chane fournie l'option -c a souvent des
rsultats inattendus. Il est prfrable de fournir plusieurs commandes sur l'entre standard de psql, soit en utilisant echo
comme illustr ci-dessus, soit avec un document shell en ligne, par exemple :
psql <<EOF
\x
SELECT * FROM foo;
EOF
-d nombase, --dbname=nombase
Indique le nom de la base de donnes o se connecter. Ceci est quivalent spcifier nombase comme premier argument
de la ligne de commande qui n'est pas une option.
Si ce paramtre contient un signe =, il est trait comme une chane conninfo. Voir Section 31.1, Fonctions de contrle
de connexion la base de donnes pour plus d'informations.
-e, --echo-queries
Copie toutes les commandes qui sont envoyes au serveur sur la sortie standard. Ceci est quivalent initialiser la variable
ECHO queries.
-E, --echo-hidden
Affiche les requtes relles gnres par \d et autres commandes antislash. Vous pouvez utiliser ceci pour tudier les oprations internes de psql. Ceci est quivalent initialiser la variable ECHO_HIDDEN dans psql.
-f nomfichier, --file=nomfichier
Utilise le fichier nomfichier comme source des commandes au lieu de lire les commandes de faon interactive. Une fois
1179

psql

que le fichier est entirement trait, psql se termine. Ceci est globalement quivalent la commande interne \i.
Si nomfichier est un - (tiret), alors l'entre standard est lue.
Utiliser cette option est lgrement diffrent d'crire psql < nomfichier. En gnral, les deux feront ce que vous souhaitez mais utiliser -f active certaines fonctionnalits intressantes comme les messages d'erreur avec les numros de ligne.
Il y a aussi une lgre chance qu'utiliser cette option rduira la surcharge du lancement. D'un autre ct, la variante utilisant la
redirection de l'entre du shell doit (en thorie) pour ramener exactement le mme affichage que celui que vous auriez eu en
saisissant tout manuellement.
-F sparateur, --field-separator=sparateur
Utilisez sparateur comme champ sparateur pour un affichage non align. Ceci est quivalent \pset fieldsep ou \f.
-h nomhte, --host=nomhte
Indique le nom d'hte de la machine sur lequel le serveur est en cours d'excution. Si la valeur commence avec un slash, elle
est utilise comme rpertoire du socket de domaine Unix.
-H, --html
Active l'affichage en tableau HTML. Ceci est quivalent \pset format html ou la commande \H.
-l, --list
Liste toutes les bases de donnes disponibles puis quitte. Les autres option non relatives la connexion sont ignores. Ceci est
similaire la commande interne \list.
-L nomfichier, --log-file=nomfichier
crit tous les rsultats des requtes dans le fichier nomfichier en plus de la destination habituelle.
-n, --no-readline
N'utilise pas readline pour l'dition de ligne et n'utilise pas l'historique. Ceci est utile quand on veut dsactiver la gestion de la
tabulation pour l'action copie/colle.
-o nomfichier, --output=nomfichier
Dirige tous les affichages de requtes dans le fichier nomfichier. Ceci est quivalent la commande \o.
-p port, --port=port
Indique le port TCP ou l'extension du fichier socket de domaine local Unix sur lequel le serveur attend les connexions. Par dfaut, il s'agit de la valeur de la variable d'environnement PGPORT ou, si elle n'est pas initialise, le port spcifi au moment de
la compilation, habituellement 5432.
-P affectation, --pset=affectation
Vous permet de spcifier les options d'affichage dans le style de \pset sur la ligne de commande. Notez que, ici, vous devez
sparer nom et valeur avec un signe gal au lieu d'un espace. Du coup, pour initialiser le format d'affichage en LaTeX, vous
devez crire -P format=latex.
-q, --quiet
Indique que psql doit travailler silencieusement. Par dfaut, il affiche des messages de bienvenue et des informations diverses.
Si cette option est utilise, rien de ceci n'est affich. C'est utile avec l'option -c. l'intrieur de psql, vous pouvez aussi initialiser la variable QUIET pour arriver au mme effet.
-R sparateur, --record-separator=sparateur
Utilisez sparateur comme sparateur d'enregistrement pour un affichage non align. Ceci est quivalent la commande
\pset recordsep.
-s, --single-step
S'excute en mode tape par tape. Ceci signifie qu'une intervention de l'utilisateur est ncessaire avant l'envoi de chaque
commande au serveur, avec une option pour annuler l'excution. Utilisez cette option pour dboguer des scripts.
-S, --single-line
S'excute en mode simple ligne o un retour la ligne termine une commande SQL, de la mme faon qu'un point-virgule.

Note
Ce mode est fourni pour ceux qui insistent pour l'avoir, mais vous n'tes pas ncessairement encourag
l'utiliser. En particulier, si vous mixez SQL et mta-commandes sur une ligne, l'ordre d'excution n'est pas toujours clair pour l'utilisateur non expriment.
-t, --tuples-only
Dsactive l'affichage des noms de colonnes et le pied de page contenant le nombre de rsultats, etc. Ceci est quivalent la
mta-commande \t.
1180

psql

-T options_table, --table-attr=options_table
Permet d'indiquer les options placer l'intrieur d'une balise table en HTML. Voir \pset pour plus de dtails.
-U nomutilisateur, --username=nomutilisateur
Se connecte la base de donnes en tant que l'utilisateur nomutilisateur au lieu de celui par dfaut. (Vous devez aussi
avoir le droit de le faire, bien sr.)
-v affectation, --set=affectation, --variable=affectation
Ralise une affectation de variable comme la commande interne \set. Notez que vous devez sparer nom et valeur par un
signe gal sur la ligne de commande. Pour dsinitialiser une variable, enlevez le signe d'galit. Pour simplement initialiser
une variable sans valeur, utilisez le signe gal sans passer de valeur. Ces affectations sont ralises lors de la toute premire
tape du lancement, du coup les variables rserves des buts internes peuvent tre crases plus tard.
-V, --version
Affiche la version de psql et quitte.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut tre
utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
Notez que cette option restera positionne pour l'ensemble de la session, et qu'elle affecte aussi l'utilisation de la mtacommande \connect en plus de la tentative de connexion initiale.
-W, --password
Force psql demander un mot de passe avant de se connecter une base de donnes.
Cette option n'est jamais obligatoire car psql demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, psql perdra une tentative de connexion pour trouver que le serveur veut un mot de passe.
Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.
Notez que cette option sera conserve pour la session entire, et que du coup elle affecte l'utilisation de la mta-commande
\connect ainsi que la tentative de connexion initiale.
-x, --expanded
Active le mode de formatage de table tendu. Ceci est quivalent la commande \x.
-X,, --no-psqlrc
Ne lit pas le fichier de dmarrage (ni le fichier systme psqlrc ni celui de l'utilisateur ~/.psqlrc).
-1, --single-transaction
Quand psql excute un script avec l'option -f, ajouter cette option englobe le script avec les instructions BEGIN/COMMIT
pour tout faire dans une seule transaction. Ceci nous assure que soit toutes les commandes se terminent avec succs, soit aucune modification n'est enregistre.
Si le script utilise lui-mme BEGIN, COMMIT ou ROLLBACK, cette option n'aura pas les effets dsirs. De plus, si le
script contient toute commande qui ne peut pas tre excute l'intrieur d'un bloc de transaction, indiquer cette option provoquera l'chec de cette commande (et du coup de la transaction entire).
-?, --help
Affiche de l'aide sur les arguments en ligne de commande de psql et quitte.

Code de sortie
psql renvoie 0 au shell s'il se termine normalement, 1 s'il y a eu une erreur fatale de son fait (pas assez de mmoire, fichier introuvable), 2 si la connexion au serveur s'est interrompue ou a t annule, 3 si une erreur est survenue dans un script et si la variable
ON_ERROR_STOP a t initialise.

Usage
Se connecter une base de donnes
psql est une application client PostgreSQL standard. Pour se connecter une base de donnes, vous devez connatre le nom de
votre base de donnes cible, le nom de l'hte et le numro de port du serveur ainsi que le nom de l'utilisateur que vous souhaitez
connecter. psql peut connatre ces paramtres partir d'options en ligne de commande, respectivement -d, -h, -p et -U. Si un argument autre qu'une option est rencontr, il est interprt comme le nom de la base de donnes (ou le nom de l'utilisateur si le nom
de la base de donnes est dj donn). Toutes les options ne sont pas requises, des valeurs par dfaut sont applicables. Si vous
omettez le nom de l'hte, psql se connecte via un socket de domaine Unix un serveur sur l'hte local ou via TCP/IP sur local1181

psql

host pour les machines qui n'ont pas sockets de domaine Unix. Le numro de port par dfaut est dtermin au moment de la
compilation. Comme le serveur de bases de donnes utilise la mme valeur par dfaut, vous n'aurez pas besoin de spcifier le port
dans la plupart des cas. Le nom de l'utilisateur par dfaut est votre nom d'utilisateur Unix, de mme pour le nom de la base de donnes par dfaut. Notez que vous ne pouvez pas simplement vous connecter n'importe quelle base de donnes avec n'importe quel
nom d'utilisateur. Votre administrateur de bases de donnes doit vous avoir inform de vos droits d'accs.
Quand les valeurs par dfaut ne sont pas correctes, vous pouvez vous simplifier la vie en configurant les variables
d'environnement PGDATABASE, PGHOST, PGPORT et/ou PGUSER avec les valeurs appropries (pour les variables
d'environnement supplmentaires, voir Section 31.13, Variables d'environnement ). Il est aussi intressant d'avoir un fichier
~/.pgpass pour viter d'avoir rgulirement saisir des mots de passe. Voir Section 31.14, Fichier de mots de passe pour
plus d'informations.
Une autre faon d'indiquer les paramtres de connexion est dans une chane conninfo qui est utilise la place du nom d'une
base de donnes. Ce mcanisme vous donne un grand contrle sur la connexion. Par exemple :
$ psql "service=monservice sslmode=require"
De cette faon, vous pouvez aussi utiliser LDAP pour la recherche de paramtres de connexion, comme dcrit dans Section 31.16,
Recherches LDAP des paramtres de connexion . Voir Section 31.1, Fonctions de contrle de connexion la base de donnes pour plus d'informations sur toutes les options de connexion disponibles.
Si la connexion ne peut pas se faire, quelle qu'en soit la raison (c'est--dire droits non suffisants, serveur arrt sur l'hte cible,
etc.), psql renvoie une erreur et s'arrte.
Si au moins l'une des entre ou sortie standard correspond un terminal, alors psql fixe le paramtre d'encodage client la valeur
auto , afin de pouvoir dtecter l'encodage appropri d'aprs les paramtres rgionaux (dfinis par la variable systme
LC_CTYPE pour les systmes Unix). Si cette mthode choue, il est possible de forcer l'encodage du client en renseignant la variable d'environnement PGCLIENTENCODING.

Saisir des commandes SQL


Dans le cas normal, psql fournit une invite avec le nom de la base de donnes sur laquelle psql est connect suivi par la chane =>.
Par exemple
$ psql basetest
psql (9.1.14)
Type "help" for help.
basetest=>
l'invite l'utilisateur peut saisir des commandes SQL. Ordinairement, les lignes en entre sont envoyes vers le serveur quand un
point-virgule de fin de commande est saisi. Une fin de ligne ne termine pas une commande. Du coup, les commandes peuvent tre
saisies sur plusieurs lignes pour plus de clart. Si la commande est envoye et excute sans erreur, les rsultats de la commande
sont affichs sur l'cran.
chaque fois qu'une commande est excute, psql vrifie aussi les vnements de notification gnrs par LISTEN(7) et NOTIFY(7).

Meta-commandes
Tout ce que vous saisissez dans psql qui commence par un antislash non chapp est une mta-commande psql qui est traite par
psql lui-mme. Ces commandes aident rendre psql plus utile pour l'administration ou pour l'criture de scripts. Les mtacommandes sont plus souvent appeles les commandes slash ou antislash.
Le format d'une commande psql est l'antislash suivi immdiatement d'un verbe de commande et de ses arguments. Les arguments
sont spars du verbe de la commande et les uns des autres par un nombre illimit d'espaces blancs.
Pour inclure des espaces blancs dans un argument, vous devez l'envelopper dans des guillemets simples. Pour inclure un guillemet
simple dans un argument, utilisez deux guillemets simples. Tout ce qui est contenu entre des guillemets simples est de plus sujet
des substitutions style C pour \n (nouvelle ligne), \t (tabulation), \chiffres (octal) et \xchiffres (hexadcimal).
Si un argument sans guillemets commence avec un caractre :, il est pris pour une variable psql et la valeur de la variable est utilise la place de l'argument.
Les arguments placs entre guillemets arrires (`) sont pris comme une ligne de commande passe au shell. L'affichage de la commande (sans l'ventuel saut de ligne la fin) est pris comme valeur de l'argument. Cela s'applique aussi aux squences
d'chappement ci-dessus.
Quelques commandes prennent un identifiant SQL (comme un nom de table) en argument. Ces arguments suivent les rgles de la
1182

psql

syntaxe SQL : les lettres sans guillemets sont forces en minuscule alors que les guillemets doubles (") protgent les lettres de la
conversion de casse et autorisent l'incorporation d'espaces blancs dans l'identifiant. l'intrieur des guillemets doubles, les guillemets doubles en paire se rduisent un seul guillemet double dans le nom rsultant. Par exemple, FOO"BAR"BAZ est interprt
comme fooBARbaz et "Un nom ""bizarre" devient Un nom "bizarre.
L'analyse des arguments se termine quand d'autres antislash non entre guillemets surviennent. Ceci est pris pour le dbut d'une
nouvelle mta-commande. La squence spciale \\ (deux antislashes) marque la fin des arguments et continue l'analyse des commandes SQL, si elles existent. De cette faon, les commandes SQL et psql peuvent tre mixes librement sur une ligne. Mais dans
tous les cas, les arguments d'une meta-commande ne peuvent pas continuer aprs la fin de la ligne.
Les meta-commandes suivantes sont dfinies :
\a
Si le format actuel d'affichage d'une table est non align, il est bascul align. S'il n'est pas non align, il devient non align.
Cette commande est conserve pour des raisons de compatibilit. Voir \pset pour une solution plus gnrale.
\c (ou \connect) [ nom_base [ nom_utilisateur ] [ hte ] [ port ] ]
tablie une nouvelle connexion un serveur PostgreSQL. Si la nouvelle connexion est russie, la connexion prcdente est
ferme. Si une option parmi nom_base, nom_utilisateur, hte et port est omise ou vaut -, la valeur de ce mme
paramtre de la connexion prcdente est utilise. S'il ny avait pas encore de connexion, la valeur par dfaut dans libpq est
utilise.
Si la tentative de connexion choue (mauvais nom d'utilisateur, accs refus, etc.), la connexion prcdente est conserve si
psql est en mode interactif. Lors de l'excution d'un script non interactif, le traitement s'arrtera immdiatement avec une erreur. Cette distinction a t choisie pour deux raisons : aider l'utilisateur face aux fautes de frappe et en tant que mesure de
prcaution pour qu'un script n'agisse pas par erreur sur la mauvaise base.
\C [ titre ]
Initialise ou supprime le titre des tables affiches en rsultat d'une requte. Cette commande est quivalente \pset title
titre. (Le nom de cette commande provient de caption , car elle avait prcdemment pour seul but d'initialiser l'en-tte
dans une table HTML.)
\cd [ rpertoire ]
Modifie le rpertoire courant par rpertoire. Sans argument, le rpertoire personnel de l'utilisateur devient le rpertoire
courant.

Astuce
Pour afficher votre rpertoire courant, utilisez \! pwd.
\conninfo
Outputs information about the current database connection.
\copy { table [ ( liste_colonnes ) ] | ( requte ) } { from | to } { nomfichier | stdin
| stdout | pstdin | pstdout } [ with ] [ binary ] [ oids ] [ delimiter [ as ] 'caractre' ] [ null [ as ] 'chane' ] [ csv [ header ] [ quote [ as ] 'caractre' ] [ escape
[ as ] 'caractre' ] [ force quote liste_colonnes ] [ force not null liste_colonnes ] ]
Ralise une opration de copy ct client. C'est une opration qui excute une commande SQL, COPY(7), mais au lieu que le
serveur lise ou crive le fichier spcifi, psql lit ou crit le fichier en faisant le routage des donnes entre le serveur et le systme de fichiers local. Ceci signifie que l'accs et les droits du fichier sont ceux de l'utilisateur local, pas celui du serveur, et
qu'aucun droit de superutilisateur n'est requis.
La syntaxe de la commande est similaire celle de la commande COPY(7) SQL. Notez que, cause de cela, des rgles spciales d'analyse s'appliquent la commande \copy. En particulier, les rgles de substitution de variable et d'chappement antislash ne s'appliquent pas.
\copy ... from stdin | to stdout lit/crit bas sur l'entre standard de la commande ou sa sortie standard respectivement. Toutes les lignes sont lues partir de la mme source qui a lanc la commande, en continuant jusqu' ce que \.
soit lu ou que le flux parvienne EOF. La sortie est envoye au mme endroit que la sortie de la commande. Pour lire/crire
partir de l'entre et de la sortie standard de psql, utilisez pstdin ou pstdout. Cette option est utile pour peupler des tables
en ligne l'intrieur d'un fichier script SQL.

Astuce
Cette opration n'est pas aussi efficace que la commande COPY en SQL parce que toutes les donnes doivent
passer au travers de la connexion client/serveur. Pour les grosses masses de donnes, la commande SQL est
1183

psql

prfrable.
\copyright
Affiche le copyright et les termes de distribution de PostgreSQL.
\d[S+] [ motif ]
Pour chaque relation (table, vue, index, squence ou table distante) ou type composite correspondant au motif, affiche
toutes les colonnes, leur types, le tablespace (s'il ne s'agit pas du tablespace par dfaut) et tout attribut spcial tel que NOT
NULL ou les valeurs par dfaut. Les index, contraintes, rgles et dclencheurs associs sont aussi affichs, ainsi que la dfinition de la vue si la relation est une vue. For foreign tables, the associated foreign server is shown as well. (Ce qui
Correspond au motif est dfini ci-dessous.)
Le forme de la commande \d+ est identique, sauf que des informations plus compltes sont affiches : tout commentaire associ avec les colonnes de la table est affich, ainsi que la prsence d'OID dans la table, la dfinition de la vue (si la relation
cible est une vue), ainsi que les options gnriques si la relation est une table distante.
Par dfaut, seuls les objets crs par les utilisateurs sont affichs ; fournissez un motif ou le modificateur S pour afficher les
objets systmes.

Note
Si \d est utilis sans argument motif, c'est quivalent, en plus commode, \dtvsE qui affiche une liste de
toutes les tables, vues, squences et tables distantes.
\da[S] [ motif ]
Liste toutes les fonctions d'agrgat disponibles, avec lee type de retour et les types de donnes sur lesquels elles oprent. Si
motif est spcifi, seuls les agrgats dont les noms commencent par le motif sont affichs. Par dfaut, seuls les objets crs
par les utilisateurs sont affichs ; fournissez un motif ou le modificateur S pour afficher les objets systmes.
\db[+] [ motif ]
Liste tous les tablespaces disponibles. Si motif est spcifi, seuls les tablespaces dont le nom correspond au motif sont affichs. Si + est ajout la fin de la commande, chaque objet est list avec les droits associs.
\dc[S] [ motif ]
Liste les conversions entre les encodages de jeux de caractres. Si motif est spcifi, seules les conversions dont le nom correspond au motif sont listes. Par dfaut, seuls les objets crs par les utilisateurs sont affichs ; fournissez un motif ou le modificateur S pour afficher les objets systmes.
\dC [ motif ]
Liste les conversions de types. Si motif est indiqu, seules sont affiches les conversions dont le type source ou cible correspond au motif.
\dd[S] [ motif ]
Affiche les descriptions des objets correspondant au motif ou de tous les objets si aucun argument n'est donn. Mais dans
tous les cas, seuls les objets qui ont une description sont lists. Par dfaut, seuls les objets crs par les utilisateurs sont affichs ; fournissez un motif ou le modificateur S pour afficher les objets systmes. Le terme objet couvre les agrgats, les
fonctions, les oprateurs, les types, les relations (tables, vues, index, squences, objets larges), les rgles et les dclencheurs.
Par exemple, :
=> \dd version
Object descriptions
Schema
| Name
| Object |
Description
------------+---------+----------+--------------------------pg_catalog | version | function | PostgreSQL version string
(1 row)
Les descriptions des objets peuvent tre ajoutes avec la commande SQL COMMENT(7).
\ddp [ motif ]
Liste les paramtres par dfaut pour les privilges d'accs. Une entre est affiche pour chaque rle (et schma, si c'est appropri) pour lequel les paramtres par dfaut des privilges ont t modifis par rapport aux paramtres par dfaut intgrs. Si
motif est spcifi, seules les entres dont le nom de rle ou le nom de schma correspond au motif sont listes.
La commande ALTER DEFAULT PRIVILEGES(7) sert positionner les privilges d'accs par dfaut. Le sens de l'affichage
des privilges est expliqu la page de GRANT(7).
\dD[S] [ motif ]
1184

psql

Liste les domaines. Si motif est spcifi, seuls les domaines dont le nom correspond au motif sont affichs. Par dfaut, seuls
les objets crs par les utilisateurs sont affichs ; fournissez un motif ou le modificateur S pour afficher les objets systmes.
\dE[S+] [ motif ], \di[S+] [ motif ], \ds[S+] [ motif ], \dt[S+] [ motif ], \dv[S+] [ motif
]
Dans ce groupe de commandes, les lettres E, i, s, t et v correspondent respectivement table distante, index, squence, table
et vue. Vous pouvez indiquer n'importe quelle combinaison de ces lettres, dans n'importe quel ordre, pour obtenir la liste de
tous les objets de ces types. Par exemple, \dit liste les index et tables. Si + est ajout la fin de la commande, chaque objet
est list avec sa taille physique sur disque et sa description associe s'il y en a une. Si motif est spcifi, seuls les objets dont
les noms correspondent au motif sont lists. Par dfaut, seuls les objets crs par les utilisateurs sont affichs ; fournissez un
motif ou le modificateur S pour afficher les objets systmes.
\det[+] [ motif ]
Liste les tables distantes (mnmotechnique : tables externes ). Si un motif est fourni, seules les entres concernant les
tables ou les schmas en correspondance seront listes. Si vous utilisez la forme \det+, les options gnriques seront galement affiches. Lists foreign tables (mnemonic: external tables ).
\des[+] [ motif ]
Liste les serveurs distants (mnmonique : external servers ). Si motif est spcifi, seuls les serveurs dont le nom correspond au motif sont affichs. Si la forme \des+ est utilise, une description complte de chaque serveur est affiche, incluant
la liste de contrle d'accs du serveur (ACL), type, version et options.
\deu[+] [ motif ]
Liste les correspondances d'utilisateurs (mnmonique : external users ). Si motif est spcifi, seules les correspondances
dont le nom correspond au motif sont affiches. Si la forme \deu+ est utilise, des informations supplmentaires sur chaque
correspondance d'utilisateur sont affiches.

Attention
\deu+ risque aussi d'afficher le nom et le mot de passe de l'utilisateur distant, il est donc important de faire attention ne pas les divulguer.
\dew[+] [ motif ]
Liste les wrappers de donnes distants (mnmonique : external wrappers ). Si motif est spcifi, seuls les wrappers dont
le nom correspond au motif sont affichs. Si la forme \dew+ est utilise, les ACL et options du wrapper sont aussi affiches.
\df[antwS+] [ motif ]
Liste les fonctions, ainsi que leurs arguments, types de retour, et types de fonctions, qui sont classs comme agg (agrgat),
normal , trigger , or window . Afin de n'afficher que les fonctions d'un type spcifi, ajoutez les lettres correspondantes, respectivement a, n, t, or w la commande. Si motif est spcifi, seules les fonctions dont le nom correspond au
motif sont affiches. Si la forme \df+ est utilise, des informations supplmentaires sur chaque fonction, dont la volatibilit,
le langage, le code source et la description, sont proposes. Par dfaut, seuls les objets crs par les utilisateurs sont affichs ;
fournissez un motif ou le modificateur S pour afficher les objets systmes.

Astuce
Pour rechercher des fonctions prenant des arguments ou des valeurs de retour d'un type spcifique, utilisez les
capacits de recherche du paginateur pour parcourir la sortie de \df.
\dF[+] [ motif ]
Liste les configurations de la recherche plein texte. Si motif est spcifi, seules les configurations dont le nom correspond
au motif seront affiches. Si la forme \dF+ est utilise, une description complte de chaque configuration est affiche, ceci
incluant l'analyseur de recherche plein texte et la liste de dictionnaire pour chaque type de jeton de l'analyseur.
\dFd[+] [ motif ]
Liste les dictionnaires de la recherche plein texte. Si motif est spcifi, seuls les dictionnaires dont le nom correspond au
motif seront affichs. Si la forme \dFd+ est utilise, des informations supplmentaires sont affiches pour chaque dictionnaire, ceci incluant le motif de recherche plein texte et les valeurs des options.
\dFp[+] [ motif ]
Liste les analyseurs de la recherche plein texte. Si motif est spcifi, seuls les analyseurs dont le nom correspond au motif
seront affichs. Si la forme \dFp+ est utilise, une description complte de chaque analyseur est affiche, ceci incluant les
fonctions sous-jacentes et les types de jeton reconnu.
\dFt[+] [ motif ]
Liste les motifs de la recherche plein texte. Si motif est spcifi, seuls les motifs dont le nom correspond au motif seront af1185

psql

fichs. Si la forme \dFt+ est utilise, des informations supplmentaires sont affiches pour chaque motif, ceci incluant les
noms des fonctions sous-jacentes.
\dg[+] [ motif ]
Liste les rles des bases de donnes. Si motif est spcifi, seuls les rles dont le nom correspond au motif sont lists. (Cette
commande est maintenant rellement identique \du.) Si la forme \dg+ est utilise, des informations supplmentaires sont
affiches pour chaque rle, par exemple le commentaire.
\dl
Ceci est un alias pour \lo_list, qui affiche une liste des objets larges.
\dL[S+] [ motif ]
Affiche les langages procduraux. Si un motif est spcifi, seuls les langages dont les noms correspondent au motif sont lists. Par dfaut, seuls les langages crs par les utilisateurs sont affichs ; il faut spcifier l'option S pour inclure les objets systmes. Si + est ajout la fin de la commande, chaque langage sera affich avec ses gestionnaire d'appels, validateur, droits
d'accs, et ce mme s'il s'agit d'un objet systme.
\dn[S+] [ motif ]
Liste les schmas. Si motif est spcifi, seuls les schmas dont le nom correspond au motif sont lists. Par dfaut, seuls les
objets crs par les utilisateurs sont affichs ; fournissez un motif ou le modificateur S pour afficher les objets systmes. Si +
est ajout la fin de la commande, chaque objet sera affich avec ses droits et son ventuelle description.
\do[S] [ motif ]
Liste les oprateurs avec leur oprande et type en retour. Si motif est spcifi, seuls les oprateurs dont le nom correspond
au motif sont lists. Par dfaut, seuls les objets crs par les utilisateurs sont affichs ; fournissez un motif ou le modificateur
S pour afficher les objets systmes.
\dO[S+] [ motif ]
Affiche les collationnements. Si motif est spcifi, seuls les collationnements dont le nom correspond au motif sont lists.
Par dfaut, seuls les objets crs par les utilisateurs sont affichs, fournissez un motif ou le modificateur S pour afficher les
objets systmes. Si + est ajout la fin de la commande, chacun des collationnements sera affich avec son ventuelle description. Notez que seuls les collationnements compatibles avec l'encodage de la base de donnes courante sont affichs, les
rsultats peuvent donc varier selon les diffrentes bases d'une mme instance.
\dp [ motif ]
Liste les tables, vues et squences avec leur droits d'accs associs. Si motif est spcifi, seules les tables, vues et squences
dont le nom correspond au motif sont listes.
Les commandes GRANT(7) et REVOKE(7) sont utilises pour configurer les droits d'accs. Les explications sur le sens de
l'affichage des privilges sont sous GRANT(7).
\drds [ role-pattern [ database-pattern ] ]
Liste les paramtres de configuration dfinis. Ces paramtres peuvent tre spcifiques un rle, spcifiques une base, ou les
deux. role-pattern et database-pattern servent choisir sur quels rles spcifiques ou quelles bases de donnes respectivement - les paramtres sont lists. Si ces options sont omises, ou si on spcifie *, tous les paramtres sont lists, y
compris ceux qui ne sont pas spcifiques un rle ou une base, respectivement.
Les commande ALTER ROLE(7) et ALTER DATABASE(7) servent dfinir les paramtres de configuration par rle et par
base de donnes.
\dT[S+] [ motif ]
Liste les types de donnes. Si motif est spcifi, seuls les types dont le nom correspond au motif sont affichs. Si + est ajout la fin de la commande, chaque type est list avec son nom interne et sa taille, ainsi que ses valeurs autorises si c'est un
type enum. Par dfaut, seuls les objets crs par les utilisateurs sont affichs ; fournissez un motif ou le modificateur S pour
afficher les objets systmes.
\du [ motif ]
Liste les rles de la base de donnes. Si motif est spcifi, seuls les rles dont le nom correspond au motif sont affichs. Si
la forme \du+ est utilise, des informations supplmentaires sont affiches pour chaque rle, par exemple le commentaire.
\dx[+] [ motif ]
Affiche les extensions installes. Si motif est spcifi, seules les entensions dont le nom correspond au motif sont affiches.
Avec la forme \dx+, tous les objets dpendants de chacune des extensions correspondantes sont galement lists.
\e (or \edit) [ nomfichier ] [ numero_ligne ]
Si nomfichier est spcifi, le fichier est dit ; en quittant l'diteur, son contenu est recopi dans le tampon de requte. Si
aucun paramtre nomfichier n'est fourni, le tampon de requte courant est copi dans un fichier temporaire et dit
l'identique.
Le nouveau tampon de requte est ensuite r-analys suivant les rgles habituelles de psql, o le tampon complet est trait
1186

psql

comme une seule ligne. (Du coup, vous ne pouvez pas faire de scripts de cette faon. Utilisez \i pour cela.) Ceci signifie que si
la requte se termine avec (ou contient) un point-virgule, elle est immdiatement excute. Dans les autres cas, elle attend
simplement dans le tampon de requte un point-virgule ou un \g pour l'envoyer, ou encore un \r pour annuler.
Si vous indiquez un numro de ligne, psql positionnera le curseur sur cette ligne du fichier ou du tampon de requte. Notez
que si un seul argument comportant uniquement des caractres numriques est fourni la commande, psql considre qu'il
s'agit d'un numro de ligne, et non pas un nom de fichier.

Astuce
Voir dans la section intitule Environnement la faon de configurer et personnaliser votre diteur.
\echo texte [ ... ]
Affiche les arguments sur la sortie standard spars par un espace et suivi par une nouvelle ligne. Ceci peut tre utile pour intgrer des informations sur la sortie des scripts. Par exemple :
=> \echo `date`
Tue Oct 26 21:40:57 CEST 1999
Si le premier argument est -n sans guillemets, alors la fin de ligne n'est pas crite.

Astuce
Si vous utilisez la commande \o pour rediriger la sortie de la requte, vous pourriez souhaiter utiliser \qecho au
lieu de cette commande.
\ef [ description_fonction [ line_number ] ]
Cette commande rcupre et dite la dfinition de la fonction dsigne au moyen d'une commande CREATE OR REPLACE FUNCTION. L'dition est faite de la mme faon que pour \edit. Aprs que l'diteur se soit ferm, la commande
mise jour attend dans le tampon de requte ; tapez ; ou \g pour l'envoyer, ou \r pour l'annuler.
La fonction cible peut tre spcifie par son nom seul, ou par son nom et ses arguments, par exemple foo(integer,
text). Les types d'arguments doivent tre fournis s'il y a plus d'une fonction du mme nom.
Si aucune fonction n'est spcifie, un modle d'ordre CREATE FUNCTION vierge est affich pour dition.
Si vous indiquez un numro de ligne, psql positionnera le curseur sur cette ligne dans le corps de la fonction. (Notez que le
corps de la fonction ne commence pas sur la premire ligne du fichier.)

Astuce
Voir dans la section intitule Environnement la faon de configurer et personnaliser votre diteur.
\encoding [ codage ]
Initialise l'encodage du jeu de caractres du client. Sans argument, cette commande affiche l'encodage actuel.
\f [ chane ]
Initialise le champ sparateur pour la sortie de requte non aligne. La valeur par dfaut est la barre verticale (|). Voir aussi
\pset comme moyen gnrique de configuration des options d'affichage.
\g [ { nomfichier | |commande } ]
Envoie le tampon de requte en entre vers le serveur et stocke en option la sortie de la requte dans nomfichier ou envoie
dans un tube la sortie vers un autre shell Unix excutant commande. Un simple \g est virtuellement quivalent un pointvirgule. Un \g avec argument est une alternative en un coup la commande \o.
\h (ou \help) [ commande ]
Donne la syntaxe sur la commande SQL spcifie. Si commande n'est pas spcifie, alors psql liste toutes les commandes
pour lesquelles une aide en ligne est disponible. Si commande est un astrisque (*), alors l'aide en ligne de toutes les commandes SQL est affiche.

Note
Pour simplifier la saisie, les commandes qui consistent en plusieurs mots n'ont pas besoin d'tre entre guillemets. Du coup, il est correct de saisir \help alter table.

1187

psql

\H
Active le format d'affichage HTML des requtes. Si le format HTML est dj activ, il est bascul au format d'affichage dfaut (texte align). Cette commande est pour la compatibilit mais voir \pset pour configurer les autres options d'affichage.
\i nomfichier
Lit l'entre partir du fichier nomfichier et l'excute comme si elle avait t saisie sur le clavier.

Note
Si vous voulez voir les lignes sur l'cran au moment de leur lecture, vous devez initialiser la variable ECHO
all.
\l (ou \list), \l+ (ou \list+)
Liste les noms, propritaires, encodage de jeux de caractres et droits d'accs de toutes les bases du serveur. Si + est ajout
la fin de la commande, la taille des bases, les tablespaces par dfaut et les descriptions sont aussi affiches. (Les tailles ne sont
disponibles que pour les bases auxquelles l'utilisateur courant a le droit de se connecter.)
\lo_export loid nomfichier
Lit l'objet large d'OID loid partir de la base de donnes et l'crit dans nomfichier. Notez que ceci est subtilement diffrent de la fonction serveur lo_export, qui agit avec les droits de l'utilisateur avec lequel est excut le serveur de base de
donnes et sur le systme de fichiers du serveur.

Astuce
Utilisez \lo_list pour trouver l'OID de l'objet large.
\lo_import nomfichier [ commentaire ]
Stocke le fichier dans un objet large PostgreSQL. En option, il associe le commentaire donn avec l'objet. Exemple :
foo=> \lo_import '/home/peter/pictures/photo.xcf' 'une
photo de moi'
lo_import 152801
La rponse indique que l'objet large a reu l'ID 152801, qui peut tre utilis pour accder de nouveau l'objet cr. Pour une
meilleure lisibilit, il est recommand de toujours associer un commentaire comprhensible par un humain avec chaque objet.
Les OID et les commentaires sont visibles avec la commande \lo_list.
Notez que cette commande est subtilement diffrente de la fonction serveur lo_import car elle agit en tant qu'utilisateur local sur le systme de fichier local plutt qu'en tant qu'utilisateur du serveur et de son systme de fichiers.
\lo_list
Affiche une liste de tous les objets larges PostgreSQL actuellement stocks dans la base de donnes, avec tous les commentaires fournis par eux.
\lo_unlink loid
Supprime l'objet large d'OID loid de la base de donnes.

Astuce
Utilisez \lo_list pour trouver l'OID d'un objet large.
\o [ {nomfichier | |commande} ]
Sauvegarde les rsultats des requtes suivantes dans le fichier nomfichier ou envoie via un tube les rsultats venir dans
un shell Unix spar pour excuter command. Si aucun argument n'est spcifi, l'affichage de la requte est redirig vers la
sortie standard.
Les rsultats de requte incluent toutes les tables, rponses de commande et messages d'avertissement obtenus du serveur
de bases de donnes, ainsi que la sortie de diffrentes commandes antislash qui envoient des requtes la base de donnes
(comme \d), mais sans message d'erreur.

Astuce
Pour intgrer du texte entre les rsultats de requte, utilisez \qecho.
\p
1188

psql

Affiche le tampon de requte actuel sur la sortie standard.


\password [ nom_utilisateur ]
Modifie le mot de passe de l'utilisateur indiqu (par dfaut, l'utilisateur en cours). Cette commande demande le nouveau mot
de passe, le chiffre et l'envoie au serveur avec la commande ALTER ROLE. Ceci vous assure que le nouveau mot de passe
n'apparat pas en clair dans l'historique de la commande, les traces du serveur ou encore ailleurs.
\prompt [ texte ] nom
Demande l'utilisateur la valeur pour la variable nom. Un affichage optionnel, texte, peut tre propos. (Pour des invites
plusieurs mots, utilisez les guillemets simples.)
Par dfaut, \prompt utilise le terminal pour les entres et sorties. Nanmoins, si la bascule -f est utilise, \prompt utilise
l'entre et la sortie standard.
\pset option [ valeur ]
Cette commande initialise les options affectant l'affichage des tables rsultat de la requte. option dcrit l'option initialiser. La smantique de valeur varie en fonction de l'option slectionne. Pour certaines options, omettre valeur a pour
consquence de basculer ou dsactiver l'option, tel que cela est dcrit pour chaque option. Si aucun comportement de ce type
n'est mentionn, alors omettre valeur occasionne simplement l'affichage de la configuration actuelle.
Les options ajustables d'affichage sont :
border
Le valeur doit tre un nombre. En gnral, plus grand est ce nombre, plus les tables ont de bordure et de ligne mais ceci dpend du format. Dans le mode HTML, ceci sera traduit directement avec l'attribut border=.... Avec les autres, seules les
valeurs 0 (sans bordure), 1 (lignes internes de division) et 2 (forme de table) ont un sens.
columns
Positionne la largeur pour le format wrapped , ainsi que la largeur partir de laquelle la sortie est suffisemment longue pour
ncessiter le pager. Si l'option est positionne zro (la valeur par dfaut), la largeur de la colonne est contrle soit par la variable d'environnement COLUMNS, soit par la largeur d'cran dtecte si COLUMNS n'est pas positionne. De plus, si columns vaut zero, alors le format wrapped affecte seulement la sortie cran. Si columns ne vaut pas zro, alors les sorties
fichier et tubes (pipe) font l'objet de retours la ligne cette largeur galement.
expanded (ou x)
Si le paramtre valeur est prcis, il peut valoir soit on soit off qui activera ou dsactivera le mode tendu. Si valeur
est omis, la commande bascule entre le mode normal et le mode tendu. Quand le mode tendu est activ, les rsultats d'une
requte sont affichs sur deux colonnes, avec le nom de la colonne dans la partie gauche et les donnes dans la partie droite.
Ce mode est utile si les donnes ne tiennent pas sur l'cran dans le mode normal, horizontal .
fieldsep
Indique le sparateur de champ utiliser dans le mode d'affichage non align. De cette faon, vous pouvez crer, par exemple,
une sortie spare par des tabulations ou des virgules, que d'autres programmes pourraient prfrer. Pour configurer une tabulation comme champ sparateur, saisissez \pset fieldsep '\t'. Le sparateur de champ par dfaut est '|' (une barre
verticale).
footer
Si le paramtre valeur est prcis, il doit valoir soit on, soit off, ce qui a pour effet d'activer ou de dsactiver l'affichage
du pied de table (le compte : (n rows)). Si le paramtre valeur est omis, la commande bascule entre l'affichage du pied
de table ou sa dsactivation.
format
Initialise le format d'affichage parmi unaligned, aligned, wrapped, html, latex ou troff-ms. Les abrviations
uniques sont autorises. (ce qui signifie qu'une lettre est suffisante.)
Le format unaligned crit toutes les colonnes d'un enregistrement sur une seule ligne, spares par le sparateur de champ
courant. Ceci est utile pour crer des sorties qui doivent tre lues par d'autres programmes (au format spar par des caractre tabulation ou par des virgules, par exemple).
Le format aligned est le format de sortie texte standard, lisible par les humains, joliement format ; c'est le format par dfaut.
Le format wrapped est comme aligned, sauf qu'il retourne la ligne dans les donnes de grande taille afin que la sortie
tienne dans la largeur de colonne cible. La largeur cible est dtermine comme cela est dcrit l'option columns. Notez que
psql n'essaie pas de revenir la ligne dans les titres de colonnes. Par consquent, si la largeur totale ncessaire pour le titre de
colonne est plus grande que la largeur cible, le format wrapped se comporte de la mme manire que aligned.
Les formats html, latex, and troff-ms produisent des tables destines tre inclues dans des documents utilisant le langage de marques respectif. Ce ne sont pas des documents complets ! (Ce n'est pas dramatique en HTML mais en LaTeX vous
devez avoir une structure de document complet.)
1189

psql

linestyle
Positionne le style des lignes de bordure sur ascii, old-ascii unicode. Les abrviations uniques sont autorises. (Cela
signifie qu'une lettre suffit.) La valeur par dfaut est ascii. Cette option affecte seulement les formats de sortie aligned et
wrapped.
Le style ascii utilise les caractres basiques ASCII . Les retours la ligne dans les donnes sont reprsents par un symbole
+ dans la marge de droite. Si le format wrapped est slectionn, un retour chariot est ajout l'affichage pour les valeurs
dont la taille l'affichage est trop importante pour tenir dans une cellule de la colonne associe. Un point (.) est affich dans
la marge droite de la ligne avant le retour chariot et un autre point est affich dans la marge gauche de la ligne suivante.
Le style old-ascii utilise des caractres basiques ASCII, utilisant le style de formatage utilis dans PostgreSQL 8.4 and
et les versions plus anciennes. Les retours la ligne dans les donnes sont reprsents par un symbole : la place du sparateur de colonnes plac gauche. Quand les donnes sont rparties sur plusieurs lignes sans qu'il y ait de caractre de retour
la ligne dans les donnes, un symbole ; est utilis la place du sparateur de colonne de gauche.
Le style unicode utilise les caractres Unicode de dessin de bote. Les retours la ligne dans les donnes sont reprsents
par un symbole de retour la ligne dans la marge de droite. Lorsque les donnes sont rparties sur plusieurs lignes, sans qu'il
y ait de caractre de retour la ligne dans les donnes, le symbole ellipse est affich dans la marge de droite de la premire
ligne, et galement dans la marge de gauche de la ligne suivante.
Quand le paramtre border vaut plus que zro, cette option dtermine galement les caractres utiliss pour dessiner les
lignes de bordure. Les simples caractres ASCII fonctionnent partout, mais les caractres Unicode sont plus jolis sur les affichages qui les reconnaissent.
null
Positionne la chane de caractres afficher la place d'une valeur null. Par dfaut, rien n'est affich, ce qui peut facilement
tre confondu avec une chane de caractres vide. Par exemple, vous pouvez prfrer afficher \pset null '(null)'.
numericlocale
Si valeur est prcise, elle doit valoir soit on, soit off afin d'activer ou dsactiver l'affichage d'un caractre dpendant de
la locale pour sparer des groupes de chiffres gauche du sparateur dcimal. Si valeur est omise, la commande bascule
entre la sortie numrique classique et celle spcifique la locale.
pager
Contrle l'utilisation d'un paginateur pour les requtes et les affichages de l'aide de psql. Si la variable d'environnement PAGER est configure, la sortie est envoye via un tube dans le programme spcifi. Sinon, une valeur par dfaut dpendant de
la plateforme (comme more) est utilise.
Quand l'option pager vaut off, le paginateur n'est pas utilis. Quand l'option pager vaut on, et que cela est appropri,
c'est dire quand la sortie est dirige vers an terminal, et ne tient pas dans l'cran, le paginateur est utilis. L'option pager
peut galement tre positionne always, ce qui a pour effet d'utiliser le paginateur pour toutes les sorties terminal, que ces
dernires tiennent ou non dans l'cran. \pset pager sans prciser valeur bascule entre les tats "paginateur activ" et
"paginateur dsactiv".
recordsep
Indique le sparateur d'enregistrement (ligne) utiliser dans le mode d'affichage non align. La valeur par dfaut est un caractre de retour chariot.
tableattr (or T)
Prcise les attributs qui seront placs l'intrieur des balises HTML table tag, dans le format de sortie html. Ceci pourrait
tre par exemple cellpadding ou bgcolor. Notez que vous ne voulez probablement pas spcifier border car c'est pris
en compte par \pset border. Si valeur n'est pas prcise, aucun attribut de table n'est positionn.
title [ texte ]
Initialise le titre de la table pour toutes les tables affiches ensuite. Ceci peut tre utilis pour ajouter des balises de description l'affichage. Si aucun valeur n'est donn, le titre n'est pas initialis.
tuples_only (ou t)
Si valeur est spcifie, elle doit valoir soit on, soit off, ce qui va activer ou dsactiver le mode "tuples seulement". Si valeur est omise, la commande bascule entre la sortie normale et la sortie "tuples seulement". La sortie normale comprend des
informations supplmentaires telles que les enttes de colonnes, les titres, et diffrents pieds. Dans le mode "tuples seulement", seules les donnes de la table sont affiches.
Des exemples d'utilisation de ces diffrents formats sont disponibles dans la section la section intitule Exemples .

Astuce
Il existe plusieurs raccourcis de commandes pour \pset. Voir \a, \C, \H, \t, \T et \x.
1190

psql

Note
C'est une erreur d'appeler \pset sans argument. Dans le futur, cet appel pourrait afficher le statut actuel de
toutes les options d'affichage.
\q ou \quit
Quitte le programme psql. Avec un script, seule l'excution du script est termine.
\qecho texte [ ... ]
Cette commande est identique \echo sauf que les affichages sont crits dans le canal d'affichage des requtes, configur par
\o.
\r
Rinitialise (efface) le tampon de requtes.
\s [ nomfichier ]
Affiche ou sauvegarde l'historique des lignes de commandes dans nomfichier. Si nomfichier est omis, l'historique est
crit sur la sortie standard. Cette option est seulement disponible si psql est configur pour utiliser la bibliothque GNU Readline.
\set [ nom [ valeur [ ... ]]]
Initialise la variable interne nom valeur ou, si plus d'une valeur est donne, la concatnation de toutes les valeurs. Si aucun second argument n'est donn, la variable est simplement initialise sans valeur. Pour dsinitialiser une variable, utilisez la
commande \unset.
Les noms de variables valides peuvent contenir des caractres, chiffres et tirets bas. Voir la section la section intitule
Variables ci-dessous pour les dtails. Les noms des variables sont sensibles la casse.
Bien que vous puissiez configurer toute variable comme vous le souhaitez, psql traite certaines variables de faon spciale.
Elles sont documentes dans la section sur les variables.

Note
Cette commande est totalement spare de la commande SQL SET(7).
\sf[+] description_fonction
Cette commande rcupre et affiche la dfinition d'une fonction sous la forme d'une commande CREATE OR REPLACE
FUNCTION. La dfinition est affiche via le canal de sortie courant, tel que dfini par \o.
La fonction cible peut tre spcifie par son seul nom, ou bien par ses nom et arguments, par exemple, foo(integer,
text). Fournir les types des arguments devient obligatoire si plusieurs fonctions portent le mme nom.
Si + est ajout la commande, les numros de lignes sont affichs, la ligne 1 dbutant partir du corps de la fonction.
\t
Bascule l'affichage des en-ttes de nom de colonne en sortie et celle du bas de page indiquant le nombre de lignes. Cette commande est quivalente \pset tuples_only et est fournie pour en faciliter l'accs.
\T options_table
Spcifie les attributs qui seront placs dans le tag table pour le format de sortie HTML. Cette commande est quivalente
\pset tableattr options_table.
\timing [ on | off ]
Sans paramtre, affiche le temps pris par chaque instruction SQL, en millisecondes, ou arrte cet affichage. Avec paramtre,
force la valeur au paramtre.
\w nomfichier, \w |commande
Place le tampon de requte en cours dans le fichier nomfichier ou l'envoie via un tube la commande Unix commande.
\x
Bascule le mode tendu de formatage en table. C'est quivalent \pset expanded.
\z [ motif ]
Liste les tables, vues et squences avec leur droit d'accs associ. Si un motif est spcifi, seules les tables, vues et squences dont le nom correspond au motif sont listes.
Ceci est un alias pour \dp ( affichage des droits ).
\! [ commande ]
1191

psql

Lance un shell Unix spar ou excute la commande Unix commande. Les arguments ne sont pas interprts, le shell les voit
tel quel.
\?
Affiche l'aide sur les commandes antislash.
motifs

Les diffrentes commandes \d acceptent un paramtre motif pour spcifier le(s) nom(s) d'objet afficher. Dans le cas le plus
simple, un motif est seulement le nom exact de l'objet. Les caractres l'intrieur du motif sont normalement mis en minuscule
comme pour les noms SQL ; par exemple, \dt FOO affichera la table nomme foo. Comme pour les noms SQL, placer des
guillemets doubles autour d'un motif empchera la mise en minuscule. Si vous devez inclure un guillemet double dans un motif,
crivez-le en double en accord avec les rgles sur les identifiants SQL. Par exemple, \dt "FOO""BAR" affichera la table nomme FOO"BAR (et non pas foo"bar). Contrairement aux rgles normales pour les noms SQL, vous pouvez placer des guillemets
doubles simplement autour d'une partie d'un motif, par exemple \dt FOO"FOO"BAR affichera la table nomme fooFOObar.
Lorsque le paramtre motif est compltement absent, la commande \d affiche tous les objets visibles dans le chemin de recherche courant -- cela est quivalent l'utilisation du motif *. (Un objet est dit visible si le schma qui le contient est dans le chemin de recherche et qu'aucun objet de mme type et mme nom n'apparat en priorit dans le chemin de recherche. Cela est quivalent dire que l'objet peut tre rfrenc par son nom sans prciser explicitement le schma.) Pour voir tous les objets de la base
quelle que soit leur visibilit, utilisez le motif *.* .
l'intrieur d'un motif, * correspond toute squence de caractres (et aussi aucun) alors que ? ne correspond qu' un seul caractre. (Cette notation est comparable celle des motifs de nom de fichier Unix.) Par exemple, \dt int* affiche les tables dont
le nom commence avec int. Mais l'intrieur de guillemets doubles, * et ? perdent leurs significations spciales et sont donc
traits directement.
Un motif qui contient un point (.) est interprt comme le motif d'un nom de schma suivi par celui d'un nom d'objet. Par
exemple, \dt foo*.*bar* affiche toutes les tables dont le nom inclut bar et qui sont dans des schmas dont le nom commence avec foo. Sans point, le motif correspond seulement avec les objets qui sont visibles dans le chemin de recherche actuel
des schmas. De nouveau, un point dans des guillemets doubles perd sa signification spciale et est trait directement.
Les utilisateurs avancs peuvent utiliser des expressions rationnelles comme par exemple les classes de caractre ([0-9] pour
tout chiffre). Tous les caractres spciaux d'expression rationnelle fonctionnent de la faon indique dans Section 9.7.3,
Expressions rationnelles POSIX , sauf pour le . qui est pris comme sparateur (voir ci-dessus), l'toile (*) qui est transforme
en l'expression rationnelle .* et ? qui est transforme en ., et $ qui est une correspondance littrale. Vous pouvez muler ces caractres si besoin en crivant ? pour ., (R+|) pour R* et (R|) pour R?. $ n'est pas ncessaire en tant que caractre d'une expression rationnelle car le motif doit correspondre au nom complet, contrairement l'interprtation habituelle des expressions rationnelles (en d'autres termes, $ est ajout automatiquement votre motif). crivez * au dbut et/ou la fin si vous ne souhaitez
pas que le motif soit ancr. Notez qu' l'intrieur de guillemets doubles, tous les caractres spciaux des expressions rationnelles
perdent leur signification spciale et sont traits directement. De plus, ces caractres sont traits littralement dans les motifs des
noms d'oprateurs (par exemple pour l'argument de \do).

Fonctionnalits avances
Variables

psql fournit des fonctionnalits de substitution de variable similaire aux shells de commandes Unix. Les variables sont simplement
des paires nom/valeur o la valeur peut tre toute chane, quel que soit sa longueur. Pour initialiser des variables, utilisez la mtacommande psql \set :
basetest=> \set foo bar
initialise la variable foo avec la valeur bar. Pour rcuprer le contenu de la variable, prcdez le nom avec un caractre deuxpoints. Vous pouvez l'utiliser comme argument de toute commande slash :
basetest=> \echo :foo
bar

Note
Les arguments de \set sont sujets aux mme rgles de substitution que les autres commandes. Du coup, vous pouvez construire des rfrences intressantes comme \set :foo 'quelquechose' et obtenir des liens doux
ou des variables de variables comme, respectivement, Perl ou PHP. Malheureusement (ou heureusement ?), on ne peut rien faire d'utile avec ces constructions. D'un autre ct, \set bar :foo est un moyen parfaitement valide de copier une variable.
1192

psql

Si vous appelez \set sans second argument, la variable est initialise avec une chane vide. Pour dsinitialiser (ou supprimer) une
variable, utilisez la commande \unset.
Les noms de variables internes de psql peuvent tre constitus de lettres, nombres et tirets bas dans n'importe quel ordre et autant
de fois que vous le voulez. Un certain nombre de ces variables sont traites spcialement par psql. Elles indiquent certaines options qui peuvent changer au moment de l'excution en modifiant la valeur de la variable ou reprsentent un certain tat de
l'application. Bien que vous puissiez utiliser ces variables dans n'importe quel but, ce n'est pas recommand car le comportement
du programme pourrait devenir trs rapidement vraiment trange. Par convention, toutes les variables traites spcialement sont
uniquement composes de lettres majuscules (et peut-tre aussi de chiffres et de tirets bas). Pour s'assurer d'une compatibilit
maximum dans le futur, vitez l'utilisation de tels noms de variables pour vos propres besoins. Une liste de toutes les variables
traites spcialement suit.
AUTOCOMMIT
Si actif (on, valeur par dfaut), chaque commande SQL est automatiquement valide si elle se termine avec succs. Pour suspendre la validation dans ce mode, vous devez saisir une commande SQL BEGIN ou START TRANSACTION. Lorsqu'elle
est dsactive (off) ou non initialise, les commandes SQL ne sont plus valides tant que vous ne lancez pas explicitement
COMMIT ou END. Le mode sans autocommit fonctionne en lanant implicitement un BEGIN, juste avant toute commande
qui n'est pas dj dans un bloc de transaction et qui n'est pas elle-mme un BEGIN ou une autre commande de contrle de
transaction, ou une commande qui ne peut pas tre excute l'intrieur d'un bloc de transaction (comme VACUUM).

Note
Dans le mode sans autocommit, vous devez annuler explicitement toute transaction choue en saisissant
ABORT ou ROLLBACK. Gardez aussi en tte que si vous sortez d'une session sans validation, votre travail
est perdu.

Note
Le mode auto-commit est le comportement traditionnel de PostgreSQL alors que le mode sans autocommit
est plus proche des spcifications SQL. Si vous prfrez sans autocommit, vous pouvez le configurer dans le
fichier psqlrc global du systme ou dans votre fichier ~/.psqlrc.
DBNAME
Le nom de la base de donnes laquelle vous tes actuellement connect. Ceci est configur chaque fois que vous vous
connectez une base de donnes (ainsi qu'au lancement du programme) mais peut tre dsinitialis.
ECHO
Si cette variable est initialise all, toutes les lignes saisies au clavier ou provenant d'un script sont crites sur la sortie standard avant d'tre analyses ou excutes. Pour slectionner ce comportement au lancement du programme, utilisez l'option
-a. Si ECHO vaut queries, psql affiche simplement toutes les requtes au moment de leur envoi au serveur. L'option pour
ceci est -e.
ECHO_HIDDEN
Quand cette variable est initialise et qu'une commande antislash est envoye la base de donnes, la requte est d'abord affiche. De cette faon, vous pouvez tudier le fonctionnement interne de PostgreSQL et fournir des fonctionnalits similaires
dans vos propres programmes. (Pour slectionner ce comportement au lancement du programme, utilisez l'option -E.) Si vous
configurez la variable avec la valeur noexec, les requtes sont juste affiches mais ne sont pas rellement envoyes au serveur ni excutes.
ENCODING
Le codage courant du jeu de caractres du client.
FETCH_COUNT
Si cette variable est un entier positif, les rsultats de la requte SELECT sont rcuprs et affichs en groupe de ce nombre de
lignes, plutt que par le comportement par dfaut (rcupration de l'ensemble complet des rsultats avant l'affichage). Du
coup, seule une petite quantit de mmoire est utilise, quelle que soit la taille de l'ensemble des rsultats. Une configuration
entre 100 et 1000 est habituellement utilise lors de l'activation de cette fonctionnalit. Gardez en tte que lors de l'utilisation
de cette fonctionnalit, une requte pourrait chouer aprs avoir affich quelques lignes.

Astuce
Bien que vous puissiez utiliser tout format de sortie avec cette fonctionnalit, le format par dfaut, aligned,
rend mal car chaque groupe de FETCH_COUNT lignes sera format sparment, modifiant ainsi les largeurs de
1193

psql

colonnes suivant les lignes du groupe. Les autres formats d'affichage fonctionnent mieux.
HISTCONTROL
Si cette variable est configure ignorespace, les lignes commenant avec un espace n'entrent pas dans la liste de
l'historique. Si elle est initialise avec la valeur ignoredups, les lignes correspondant aux prcdentes lignes de l'historique
n'entrent pas dans la liste. Une valeur de ignoreboth combine les deux options. Si elle n'est pas initialise ou si elle est
configure avec une autre valeur que celles-ci, toutes les lignes lues dans le mode interactif sont sauvegardes dans la liste de
l'historique.

Note
Cette fonctionnalit a t plagie sur Bash.
HISTFILE
Le nom du fichier utilis pour stocker l'historique. La valeur par dfaut est ~/.psql_history. Par exemple, utiliser :
\set HISTFILE ~/.psql_history- :DBNAME
dans ~/.psqlrc fera que psql maintiendra un historique spar pour chaque base de donnes.

Note
Cette fonctionnalit a t plagie sans honte partir de Bash.
HISTSIZE
Le nombre de commandes stocker dans l'historique des commandes. La valeur par dfaut est 500.

Note
Cette fonctionnalit a t plagie sur Bash.
HOST
L'hte du serveur de la base de donnes o vous tes actuellement connect. Ceci est configur chaque fois que vous vous
connectez une base de donnes (ainsi qu'au lancement du programme) mais peut tre dsinitialis.
IGNOREEOF
Si non initialis, envoyer un caractre EOF (habituellement Ctrl+D) dans une session interactive de psql ferme l'application.
Si elle est configure avec une valeur numrique, ce nombre de caractres EOF est ignor avant la fin de l'application. Si la
variable est configure mais n'a pas de valeur numrique, la valeur par dfaut est de 10.

Note
Cette fonctionnalit a t plagie sur Bash.
LASTOID
La valeur du dernier OID affect, renvoye partir d'une commande INSERT ou lo_import. La validit de cette variable est
seulement garantie jusqu' l'affichage du rsultat de la commande SQL suivante.
ON_ERROR_ROLLBACK
Lorsqu'il est actif (on), si une instruction d'un bloc de transaction gnre une erreur, cette dernire est ignore et la transaction
continue. Lorsqu'il vaut interactive, ces erreurs sont seulement ignores lors des sessions interactives, mais ne le sont
pas lors de la lecture de scripts. Lorsqu'il vaut off (valeur par dfaut), une instruction gnrant une erreur dans un bloc de
transaction annule la transaction complte. Le mode on_error_rollback-on fonctionne en excutant un SAVEPOINT implicite pour vous, juste avant chaque commande se trouvant dans un bloc de transaction et annule jusqu'au dernier point de sauvegarde en cas d'erreur.
ON_ERROR_STOP
Par dfaut, le traitement des commandes continue aprs une erreur. Quand cette variable est positionne, le traitement sera
immdiatement arrt ds la premire erreur rencontre. Dans le mode interactif, psql reviendra l'invite de commande. Sinon psql quittera en renvoyant le code d'erreur 3 pour distinguer ce cas des conditions d'erreurs fatales, qui utilisent le code 1.
Dans tous les cas, tout script en cours d'excution (le script de haut niveau et tout autre script qui pourrait avoir t appel) sera termin immdiatement. Si la chane de commande de haut niveau contient plusieurs commandes SQL, le traitement
s'arrtera la commande en cours.
1194

psql

PORT
Le port du serveur de la base de donnes sur lequel vous tes actuellement connect. Ceci est configur chaque fois que
vous vous connectez une base de donnes (ainsi qu'au lancement du programme) mais peut tre dsinitialis.
PROMPT1, PROMPT2, PROMPT3
Ils spcifient quoi doit ressembler l'invite psql. Voir la section intitule Invite ci-dessous.
QUIET
Cette variable est quivalente l'option -q en ligne de commande. Elle n'est probablement pas trs utile en mode interactif.
SINGLELINE
Cette variable est quivalente l'option -S en ligne de commande.
SINGLESTEP
Cette variable est quivalente l'option -s en ligne de commande.
USER
L'utilisateur de la base de donnes o vous tes actuellement connect. Ceci est configur chaque fois que vous vous
connectez une base de donnes (ainsi qu'au lancement du programme) mais peut tre dsinitialis.
VERBOSITY
Cette variable peut tre configure avec les valeurs default, verbose (bavard) ou terse (succinct) pour contrler la
verbosit des rapports d'erreurs.
Interpolation SQL

Une fonctionnalit utile supplmentaire des variables psql est que vous pouvez les substituer ( interpoler ) dans les instructions
SQL standards. psql offre des fonctionalits spciales pour garantir que les valeurs utilises comme chanes SQL litrales ou
comme identifiants sont correctement chappes. La syntaxe pour interpoler une valeur sans chappement spcial est de nouveau
de prcder le nom de la variable avec un caractre deux-points (:) :
basetest=> \set foo 'ma_table'
basetest=> SELECT * FROM :foo;
envoie alors la requte pour la table ma_table. Notez que cela peut tre dangereux ; la valeur de la variable est copie de faon
litrale, elle peut mme contenir des guillemets non ferms, ou bien des commandes backslash. Vous devez vous assurer que cela
a du sens l'endroit o vous les utilisez.
Lorsqu'une valeur doit tre utilise comme une chane SQL litrale ou un identifiant, il est plus sr de s'arranger pour qu'elle soit
chappe. Afin d'chapper la valeur d'une variable en tant que chane SQL litrale, crivez un caractre deux-points, suivi du nom
de la variable entour par des guillemets simples. Pour chapper la valeur en tant qu'identifiant SQL, crivez un caractre deuxpoints suivi du nom de la valeur entour de guillemets doubles. L'exemple prcdent peut s'crire de faon plus sre ainsi :
testdb=> \set foo 'my_table'
testdb=> SELECT * FROM :"foo";
L'interpolation de variable n'est pas effectue dans les entits SQL entoures de guillemets. SQL
Une utilisation possible de ce mcanisme est de copier le contenu d'un fichier dans une colonne d'une table. Tout d'abord, chargez
le fichier dans une variable puis procdez ainsi :
basetest=> \set contenu `cat mon_fichier.txt`
basetest=> INSERT INTO ma_table VALUES (:'contenu');
(Notez que cela ne fonctionnera par si le fichier mon_fichier.txt contient des octets nuls. psql ne gre pas les octets nuls inclus dans les valeurs de variable.)
Comme les caractres deux-points peuvent lgitimement apparatre dans les commandes SQL, une tentative apparente
d'interpolation (comme :nom, :'nom', or :"nom") n'est pas modifie, sauf si la variable nomme est actuellement positionne.
Dans tous les cas, vous pouvez chapper un caractre deux-points avec un backslash pour le protger des substitutions. (La syntaxe deux-points pour les variables est du SQL standard pour les langages de requte embarqus, comme ECPG. La syntaxe avec
les deux-points pour les tranches de tableau et les conversions de types sont des extensions PostgreSQL extensions, d'o le
conflit. La syntaxe avec le caractre deux-points pour chapper la valeur d'une variable en tant que chane SQL litrale ou identifiant est une extension psql .)
Invite

Les invites psql peuvent tre personnalises suivant vos prfrences. Les trois variables PROMPT1, PROMPT2 et PROMPT3
contiennent des chanes et des squences d'chappement spciales dcrivant l'apparence de l'invite. L'invite 1 est l'invite normale
1195

psql

qui est lance quand psql rclame une nouvelle commande. L'invite 2 est lance lorsqu'une saisie supplmentaire est attendue lors
de la saisie de la commande parce que la commande n'a pas t termine avec un point-virgule ou parce qu'un guillemet n'a pas t
ferm. L'invite 3 est lance lorsque vous excutez une commande SQL COPY et que vous devez saisir les valeurs des lignes sur le
terminal.
La valeur de la variable prompt slectionne est affiche littralement sauf si un signe pourcentage (%) est rencontr. Suivant le
prochain caractre, certains autres textes sont substitus. Les substitutions dfinies sont :
%M
Le nom complet de l'hte (avec le nom du domaine) du serveur de la base de donnes ou [local] si la connexion est tablie
via une socket de domaine Unix ou [local:/rpertoire/nom], si la socket de domaine Unix n'est pas dans
l'emplacement par dfaut dfini la compilation.
%m
Le nom de l'hte du serveur de la base de donnes, tronqu au premier point ou [local] si la connexion se fait via une socket de domaine Unix.
%>
Le numro de port sur lequel le serveur de la base de donnes coute.
%n
Le nom d'utilisateur de la session. (L'expansion de cette valeur peut changer pendant une session aprs une commande SET
SESSION AUTHORIZATION.)
%/
Le nom de la base de donnes courante.
%~
Comme %/ mais l'affichage est un ~ (tilde) si la base de donnes est votre base de donnes par dfaut.
%#
Si l'utilisateur de la session est un superutilisateur, alors un # sinon un >. (L'expansion de cette valeur peut changer durant une
session aprs une commande SET SESSION AUTHORIZATION.)
%R
Pour l'invite 1, affiche normalement = mais affiche ^ si on est en mode simple ligne et ! si la session est dconnecte de la
base de donnes (ce qui peut arriver si \connect choue). Pour l'invite 2, la squence est remplace par -, *, un simple guillemet, un double ou un signe dollar, suivant si psql attend une saisie supplmentaire parce que la commande n'est pas termine,
parce que vous tes l'intrieur d'un commentaire /* ... */, ou parce que vous n'avez pas termin un guillemet ou une
chane chappe avec des dollars. Pour l'invite 3, la squence ne produit rien.
%x
tat de la Transaction : une chane vide lorsque vous n'tes pas dans un bloc de transaction ou * si vous vous y trouvez, ou !
si vous tes dans une transaction choue, ou enfin ? lorsque l'tat de la transaction est indtermin (par exemple cause
d'une rupture de la connexion).
%chiffres
Le caractre avec ce code numrique est substitu.
%:nom:
La valeur de la variable nom de psql. Voir la section la section intitule Variables pour les dtails.
%`commande`
la sortie de la commande, similaire la substitution par guillemets inverse classique.
%[ ... %]
Les invites peuvent contenir des caractres de contrle du terminal qui, par exemple, modifient la couleur, le fond ou le style
du texte de l'invite, ou modifient le titre de la fentre du terminal. Pour que les fonctionnalits d'dition de ligne de Readline
fonctionnent correctement, les caractres de contrle non affichables doivent tre indiqus comme invisibles en les entourant
avec %[ et %]. Des pairs multiples de ceux-ci pourraient survenir l'intrieur de l'invite. Par exemple :
basetest=> \set PROMPT1 '%[%033[1;33;40m%]%n@%/%R%[%033[0m%]%# '
a pour rsultat une invite en gras (1;), jaune sur noir (33;40) sur les terminaux compatibles VT100.
Pour insrer un pourcentage dans votre invite, crivez %%. Les invites par dfaut sont '%/%R%# ' pour les invites 1 et 2 et '>>
' pour l'invite 3.

Note
1196

psql

Cette fonctionnalit a t plagie sur tcsh.


dition de la ligne de commande

psql supporte la bibliothque Readline pour une dition et une recherche simplifie et conviviale de la ligne de commande.
L'historique des commandes est automatiquement sauvegard lorsque psql quitte et est recharg quand psql est lanc. La compltion par tabulation est aussi supporte bien que la logique de compltion n'ait pas la prtention d'tre un analyseur SQL. Si pour
quelques raisons que ce soit, vous n'aimez pas la compltion par tabulation, vous pouvez la dsactiver en plaant ceci dans un fichier nomm .inputrc de votre rpertoire personnel :
$if psql
set disable-completion on
$endif
(Ceci n'est pas une fonctionnalit psql mais Readline. Lisez sa documentation pour plus de dtails.)

Environnement
COLUMNS
Si \pset columns vaut zro, contrle la largeur pour le format wrapped et la largeur pour dterminer si une sortie large
a besoin du pager.
PAGER
Si les rsultats d'une requte ne tiennent pas sur l'cran, ils sont envoys via un tube sur cette commande. Les valeurs typiques
sont more ou less. La valeur par dfaut dpend de la plateforme. L'utilisation du paginateur peut tre dsactive en utilisant
la commande \pset.
PGDATABASE, PGHOST, PGPORT, PGUSER
Paramtres de connexion par dfaut (voir Section 31.13, Variables d'environnement ).
PSQL_EDITOR, EDITOR, VISUAL
diteur utilis par les commandes \e et \ef. Les variables sont examines dans l'ordre donn ; la premire initialise est utilise.
Les diteurs intgrs par dfaut sont vi sur les systmes Unix et notepad.exe sur les systmes Windows.
PSQL_EDITOR_LINENUMBER_ARG
Lorsque les commandes \e ou \ef sont utilises avec un argument spcifiant le numro de ligne, cette variable doit indiquer
l'argument en ligne de commande fournir l'diteur de texte. Pour les diteurs les plus courants, tels qu'emacs ou vi,
vous pouvez simplement initialiser cette variable avec le signe +. Il faut inclure le caractre d'espacement en fin de la valeur
de la variable si la syntaxe de l'diteur ncessite un espace entre l'option spcifier et le numro de ligne. Par exemple :
PSQL_EDITOR_LINENUMBER_ARG='+'
PSQL_EDITOR_LINENUMBER_ARG='--line '
La valeur par dfaut est + sur les systmes Unix (ce qui correspond la bonne configuration pour l'diteur par dfaut, vi, et
est utilisable gnralement avec la plupart des diteurs courants) ; par contre, il n'y a pas de valeur par dfaut pour les systmes Windows.
SHELL
Commande excute par la commande \!.
TMPDIR
Rpertoire pour stocker des fichiers temporaires. La valeur par dfaut est /tmp.
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Fichiers

Sauf si une option -X ou -c est fournie, psql tente de lire et excuter les commandes provenant du fichier global au systme
psqlrc ou du fichier utilisateur ~/.psqlrc avant de dmarrer. (Sur Windows, le fichier de dmarrage de l'utilisateur est
nomm %APPDATA%\postgresql\psqlrc.conf.) Voir PREFIX/share/psqlrc.sample pour plus
d'informations sur la configuration du fichier global au systme. Il pourrait tre utilis pour configurer le client et le serveur
votre got (en utilisant les commandes \set et SET).
1197

psql

la fois le fichier psqlrc global au systme et le fichier ~/.psqlrc de l'utilisateur peuvent tre crs en tant spcifiques
une version si vous leur ajouter un tiret et le numro de version de ~/.psqlrc-9.1.14. Un fichier correspondant une
version spcifique est prfr un fichier sans indication de version.

L'historique de la ligne de commandes est stock dans le fichier ~/.psql_history ou


%APPDATA%\postgresql\psql_history sur Windows.

Notes

Dans une vie prcdente, psql permettait au premier argument d'une commande antislash une seule lettre de commencer directement aprs la commande, sans espace sparateur. partir de PostgreSQL 8.4, ce n'est plus autoris.

Le fonctionnement de psql n'est garanti qu'avec des serveurs de mme version. Cela ne signifie pas que d'autres combinaisons
vont compltement chouer, mais des problmes subtils, voire moins subtils, pourraient apparatre. Les mta-commandes sont
particulirements fragiles si le serveur est d'une version plus rcente que psql lui-mme. Toutefois, les commandes backslash
de la famille \d devraient fonctionner avec des serveurs 7.4 jusqu' la version courante, mme si pas ncessairement avec des
serveurs plus rcents que psql lui-mme.

Notes pour les utilisateurs sous Windows


psql est construit comme une application de type console . Comme les fentres console de windows utilisent un codage diffrent du reste du systme, vous devez avoir une attention particulire lors de l'utilisation de caractres sur 8 bits l'intrieur de psql.
Si psql dtecte une page de code problmatique, il vous avertira au lancement. Pour modifier la page de code de la console, deux
tapes sont ncessaires :

Configurez la page code en saisissant cmd.exe /c chcp 1252. (1252 est une page code approprie pour l'Allemagne ;
remplacez-la par votre valeur.) Si vous utilisez Cygwin, vous pouvez placer cette commande dans /etc/profile.

Configurez la police de la console par Lucida Console parce que la police raster ne fonctionne pas avec la page de code
ANSI.

Exemples
Le premier exemple montre comment envoyer une commande sur plusieurs lignes d'entre. Notez le changement de l'invite :
basetest=> CREATE TABLE ma_table (
basetest(> premier integer not NULL default 0,
basetest(> second text)
basetest-> ;
CREATE TABLE
Maintenant, regardons la dfinition de la table :
basetest=> \d ma_table
Table "ma_table"
Attribute | Type
|
Modifier
-----------+---------+-------------------premier
| integer | not null default 0
second
| text
|
Maintenant, changeons l'invite par quelque chose de plus intressant :
basetest=> \set PROMPT1 '%n@%m %~%R%# '
peter@localhost basetest=>
Supposons que nous avons rempli la table de donnes et que nous voulons les regarder :
peter@localhost basetest=> SELECT * FROM ma_table;
premier | second
---------+-------1 | one
2 | two
3 | three
4 | four
(4 rows)

1198

psql

Vous pouvez afficher cette table de faon diffrente en utilisant la commande \pset :
peter@localhost basetest=> \pset border 2
Border style is 2.
peter@localhost basetest=> SELECT * FROM ma_table;
+---------+--------+
| premier | second |
+---------+--------+
|
1 | one
|
|
2 | two
|
|
3 | three |
|
4 | four
|
+---------+--------+
(4 rows)
peter@localhost basetest=> \pset border 0
Border style is 0.
peter@localhost basetest=> SELECT * FROM ma_table;
premier second
------- -----1 one
2 two
3 three
4 four
(4 rows)
peter@localhost basetest=> \pset border 1
Border style is 1.
peter@localhost basetest=> \pset format unaligned
Output format is unaligned.
peter@localhost basetest=> \pset fieldsep ","
Field separator is ",".
peter@localhost basetest=> \pset tuples_only
Showing only tuples.
peter@localhost basetest=> SELECT second, first FROM
ma_table;
one,1
two,2
three,3
four,4
Vous pouvez aussi utiliser les commandes courtes :
peter@localhost basetest=> \a \t \x
Output format is aligned.
Tuples only is off.
Expanded display is on.
peter@localhost basetest=> SELECT * FROM ma_table;
-[ RECORD 1 ]first | 1
second | one
-[ RECORD 2 ]first | 2
second | two
-[ RECORD 3 ]first | 3
second | three
-[ RECORD 4 ]first | 4
second | four

1199

Nom
reindexdb reindexe une base de donnes PostgreSQL

Synopsis
reindexdb [option-connexion...] [--table | -t table ] [--index | -i index ] [nombase]
reindexdb [option-connexion...] [--all | -a]
reindexdb [option-connexion...] [--system | -s] [nombase]

Description
reindexdb permet de reconstruire les index d'une base de donnes PostgreSQL.
reindexdb est un enrobage de la commande REINDEX(7). Il n'y a pas de diffrence entre la rindexation des bases de donnes
par cette mthode et par celles utilisant d'autres mthodes d'accs au serveur.

Options
reindexdb accepte les arguments suivants en ligne de commande :
-a, --all
Rindexe toutes les bases de donnes.
[-d] base, [--dbname=]base
Spcifie le nom de la base rindexer. Si cette option n'est pas prsente et que l'option -a (ou --all) n'est pas utilise, le
nom de la base est lu partir de la variable d'environnement PGDATABASE. Si elle n'est pas configure, le nom de
l'utilisateur pour la connexion est utili.
-e, --echo
Affiche les commandes que reindexdb gnre et envoie au serveur.
-i index, --index=index
Ne recre que l'index index.
-q, --quiet
N'affiche pas la progression.
-s, --system
Rindexe les catalogues systme de la base de donnes.
-t table, --table=table
Ne rindexe que la table table.
-V, --version
Affiche la version de reindexdb, puis quitte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de reindexdb, puis quitte.
reindexdb accepte aussi les arguments suivants en ligne de commande pour les paramtres de connexion :
-h hte, --host=hte
Prcise le nom d'hte de la machine hbergeant le serveur. Si cette valeur dbute par une barre oblique ('/' ou slash), elle est
utilise comme rpertoire de socket UNIX.
-p port, --port=port
Prcise le port TCP ou le fichier de socket UNIX d'coute.
-U nom_utilisateur, --username=nom_utilisateur
Nom de l'utilisateur utiliser pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut
tre utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
1200

reindexdb

-W, --password
Force reindexdb demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais obligatoire car reindexdb demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, reindexdb perdra une tentative de connexion pour trouver que le serveur veut un
mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.

Environnement
PGDATABASE, PGHOST, PGPORT, PGUSER
Paramtres par dfaut pour la connexion
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
En cas de difficults, il peut tre utile de consulter REINDEX(7) et psql(1), sections prsentant les problmes ventuels et les messages d'erreur.
Le serveur de base de donnes doit fonctionner sur le serveur cible. Les paramtres de connexion ventuels et les variables
d'environnement utiliss par la bibliothque cliente libpq s'appliquent.

Notes
reindexdb peut avoir besoin de se connecter plusieurs fois au serveur PostgreSQL. Afin d'viter de saisir le mot de passe
chaque fois, on peut utiliser un fichier ~/.pgpass. Voir Section 31.14, Fichier de mots de passe pour plus d'informations.

Exemples
Pour rindexer la base de donnes test :
$ reindexdb test
Pour rindexer la table foo et l'index bar dans une base de donnes nomme abcd :
$ reindexdb --table foo --index bar abcd

Voir aussi
REINDEX(7)

1201

Nom
vacuumdb rcupre l'espace inutilis et, optionnellement, analyse une base de donnes PostgreSQL

Synopsis
vacuumdb [option-de-connexion...] [[--full] | [-f]] [[--freeze] | [-F]] [[--verbose] | [-v]] [[--analyze] | [-z]]
[[--analyze-only] | [-Z]] [--table | -t table [( colonne [,...] )] ] [base-de-donnees]
vacuumdb [options-de-connexion...] [[--full] | [-f]] [[--freeze] | [-F]] [[--verbose] | [-v]] [[--analyze] | [-z]]
[[--analyze-only] | [-Z]] [[--all] | [-a]]

Description
vacuumdb est un outil de nettoyage d'une base de donnes. vacuumdb peut galement engendrer des statistiques internes utilises par l'optimiseur de requtes de PostgreSQL.
vacuumdb est une surcouche de la commande VACUUM(7). Il n'y a pas de diffrence relle entre excuter des VACUUM et
des ANALYZE sur les bases de donnes via cet outil et via d'autres mthodes pour accder au serveur.

Options
vacuumdb accepte les arguments suivants sur la ligne de commande :
-a, --all
Nettoie toutes les bases de donnes.
[-d] base-de-donnees, [--dbname=]base-de-donnees
Indique le nom de la base de donnes nettoyer ou analyser. Si aucun nom n'est pas prcis et si -a (ou --all) n'est pas
utilis, le nom de la base de donnes est rcupr dans la variable d'environnement PGDATABASE. Si cette variable n'est
pas initialise, c'est le nom d'utilisateur prcis pour la connexion qui est utilis.
-e, --echo
Affiche les commandes que vacuumdb engendre et envoie au serveur.
-f, --full
Excute un nettoyage complet .
-F, --freeze
Gle agressivement les lignes.
-q, --quiet
N'affiche pas de message de progression.
-t table [ (colonne [,...]) ], --table=table [ (colonne [,...]) ]
Ne nettoie ou n'analyse que la table table. Des noms de colonnes peuvent tre prciss en conjonction avec les options -analyze ou --analyze-only.

Astuce
Lorsque des colonnes sont indiques, il peut tre ncessaire d'chapper les parenthses. (Voir les exemples
plus bas.)
-v, --verbose
Affiche des informations dtailles durant le traitement.
-V, --version
Affiche la version de vacuumdb, puis quitte.
-z, --analyze
Calcule aussi les statistiques utilises par le planificateur.
-Z, --analyze-only
Calcule seulement les statistiques utilises par le planificateur (donc pas de VACUUM).
-?, --help
Affiche l'aide sur les arguments en ligne de commande de vacuumdb, puis quitte.
1202

vacuumdb

vacuumdb accepte aussi les arguments suivants comme paramtres de connexion :


-h hte, --host=hte
Indique le nom d'hte de la machine qui hberge le serveur de bases de donnes. Si la valeur commence par une barre oblique
(/), elle est utilise comme rpertoire pour la socket de domaine Unix.
-p port, --port=port
Indique le port TCP ou le fichier local de socket de domaine Unix sur lequel le serveur attend les connexions.
-U utilisateur, --username=utilisateur
Nom d'utilisateur pour la connexion.
-w, --no-password
Ne demande jamais un mot de passe. Si le serveur en rclame un pour l'authentification et qu'un mot de passe n'est pas disponible d'une autre faon (par exemple avec le fichier .pgpass), la tentative de connexion chouera. Cette option peut tre
utile pour les scripts o aucun utilisateur n'est prsent pour saisir un mot de passe.
-W, --password
Force vacuumdb demander un mot de passe avant la connexion une base de donnes.
Cette option n'est jamais obligatoire car vacuumdb demandera automatiquement un mot de passe si le serveur exige une authentification par mot de passe. Nanmoins, vacuumdb perdra une tentative de connexion pour trouver que le serveur veut un
mot de passe. Dans certains cas, il est prfrable d'ajouter l'option -W pour viter la tentative de connexion.

Environnement
PGDATABASE, PGHOST, PGPORT, PGUSER
Paramtres de connexion par dfaut.
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Diagnostiques
En cas de difficults, il peut tre utile de consulter VACUUM(7) et psql(1), sections prsentant les problmes ventuels et les messages d'erreur.
Le serveur de base de donnes doit fonctionner sur le serveur cible. Les paramtres de connexion ventuels et les variables
d'environnement utiliss par la bibliothque cliente libpq s'appliquent.

Notes
vacuumdb peut avoir besoin de se connecter plusieurs fois au serveur PostgreSQL. Afin d'viter de saisir le mot de passe
chaque fois, on peut utiliser un fichier ~/.pgpass. Voir Section 31.14, Fichier de mots de passe pour plus d'informations.

Exemples
Pour nettoyer la base de donnes test :
$ vacuumdb test
Pour nettoyer et analyser une base de donnes nomme grossebase :
$ vacuumdb --analyze grossebase
Pour nettoyer la seule table foo dans une base de donnes nomme xyzzy et analyser la seule colonne bar de la table :
$ vacuumdb --analyze --verbose --table 'foo(bar)' xyzzy

Voir aussi
VACUUM(7)

1203

Applications relatives au serveur


PostgreSQL
Cette partie contient des informations de rfrence concernant les applications et les outils relatifs au serveur PostgreSQL.
Ces commandes n'ont d'utilit que lances sur la machine sur laquelle le serveur fonctionne. D'autres programmes utilitaires sont
lists dans la Applications client de PostgreSQL.

1204

Nom
initdb Crer un nouveau cluster

Synopsis
initdb [option...] [--pgdata] | [-D ]rpertoire

Description
initdb cre une nouvelle grappe de bases de donnes, ou cluster , PostgreSQL. Un cluster est un ensemble de bases de
donnes gres par une mme instance du serveur.
Crer un cluster consiste :

crer les rpertoires dans lesquels sont stockes les donnes de la base ;

crer les tables partages du catalogue (tables partages par tout le cluster) ;

crer les bases de donnes template1 et postgres.

Lors de la cration ultrieure d'une base de donnes, tout ce qui se trouve dans la base template1 est copi. (Ce qui implique
que tout ce qui est install dans template1 est automatiquement copi dans chaque base de donnes cre par la suite.) La
base de donnes postgres est une base de donnes par dfaut destination des utilisateurs, des outils et des applications tiers.
initdb tente de crer le rpertoire de donnes indiqu. Il se peut que la commande n'est pas les droits ncessaires si le rpertoire
parent du rpertoire de donnes indiqu est possd par root. Dans ce cas, pour russir l'initialisation, il faut crer un rpertoire
de donnes vide en tant que root, puis utiliser chown pour en donner la possession au compte utilisateur de la base de donnes.
su peut alors tre utilis pour prendre l'identit de l'utilisateur de la base de donnes et excuter initdb.
initdb doit tre excut par l'utilisateur propritaire du processus serveur parce que le serveur doit avoir accs aux fichiers et rpertoires crs par initdb. Comme le serveur ne peut pas tre excut en tant que root, il est impratif de ne pas lancer initdb en
tant que root. (En fait, initdb refuse de se lancer dans ces conditions.)
initdb initialise la locale et l'encodage de jeu de caractres par dfaut du cluster. L'encodage du jeu de caractres, l'ordre de tri
(LC_COLLATE) et les classes d'ensembles de caractres (LC_CTYPE, c'est--dire majuscule, minuscule, chiffre) peuvent tre
configurs sparment pour chaque base de donnes sa cration. initdb dtermine ces paramtres partir de la base de donnes template1 qui servira de valeur par dfaut pour toutes les autres bases de donnes.
Pour modifier l'ordre de tri ou les classes de jeu de caractres par dfaut, utilisez les options --lc-collate et
--lc-ctype. Les ordres de tri autres que C et POSIX ont aussi un cot en terme de performance. Pour ces raisons, il est important de choisir la bonne locale lors de l'excution d'initdb.
Les catgories de locale restantes peuvent tre modifies plus tard, lors du dmarrage du serveur. Vous pouvez aussi utiliser -locale pour configurer les valeurs par dfaut de toutes les catgories de locale, ceci incluant l'ordre de tri et les classes de
jeu de caractres. Toutes les valeurs de locale ct serveur (lc_*) peuvent tre affiches via la commande SHOW ALL. Il y a
plus d'informations sur ce point sur Section 22.1, Support des locales .
Pour modifier l'encodage par dfaut, utilisez l'option --encoding. Section 22.3, Support des jeux de caractres propose
plus d'options.

Options
-A mthode_auth, --auth=mthode_auth
Prcise la mthode d'authentification utilise dans pg_hba.conf pour les utilisateurs locaux. trust ne doit tre utilis
que lorsque tous les utilisateurs locaux du systme sont dignes de confiance. Pour faciliter l'installation, trust est la valeur par dfaut.
-D rpertoire, --pgdata=rpertoire
Indique le rpertoire de stockage de la grappe de bases de donnes. C'est la seule information requise par initdb. Il est possible d'viter de prciser cette option en configurant la variable d'environnement PGDATA. Cela permet, de plus, au serveur
de bases de donnes (postgres) de trouver le rpertoire par cette mme variable.
-E codage, --encoding=codage
Dfinit l'encodage de la base de donnes modle (template). C'est galement l'encodage par dfaut des bases de donnes
cres ultrieurement. Cette valeur peut toutefois tre surcharge. La valeur par dfaut est dduite de la locale. Dans le cas
1205

initdb

o cela n'est pas possible, SQL_ASCII est utilis. Les jeux de caractres supports par le serveur PostgreSQL sont dcrits
dans Section 22.3.1, Jeux de caractres supports .
--locale=locale
Configure la locale par dfaut pour le cluster. Si cette option n'est pas prcise, la locale est hrite de l'environnement
d'excution d'initdb. Le support des locales est dcrit dans Section 22.1, Support des locales .
--lc-collate=locale, --lc-ctype=locale, --lc-messages=locale, --lc-monetary=locale,
-lc-numeric=locale, --lc-time=locale
Mme principe que --locale, mais seule la locale de la catgorie considre est configure.

--no-locale
quivalent --locale=C.
--pwfile=nomfichier
Incite initdb lire le mot de passe du superutilisateur partir d'un fichier. La premire ligne du fichier est utilise comme mot
de passe.
-U nomutilisateur, --username=nomutilisateur
Prcise le nom de l'utilisateur dfini comme superutilisateur de la base de donnes. Par dfaut, c'est le nom de l'utilisateur qui
lance initdb. Le nom du superutilisateur importe peu, mais postgres peut tre conserv, mme si le nom de l'utilisateur
systme diffre.
-W, --pwprompt
Force initdb demander un mot de passe pour le superutilisateur de la base de donnes. Cela n'a pas d'importance lorsqu'aucune authentification par mot de passe n'est envisage. Dans le cas contraire, l'authentification par mot de passe n'est pas
utilisable tant qu'un mot de passe pour le superutilisateur n'est pas dfini.
-X rpertoire, --xlogdir=rpertoire
Dfinit le rpertoire de stockage des journaux de transaction.
--text-search-config=CFG
Slectionne la configuration par dfaut de la recherche plein texte. Voir default_text_search_config pour plus d'informations.
D'autres paramtres, moins utiliss, sont disponibles :
-d, --debug
Affiche les informations de dbogage du processus amorce et quelques autres messages de moindre intrt pour le grand public. Le processus amorce est le programme qu'initdb lance pour crer les tables catalogues. Cette option engendre une quantit considrable de messages ennuyeux.
-L rpertoire
Indique initdb o trouver les fichiers d'entre ncessaires l'initialisation du cluster. En temps normal, cela n'est pas ncessaire. Un message est affich lorsque leur emplacement doit tre indiqu de manire explicite.
-n, --noclean
Par dfaut, lorsqu'initdb rencontre une erreur qui l'empche de finaliser la cration du cluster, le programme supprime tous
les fichiers crs avant l'erreur. Cette option dsactive le nettoyage. Elle est utile pour le dbogage.
-V, --version
Affiche la version de initdb puis quitte.
-?, --help
Affiche l'aide sur les arguments en ligne de commande de initdb, puis quitte

Environnement
PGDATA
Indique le rpertoire de stockage de la grappe de bases de donnes ; peut tre surcharg avec l'option -D.
Cet outil, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ).

Notes
initdb peut aussi tre appel avec pg_ctl initdb.

1206

initdb

Voir aussi
postgres(1)

1207

Nom
pg_controldata afficher les informations de contrle d'un groupe de bases de donnes PostgreSQL

Synopsis
pg_controldata [option] [rpertoire_donnes]

Description
pg_controldata affiche les informations initialises lors d'initdb, telles que la version du catalogue. Il affiche aussi des informations sur le traitement des WAL et des points de vrification. Cette information, qui porte sur le groupe complet, n'est pas spcifique une base de donnes.
Cet outil ne peut tre lanc que par l'utilisateur qui a initialis le groupe. Il est, en effet, ncessaire d'avoir le droit de lire le rpertoire des donnes. Le rpertoire des donnes peut tre spcicif sur la ligne de commande ou l'aide de la variable
d'environnement PGDATA. Cet outil accepte les options -V et --version, qui affiche la version de pg_controldata puis arrte
l'application. Il accepte aussi les options -? et --help, qui affichent les arguments accepts.

Environnement
PGDATA
Emplacement du rpertoire de donnes par dfaut

1208

Nom
pg_ctl initialiser, dmarrer, arrter ou contrler le serveur PostgreSQL

Synopsis
pg_ctl init[db] [-s] [-D rpertoire_donnes] [-o options-initdb]
pg_ctl start [-w] [-t secondes] [-s] [-D rpertoire_donnes] [-l nomfichier] [-o options] [-p chemin] [-c]
pg_ctl stop [-W] [-t secondes] [-s] [-D rpertoire_donnes] [-m [s[mart]] | [f[ast]] | [i[mmediate]] ]
pg_ctl restart [-w] [-t secondes] [-s] [-D rpertoire_donnes] [-c] [-m [s[mart]] | [f[ast]] | [i[mmediate]] ] [-o options]
pg_ctl reload [-D rpertoire_donnes]
pg_ctl status [-s] [-D rpertoire_donnes]
pg_ctl promote [-s] [-D rpertoire_donnes]
pg_ctl kill nom_signal id_processus
pg_ctl register [-N nom_service] [-U nom_utilisateur] [-P mot_de_passe] [-D rpertoire_donnes] [-S
[a[uto]] | [d[emand]] ] [-w] [-t secondes] [-s] [-o options]
pg_ctl unregister [-N nom_service]

Description
pg_ctl est un outil qui permet d'initialiser une instance, de dmarrer, d'arrter, ou de redmarrer un serveur PostgreSQL
(postgres(1)). Il permet galement d'afficher le statut d'un serveur en cours d'excution.
Bien que le serveur puisse tre dmarr manuellement, pg_ctl encapsule les tches comme la redirection des traces ou le dtachement du terminal et du groupe de processus. Il fournit galement des options intressantes pour contrler l'arrt.
Le mode init ou initdb cre une nouvelle grappe PostgreSQL. Une grappe est un ensemble de bases contrles par une
mme instance du serveur. Ce mode invoque la commande initdb. Voir initdb(1) pour les dtails.
En mode start, un nouveau serveur est dmarr. Le serveur est dmarr en tche de fond et l'entre standard est attache /
dev/null (or nul on Windows). On Unix-like systems, by default, the server's standard output and standard error are send to
pg_ctl's standard output (not standard error). The standard output of pg_ctl should then be redirected to a file or piped to another
process such as a log rotating program like rotatelogs; otherwise postgres will write its output to the controlling terminal (from
the background) and will not leave the shell's process group. On Windows, by default the server's standard output and standard
error are sent to the terminal. These default behaviors can be changed by using -l to append server output to a log file.
L'utilisation de l'option -l ou d'une redirection de la sortie est recommande.
En mode stop, le serveur en cours d'excution dans le rpertoire indiqu est arrt. Trois mthodes diffrentes d'arrt peuvent
tre choisies avec l'option -m : le mode smart (la valeur par dfaut) attend la fin de la sauvegarde en ligne (PITR) et la dconnexion de tous les clients. C'est la valeur par dfaut. Si le serveur est en mode hot standby, la rcupration et la rplication en
continu sont arrtes ds que tous les clients se sont dconnects. Le mode fast n'attend pas la dconnexion des clients et
stoppe la sauvegarde en ligne (PITR). Toutes les transactions actives sont annules et les clients sont dconnects. Le serveur est
ensuite arrt. Le mode immediate tue tous les processus serveur immdiatement, sans leur laisser la possibilit de s'arrter
proprement. Cela conduit une rcupration au redmarrage.
Le mode restart excute un arrt suivi d'un dmarrage. Ceci permet de modifier les options en ligne de commande de
postgres.
Le mode reload envoie simplement au processus postgres un signal SIGHUP. Le processus relit alors ses fichiers de configuration (postgresql.conf, pg_hba.conf, etc.). Cela permet de modifier les options des fichiers de configuration qui ne
requirent pas un redmarrage complet pour tre prises en compte.
Le mode status vrifie si un serveur est toujours en cours d'excution sur le rpertoire de donnes indiqu. Si c'est le cas, le
PID et les options en ligne de commande utilises lors de son dmarrage sont affichs.
Dans le mode promote, le serveur en attente, fonctionnant partir du rpertoire de donnes spcifie, sort de la restauration et
commence oprer en mode lecture/criture.
Le mode kill permet d'envoyer un signal un processus spcifique. Ceci est particulirement utile pour Microsoft
Windows, qui ne possde pas de commande kill. --help permet d'afficher la liste des noms de signaux supports.
1209

pg_ctl

Le mode register permet d'enregistrer un service systme sur Microsoft Windows. L'option -S permet la slection du type
de dmarrage du service, soit auto (lance le service automatiquement lors du dmarrage du serveur) soit demand (lance le
service la demande).
Le mode unregister permet, sur Microsoft Windows, d'annuler un service systme. Ceci annule les effets de la commande
register.

Options
-c
Tente d'autoriser la cration de fichiers core suite un arrt brutal du serveur, sur les plateformes o cette fonctionnalit est
disponible, en augmentant la limite logicielle qui en dpend. C'est utile pour le dboguage et pour diagnostiquer des problmes en permettant la rcupration d'une trace de la pile d'un processus serveur en chec.
-D rpertoire_donnes
Indique l'emplacement des fichiers de la base de donnes sur le systme de fichiers. Si cette option est omise, la variable
d'environnement PGDATA est utilise.
-l nomfichier
Ajoute la sortie des traces du serveur dans nomfichier. Si le fichier n'existe pas, il est cr. L'umask est configur 077,
donc l'accs au journal des traces est, par dfaut, interdit aux autres utilisateurs.
-m mode
Prcise le mode d'arrt. mode peut tre smart, fast ou immediate, ou la premire lettre d'un de ces trois mots. En cas
d'omission, smart est utilis.
-o options
Indique les options passer directement la commande postgres.
Les options doivent habituellement tre entoures de guillemets simples ou doubles pour s'assurer qu'elles soient bien passes
comme un groupe.
-o options-initdb
Spcifie les options passer directement la commande initdb.
Ces options sont habituellement entoures par des guillemets simples ou doubles pour s'assurer qu'elles soient passes groupes.
-p chemin
Indique l'emplacement de l'excutable postgres. Par dfaut, l'excutable postgres est pris partir du mme rpertoire
que pg_ctl ou, si cela choue, partir du rpertoire d'installation cod en dur. Il n'est pas ncessaire d'utiliser cette option sauf
cas inhabituel, comme lorsque des erreurs concernant l'impossibilit de trouver l'excutable postgres apparaissent.
Dans le mode init, cette option indique de manire analogue la localisation de l'excutable initdb.
-s
Affichage des seules erreurs, pas de messages d'information.
-t
Le nombre maximum de secondes attendre pour la fin du lancement ou de l'arrt.
-w
Attendre que le dmarrage ou l'arrt se termine. Attendre est l'option par dfaut pour les arrts, mais pas pour les dmarrages.
Lors d'une attente d'un dmarrage, pg_ctl tente plusieurs fois de se connecter au serveur. Lors d'une attente d'un arrt, pg_ctl
attend que le serveur supprime le fichier PID. pg_ctl renvoie un code d'erreur bas sur le succs du dmarrage ou de l'arrt.
-W
Ne pas attendre la fin du dmarrage ou de l'arrt. C'est la valeur par dfaut pour les dmarrages et redmarrages.

Options Windows
-N nom_service
Nom du service systme enregistrer. Le nom est utilis la fois comme nom de service et comme nom affich.
-P mot_de_passe
Mot de passe de l'utilisateur qui dmarre le service.
-S start-type
1210

pg_ctl

Type de dmarrage du service systme enregistrer. start-type peut valoir auto ou demand ou la premire lettre de ces deux
possibilits. Si ce paramtre est omis, la valeur par dfaut est auto.
-U nom_utilisateur
Nom de l'utilisateur qui dmarre le service. Pour les utilisateurs identifis sur un domaine, on utilise le format DOMAIN\nom_utilisateur.

Environnement
PGDATA
Emplacement par dfaut du rpertoire des donnes.
pg_ctl, comme la plupart des autres outils PostgreSQL, utilise aussi les variables d'environnement supportes par la bibliothque libpq (voir Section 31.13, Variables d'environnement ). Pour des variables serveurs supplmentaires, voir postgres(1).

Fichiers
postmaster.pid
Ce fichier, situ dans le rpertoire des donnes, est utilis pour aider pg_ctl dterminer si le serveur est actuellement en
cours d'excution.
postmaster.opts
Si ce fichier existe dans le rpertoire des donnes, pg_ctl (en mode restart) passe le contenu du fichier comme options de
postgres, sauf en cas de surcharge par l'option -o. Le contenu de ce fichier est aussi affich en mode status.

Exemples
Lancer le serveur
Dmarrer un serveur :
$ pg_ctl start
Dmarrer un serveur, avec blocage tant que le serveur n'est pas compltement dmarr :
$ pg_ctl -w start
Pour excuter le serveur en utilisant le port 5433, et en s'excutant sans fsync :
$ pg_ctl -o "-F -p 5433" start

Arrt du serveur
Pour arrter le serveur, utilisez :
$ pg_ctl stop
L'option -m autorise le contrle sur la faon dont le serveur est arrt :
$ pg_ctl stop -m fast

Redmarrage du serveur
Redmarrer le serveur est pratiquement quivalent l'arrter puis le dmarrer nouveau si ce n'est que pg_ctl sauvegarde et
rutilise les options en ligne de commande qui taient passes l'instance prcdente. Pour redmarrer le serveur de la faon la
plus simple, on utilise :
$ pg_ctl restart
Redmarrer le serveur, en attendant l'arrt et le redmarrage :
$ pg_ctl -w restart
Redmarrer en utilisant le port 5433 et en dsactivant fsync aprs redmarrage :
1211

pg_ctl

$ pg_ctl -o "-F -p 5433" restart

Affichage de l'tat du serveur


Exemple de statut affich partir de pg_ctl :
$ pg_ctl status
+pg_ctl: server is running (PID: 13718)
+/usr/local/pgsql/bin/postgres "-D" "/usr/local/pgsql/data" "-p" "5433" "-B" "128"
C'est la ligne de commande qui sera appele en mode redmarrage.

Voir aussi
initdb(1), postgres(1)

1212

Nom
pg_resetxlog rinitialiser les WAL et les autres informations de contrle d'une grappe de bases de donnes PostgreSQL

Synopsis
pg_resetxlog [-f] [-n] [-ooid ] [-x xid ] [-e xid_epoch ] [-m mxid ] [-O mxoff ] [-l timelineid,fileid,seg ]
rp_donnes

Description
pg_resetxlog efface les jouranux d'critures anticipes (Write-Ahead Log ou WAL) et rinitialise optionnellement quelques
autres informations de contrle stockes dans le fichier pg_control. Cette fonction est parfois ncessaire si ces fichiers ont
t corrompus. Elle ne doit tre utilise qu'en dernier ressort quand le serveur ne dmarre plus du fait d'une telle corruption.
la suite de cette commande, le serveur doit pouvoir redmarrer. Toutefois, il ne faut pas perdre de vue que la base de donnes
peut contenir des donnes inconsistantes du fait de transactions partiellement valides. Il est alors opportun de sauvegarder les
donnes, lancer initdb et de les recharger. Aprs cela, les inconsistances doivent tre recharches et le cas chant corriges.
Seul l'utilisateur qui a install le serveur peut utiliser cet outil. Il requiert, en effet, un accs en lecture/criture au rpertoire des
donnes. Pour des raisons de scurit, pg_resetxlog n'utilise pas la variable d'environnement PGDATA. Le rpertoire des donnes doit donc tre prcis sur la ligne de commande.
Si pg_resetxlog se plaint de ne pas pouvoir dterminer de donnes valides pour pg_control, vous pouvez malgr tout le forcer continuer en spcifiant l'option -f (force). Dans ce cas, des valeurs probables sont substitues aux donnes manquantes.
La plupart des champs correspondent mais une aide manuelle pourrait tre ncessaire pour le prochain OID, le prochain TID et
sa date, le prochain identifiant multi-transaction et son dcalage, l'adresse de dbut des journaux de transactions. Ces champs
peuvent tre configurs en utilisant les options indiques ci-dessus. Si vous n'tes pas capable de dterminer les bonnes valeurs
pour tous ces champs, -f peut toujours tre utilis mais la base de donnes rcupre doit tre traite avec encore plus de suspicion que d'habitude : une sauvegarde immdiate et un rechargement sont impratifs. Ne pas excuter d'oprations de modifications de donnes dans la base avant de sauvegarder ; ce type d'action risque de faire empirer la corruption.
Les options -o, -x, -e, -m, -O et -l permettent d'initialiser manuellement le prochain OID, le prochain TID et sa date, le prochain ID multitransaction, son dcalage et l'adresse de dbut des WAL. Elles sont seulement ncessaires si pg_resetxlog est incapable de dterminer les valeurs appropries en lisant pg_control. Les valeurs saines pour le prochain ID en transaction
peuvent se dterminer ainsi :

Une bonne valeur du prochain ID de transaction (-x) peut tre dtermine en recherchant le fichier le plus large numriquement dans le rpertoire pg_clog sous le rpertoire des donnes, en ajoutant un et en multipliant par 1048576. Notez que
les noms de fichiers sont en hexadcimal. Il est habituellement plus facile de spcifier la valeur de l'option en hexadcimal
aussi. Par exemple, si 0011 est l'entre la plus large dans pg_clog, -x 0x1200000 fonctionnera (cinq zros la fin
fournissent le bon multiplieur).

Une valeur saine pour le prochain ID multitransaction (-m) peut tre dtermine en recherchant le nom de fichier le plus important numriquement dans le sous-rpertoire pg_multixact/offsets du rpertoire data, en lui ajoutant un, puis en le
multipliant par 65536. Comme ci-dessus, les noms de fichiers sont en hexadcimal, donc la faon la plus simple de le faire
est de spcifier la valeur de l'option en hexadcimal et de lui ajouter quatre zros.

Une valeur saine pour le prochain dcalage multitransaction (-O) peut tre dtermine en recherchant le nom de fichier le
plus important numriquement dans le sous-rpertoire pg_multixact/members du rpertoire data, en lui ajoutant un,
puis en le multipliant par 65536. Comme ci-dessus, les noms de fichiers sont en hexadcimal, donc la faon la plus simple
de le faire est de spcifier la valeur de l'option en hexadcimal et de lui ajouter quatre zros.

L'adresse de dbut des WAL (-l) doit tre plus large que tout nom de fichier de segment WAL dj existant dans le rpertoire pg_xlog sous le rpertoire des donnes. Ces noms sont aussi en hexadcimal et ont trois parties. La premire est le
timeline ID et doit habituellement tre conserve identique. Ne choisissez pas de valeur plus importante que 255 (0xFF)
pour la troisime partie ; la place, incrmentez la deuxime partie et rinitialisez la troisime partie 0. Par exemple, si
00000001000000320000004A est l'entre la plus importante de pg_xlog, -l 0x1,0x32,0x4B fonctionnera ;
mais si l'entre la plus importante est 000000010000003A000000FF, choisissez -l 0x1,0x3B,0x0 ou plus.

Note
pg_resetxlog lui-mme recherche les fichiers dans pg_xlog et choisit un paramtre -l par dfaut au-del
du dernier fichier existant. Du coup, un ajustement manuel de -l sera seulement ncessaire si vous avez
connaissance de fichiers WAL qui ne sont actuellement pas prsents dans le rpertoire pg_xlog, comme des
1213

pg_resetxlog

entres dans une archive hors ligne ou si le contenu de pg_xlog avait compltement disparu.

Il n'y a pas de faon plus simple pour dterminer un OID suivant qui se trouve aprs celui de la base de donnes mais, heureusement, il n'est pas critique d'obtenir le bon OID suivant.

La valeur epoch de l'identifiant de transaction n'est pas rellement stocke dans la base, sauf dans le champ qui est initialis
par pg_resetxlog, donc toute valeur sera correcte en ce qui concerne la base de donnes elle-mme. Vous pourrez avoir besoin
d'ajuster cette valeur pour vous assurer que les systmes de rplication comme Slony-I fonctionnent correctement -- dans ce
cas, une valeur approprie doit tre obtenue partir de l'tat de la base rplique.

L'option -n (sans opration) demande pg_resetxlog d'afficher les valeurs reconstruites partir de pg_control puis quitte
sans rien modifier. C'est principalement un outil de dbogage mais qui peut tre utile pour une vrification avant de permettre
pg_resetxlog de traiter rellement la base.
Les options -V et --version affichent la version de pg_resetxlog puis arrtent l'application. Les options -? et --help affichent les arguments accepts.

Notes
Cette commande ne doit pas tre utilise si le serveur est en cours d'excution. pg_resetxlog refuse de se lancer s'il trouve un fichier de verrouillage du serveur dans le rpertoire des donnes ; Si le serveur s'est arrt brutalement, il peut subsister un tel fichier. Dans ce cas, vous pouvez supprimer le fichier de verrouillage pour permettre pg_resetxlog de se lancer. Mais avant de le
faire, soyez doublement certain qu'il n'y a pas de processus serveur en cours.

1214

Nom
postgres Serveur de bases de donnes PostgreSQL

Synopsis
postgres [option...]

Description
postgres est le serveur de bases de donnes PostgreSQL. Pour qu'une application cliente puisse accder une base de donnes, elle se connecte (soit via le rseau soit localement) un processus postgres en cours d'excution. L'instance postgres dmarre ensuite un processus serveur spar pour grer la connexion.
Une instance postgres gre toujours les donnes d'un seul cluster. Un cluster est un ensemble de bases de donnes stock un
mme emplacement dans le systme de fichiers (le rpertoire des donnes ). Plus d'un processus postgres peut tre en cours
d'excution sur un systme un moment donn, s'ils utilisent des rpertoires diffrents et des ports de communication diffrents
(voir ci-dessous). Quand postgres se lance, il a besoin de connatre l'emplacement du rpertoire des donnes. Cet emplacement
doit tre indique par l'option -D ou par la variable d'environnement PGDATA ; il n'y a pas de valeur par dfaut. Typiquement, D ou PGDATA pointe directement vers le rpertoire des donnes cr par initdb(1). D'autres dispositions de fichiers possibles
sont discuts dans Section 18.2, Emplacement des fichiers . Un rpertoire de donnes est cr avec initdb(1). Un rpertoire de
donnes est cr avec initdb(1).
Par dfaut, postgres s'excute en avant-plan et affiche ses messages dans le flux standard des erreurs. En pratique, postgres devrait tre excut en tant que processus en arrire-plan, par exemple au lancement.
La commande postgres peut aussi tre appel en mode mono-utilisateur. L'utilisation principal de ce mode est lors du
bootstrap utilis par initdb(1). Quelque fois, il est utilis pour du dbogage et de la rcupration suite un problme (mais
noter qu'excuter un serveur en mode mono-utilisateur n'est pas vraiment convenable pour dboguer le serveur car aucune communication inter-processus raliste et aucun verrouillage n'interviennent.) Quand il est appel en mode interactif partir du
shell, l'utilisateur peut saisir des requtes et le rsultat sera affich l'cran mais dans une forme qui est plus utile aux dveloppeurs qu'aux utilisateurs. Dans le mode mono-utilisateur, la session ouverte par l'utilisateur sera configure avec l'utilisateur
d'identifiant 1 et les droits implicites du superutilisateur lui sont donns. Cet utilisateur n'a pas besoin d'exister, donc le mode
mono-utilisateur peut tre utilis pour rcuprer manuellement aprs certains types de dommages accidentels dans les catalogues
systmes.

Options
postgres accepte les arguments suivants en ligne de commande. Pour une discussion dtaille des options, consultez Chapitre 18, Configuration du serveur. Vous pouvez viter de saisir la plupart de ces options en les initialisant dans le fichier de
configuration. Certaines options (sres) peuvent aussi tre configures partir du client en cours de connexion d'une faon dpendante de l'application, configuration qui ne sera applique qu' cette session. Par exemple si la variable d'environnement
PGOPTIONS est configure, alors les clients bass sur libpq passeront cette chane au serveur qui les interprtera comme les options en ligne de commande de postgres.

Gnral
-A 0|1
Active les vrifications d'assertion l'excution, donc une aide au dbogage pour dtecter les erreurs de programmation.
Cette option est seulement disponible si les assertions on t actives lors de la compilation de PostgreSQL. Dans ce cas,
la valeur par dfaut est on .
-B ntampons
Configure le nombre de tampons partags utiliss par les processus serveur. La valeur par dfaut de ce paramtre est choisi
automatiquement par initdb. Indiquer cette option est quivalent configurer le paramtre shared_buffers.
-c nom=valeur
Configure un parammtre d'excution nomm. Les paramtres de configuration supports par PostgreSQL sont dcrits
dans Chapitre 18, Configuration du serveur. La plupart des autres options en ligne de commande sont en fait des formes
courtes d'une affectation de paramres. -c peut apparatre plusieurs fois pour configurer diffrents paramtres.
-d niveau-dbogage
Configure le niveau de dbogage. Plus haute est sa valeur, plus importante seront les traces crites dans les journaux. Les
valeurs vont de 1 5. Il est aussi possible de passer -d 0 pour une session spcifique qui empchera le niveau des traces
serveur du processus postgres parent d'tre propag jusqu' cette session.
1215

postgres

-D repdonnes
Indique le rpertoire des donnes ou des fichier(s) de configuration. Voir Section 18.2, Emplacement des fichiers pour les
dtails.
-e
Configure le style de date par dfaut European , c'est--dire l'ordre DMY pour les champs en entre. Ceci cause aussi
l'affichage de la date avant le mois dans certains formats de sortie de date. Voir Section 8.5, Types date/heure pour plus
d'informations.
-F
Dsactive les appels fsync pour amliorer les performances au risque de corrompre des donnes dans l'ide d'un arrt brutal
du systme. Spcifier cette option est quivalent dsactiver le paramtre de configuration fsync. Lisez la documentation dtaille avant d'utiliser ceci !
-h hte
Indique le nom d'hte ou l'adresse IP sur lequel postgres attend les connexions TCP/IP d'applications clientes. La valeur peut
aussi tre une liste d'adresses spares par des virgules ou * pour indiquer l'attente sur toutes les interfaces disponibles. Une
valeur vide indique qu'il n'attend sur aucune adresse IP, auquel cas seuls les sockets de domaine Unix peuvent tre utiliss
pour se connecter au serveur. Par dfaut, attend les connexions seulement sur localhost. Spcifier cette option est quivalent la configurer dans le paramtre listen_addresses.
-i
Autorise les clients distants se connecter via TCP/IP (domaine Internet). Sans cette option, seules les connexions locales
sont autorises. Cette option est quivalent la configuration du paramtre listen_addresses * dans postgresql.conf ou via -h.
Cette option est obsolte car il ne permet plus l'accs toutes les fonctionnalits de listen_addresses. Il est gnralement
mieux de configurer directement listen_addresses.
-k directory
Indique le rpertoire de la socket de domaine Unix sur laquelle postgres est en attente des connexions des applications
clients. La valeur par dfaut est habituellement /tmp mais cela peut se changer au moment de la construction.
-l
Active les connexions scurises utilisant SSL. PostgreSQL doit avoir t compil avec SSL pour que cette option soit disponible. Pour plus d'informations sur SSL, rfrez-vous Section 17.9, Connexions tcp/ip scurises avec ssl .
-N max-connections
Initialise le nombre maximum de connexions clientes que le serveur acceptera. La valeur par dfaut de ce paramtre est choisi
automatiquement par initdb. Indiquer cette option est quivalent configurer le paramtre max_connections.
-o extra-options
Les options en ligne de commande indiques dans extra-options sont passes tous les processus serveur excuts par
ce processus postgres. Si la chane d'option contient des espaces, la chane entire doit tre entre guillemets.
Cette option est obsolte ; toutes les options en ligne de commande des processus serveur peuvent tre spcifies directement
sur la ligne de commande de postgres.
-p port
Indique le port TCP/IP ou l'extension du fichier socket de domaine Unix sur lequel postgres attend les connexions des applications clientes. Par dfaut, la valeur de la variable d'environnement PGPORT environment ou, si cette variable n'est pas
configurer, la valeur connue la compilation (habituellement 5432). Si vous indiquez un port autre que celui par dfaut, alors
toutes les applications clientes doivent indiquer le mme numro de port soit dans les options en ligne de commande soit avec
PGPORT.
-s
Affiche une information de temps et d'autres statistiques la fin de chaque commande. Ceci est utile pour crer des rapports
de performance ou pour configurer finement le nombre de tampons.
-S work-mem
Indique la quantit de mmoire utiliser par les tris internes et par les hachages avant d'utiliser des fichiers disque temporaires. Voir la description du paramtre work_mem dans Section 18.4.1, Mmoire .
--nom=valeur
Configure un paramtre l'excution ; c'est une version courte de -c.
--describe-config
Cette option affiche les variables de configuration internes du serveur, leurs descriptions et leurs valeurs par dfaut dans un
format COPY dlimit par des tabulations. Elle est conue principalement pour les outils d'administration.
1216

postgres

Options semi-internes
Les options dcrites ici sont utilises principalement dans un but de dbogage et pouvant quelque fois aider la rcupration de
bases de donnes trs endommages/ Il n'y a aucune raison pour les utiliser dans la configuration d'un systme en production.
Elles sont listes ici l'intention des dveloppeurs PostgreSQL. De plus, une de ces options pourrait disparatre ou changer dans
le futur sans avertissement.
-f { s | i | m | n | h }
Interdit l'utilisation de parcours et de mthode de jointure particulires. s and i dsactivent respectivement les parcours squentiels et d'index alors que n, m et h dsactivent respectivement les jointures de boucles imbriques, jointures de fusion et
hash.
Ni les parcours squentiels ni les jointures de boucles imbriques ne peuvent tre dsactivs compltement ; les options -fs
et -fn ne font que dcourager l'optimiseur d'utiliser ce type de plans.
-n
Cette option est prsente pour les problmes de dbogage du genre mort brutal d'un processus serveur. La stratgie habituelle
dans cette situation est de notifier tous les autres processus serveur qu'ils doivent se terminer, puis rinitialiser la mmoire
partage et les smaphores. Tout ceci parce qu'un processus serveur errant peut avoir corrompu certains tats partags avant
de terminer. Cette option spcifie seulement que postgres ne rinitialisera pas les structures de donnes partages. Un dveloppeur systme avec quelques connaissances peut utiliser un dbogueur pour examiner l'tat de la mmoire partage et des
smaphores.
-O
Autorise la modification de la structure des tables systme. C'est utilis par initdb.
-P
Ignore les index systme lors de la lecture des tables systme (mais les met jour lors de la modification des tables). Ceci est
utile lors de la rcupration d'index systme endommags.
-t pa[rser] | pl[anner] | e[xecutor]
Affiche les statistiques en temps pour chaque requte en relation avec un des modules majeurs du systme. Cette option ne
peut pas tre utilise avec l'option -s.
-T
Cette option est prsente pour les problmes de dbogage du genre mort brutal d'un processus serveur. La stratgie habituelle
dans cette situation est de notifier tous les autres processus serveur qu'ils doivent se terminer, puis rinitialiser la mmoire
partage et les smaphores. Tout ceci parce qu'un processus serveur errant peut avoir corrompu certains tats partags avant
de terminer. Cette option spcifie seulement que postgres arrtera tous les autres processus serveur en leur envoyant le signal
SIGSTOP mais ne les arrtera pas. Ceci permet aux dveloppeurs systme de rcuprer manuellement des core dumps de
tous les processus serveur.
-v protocole
Indique le numro de version utilis par le protocole interface/moteur pour une session particulire. Cette option est uniquement utilise en interne.
-W secondes
Un dlai de ce nombre de secondes survient quand un nouveau processus serveur est lanc, une fois la procdure
d'authentification termine. Ceci a pour but de permettre au dveloppeur d'attacher un dbogueur au processus serveur.

Options en mode mono-utilisateur


Les options suivantes s'appliquent uniquement en mode mono-utilisateur.
--single
Slectionne le mode mono-utilisateur. Cette option doit tre la premire sur la ligne de commande.
base
Indique le nom de la base accder. Il doit tre le dernier argument. Si elle est omise, le nom de l'utilisateur est utilis par dfaut.
-E
Affiche toutes les commandes.
-j
Dsactive l'utilisation du retour chariot comme dlimiteur d'instruction.
-r fichier
1217

postgres

Envoie toute la sortie des traces du serveur dans fichier. Dans le mode normal, cette option est ignore et stderr est utilis par tous les processus.

Environnement
PGCLIENTENCODING
Jeu de caractres utilis par dfaut par tous les clients. (Les clients peuvent surcharger ce paramtre individuellement.) Cette
valeur est aussi configurable dans le fichier de configuration.
PGDATA
Emplacement du rpertoire des donnes par dfaut
PGDATESTYLE
Valeur par dfaut du paramtre en excution datestyle. (Cette variable d'environnement est obsolte.)
PGPORT
Numro de port par dfaut ( configurer de prfrence dans le fichier de configuration)
TZ
Fuseau horaire du serveur

Diagnostiques
Un message d'erreur mentionnant semget ou shmget indique probablement que vous devez configurer votre noyau pour fournir
la mmoire partage et les smaphores adquates. Pour plus de discussion, voir Section 17.4, Grer les ressources du noyau .
Vous pouvez aussi repousser la configuration du noyau en diminuant shared_buffers pour rduire la consommation de la mmoire
partage utilise par PostgreSQL, et/ou en diminuant max_connections pour rduire la consommation de smaphores.
Un message d'erreur suggrant qu'un autre serveur est dj en cours d'excution devra vous demander une vrification attentive,
par exemple en utilisant la commande ps should be checked carefully, for example by using the command
$ ps ax | grep postgres
ou
$ ps -ef | grep postgres
suivant votre systme. Si vous tes certain qu'il n'y a aucun serveur en conflit, vous pouvez supprimer le fichier verrou mentionn
dans le message et tenter de nouveau.
Un message d'erreur indiquant une incapacit se lier un port indique que ce port est dj utilis par des processus autres que
PostgreSQL. Vous pouvez aussi obtenir cette erreur si vous quittez postgres et le relancez immdiatement en utilisant le mme
port ; dans ce cas, vous devez tout simplement attendre quelques secondes pour que le systme d'exploitation ferme bien le port
avant de tenter de nouveau. Enfin, vous pouvez obtenir cette erreur si vous indiquez un numro de port que le systme considre
comme rserv. Par exemple, beaucoup de versions d'Unix considrent les numros de port sous 1024 comme de confiance et
permettent seulement leur accs par le superutilisateur Unix.

Notes
L'outil pg_ctl(1) est utilisable pour lancer et arrter le serveur postgres de faon sre et confortable.
Si possible, ne pas utiliser SIGKILL pour tuer le serveur postgres principal. Le fait empchera postgres de librer les ressources
systme (c'est--dire mmoire partage et smaphores) qu'il dtient avant de s'arrter. Ceci peut poser problmes lors du lancement d'un postgres frais.
Pour terminer le serveur postgres normalement, les signaux SIGTERM, SIGINT ou SIGQUIT peuvent tre utiliss. Le premier
attendra que tous les clients terminent avant de quitter, le second forcera la dconnexion de tous les clients et le troisime quittera
immdiatement sans arrt propre. Ce dernier amnera une rcupration lors du redmarrage.
Le signal SIGHUP rechargera les fichiers de configuration du serveur. Il est aussi possible d'envoyer SIGHUP un processus serveur individuel mais ce n'est pas perceptible.
Pour annuler une requte en cours d'excution, envoyez le signal SIGINT au processus excutant cette commande.
Le serveur postgres utilise SIGTERM pour indiquer aux processus serveur de quitter normalement et SIGQUIT pour terminer
sans le nettoyage habituel. Ces signaux ne devraient pas tre utiliss par les utilisateurs. Il est aussi dconseill d'envoyer SIGKILL un processus serveur -- le serveur postgres principal interprtera ceci comme un arrt brutal et forcera tous les autres processus serveur quitter dans le cas d'une procdure standard de rcupration aprs arrt brutal.
1218

postgres

Bogues
Les options -- ne fonctionneront pas sous FreeBSD et OpenBSD. Utilisez -c la place. C'est un bogue dans les systmes
d'exploitation affects ; une prochaine version de PostgreSQL fournira un contournement si ce n'est pas corrig.

Utilisation
Pour dmarrer un serveur en mode mono-utilisateur, utilisez une commande comme
postgres --single -D /usr/local/pgsql/data autres-options ma_base
Fournissez le bon chemin vers le rpertoire des bases avec l'option -D ou assurez-vous que la variable d'environnement PGDATA
est configure. De plus, spcifiez le nom de la base particulire avec laquelle vous souhaitez travailler.
Habituellement, le serveur en mode mono-utilisateur traite le retour chariot comme le terminateur d'une commande ; il n'y a pas le
concept du point-virgule contraitement psql. Pour saisir une commande sur plusieurs lignes, vous devez saisir un antislash juste
avant un retour chariot, sauf pour le dernier.
Mais si vous utilisez l'option -j, alors le retour chariot ne termine pas une commande. Dans ce cas, le serveur lira l'entre standard jusqu' une marque de fin de fichier (EOF), puis il traitera la saisie comme une seule chane de commande. Les retours chariot avec antislash ne sont pas traits spcialement dans ce cas.
Pour quitter la session, saisissez EOF (habituellement, Control+D). Si vous avez utilis l'option -j, deux EOF conscutifs sont
ncessaires pour quitter.
Notez que le serveur en mode mono-utilisateur ne fournit pas de fonctionnalits avances sur l'dition de lignes (par exemple, pas
d'historique des commandes). De plus, le mode mono-utilisateur ne lance pas de processus en tche de fond, comme par exemple
les checkpoints automatiques.

Exemples
Pour lancer postgres en tche de fond avec les valeurs par dfaut, saisissez :
$ nohup postgres >logfile 2>&1 </dev/null &
Pour lancer postgres avec un port spcifique, e.g. 1234 :
$ postgres -p 1234
Pour se connecter ce serveur avec psql, indiquez le numro de port avec l'option -p :
$ psql -p 1234
ou de configurer la variable d'environnement PGPORT :
$ export PGPORT=1234
$ psql
Les paramtres nomms peuvent tre configurs suivant deux faons :
$ postgres -c work_mem=1234
$ postgres --work-mem=1234
Ces deux formes surchargent le paramtrage qui pourrait exister pour work_mem dans postgresql.conf. Notez que les tirets
bas dans les noms de paramtres sont crits avec soir des tirets bas soit des tirets sur la ligne de commande. Sauf pour les expriences court terme, il est probablement mieux de modifier le paramtrage dans postgresql.conf que de se baser sur une
option en ligne de commande.

Voir aussi
initdb(1), pg_ctl(1)

1219

Nom
postmaster Serveur de bases de donnes PostgreSQL

Synopsis
postmaster [option...]

Description
postmaster est un alias obsolte de postgres.

Voir aussi
postgres(1)

1220

Partie VII. Internes


Cette partie contient des informations diverses utiles aux dveloppeurs.

Chapitre 44. Prsentation des mcanismes internes


de PostgreSQL
Auteur
Ce chapitre est extrait de sim98, mmoire de matrise (Master's Thesis) de Stefan Simkovics. Cette matrise a t
prpare l'universit de technologie de Vienne sous la direction du professeur (O.Univ.Prof.Dr.) Georg Gottlob
et de l'assistante d'universit (Univ.Ass.) Mag. Katrin Seyr.
Ce chapitre prsente la structure interne du serveur PostgreSQL. La lecture des sections qui suivent permet de se faire une
ide de la faon dont une requte est excute ; les oprations internes ne sont pas dcrites dans le dtail. Ce chapitre a, au
contraire, pour but d'aider le lecteur comprendre la suite des oprations effectues sur le serveur depuis la rception d'une requte jusqu'au retour des rsultats.

44.1. Chemin d'une requte


Ceci est un rapide aperu des tapes franchies par une requte pour obtenir un rsultat.
1.

Une connexion au serveur est tablie par une application. Elle transmet une requte et attend le retour des rsultats.

2.

L'tape d'analyse (parser stage) vrifie la syntaxe de la requte et cre un arbre de requte (query tree).

3.

Le systme de rcriture (rewrite system) recherche les rgles (stockes dans les catalogues systme) appliquer l'arbre
de requte. Il excute les transformations indiques dans le corps des rgles (rule bodies).
La ralisation des vues est une application du systme de rcriture. Toute requte utilisateur impliquant une vue
(c'est--dire une table virtuelle), est rcrite en une requte qui accde aux tables de base, en fonction de la dfinition de la
vue.

4.

Le planificateur/optimiseur (planner/optimizer) transforme l'arbre de requte (rcrit) en un plan de requte (query plan)
pass en entre de l'excuteur.
Il cre tout d'abord tous les chemins possibles conduisant au rsultat. Ainsi, s'il existe un index sur une relation parcourir,
il existe deux chemins pour le parcours. Le premier consiste en un simple parcours squentiel, le second utilise l'index. Le
cot d'excution de chaque chemin est estim ; le chemin le moins coteux est alors choisi. Ce dernier est tendu en un
plan complet que l'excuteur peut utiliser.

5.

L'excuteur traverse rcursivement les tapes de l'arbre de planification (plan tree) et retrouve les lignes en fonction de ce
plan. L'excuteur utilise le systme de stockage lors du parcours des relations, excute les tris et jointures, value les qualifications et retourne finalement les lignes concernes.

Les sections suivantes prsentent en dtail les lments brivement dcrits ci-dessus.

44.2. tablissement des connexions


PostgreSQL est crit suivant un simple modle client/serveur processus par utilisateur . Dans ce modle, il existe un processus client connect un seul processus serveur. Comme le nombre de connexions tablies n'est pas connu l'avance, il est
ncessaire d'utiliser un processus matre qui lance un processus serveur chaque fois qu'une connexion est demande. Ce processus matre s'appelle postgres et coute les connexions entrantes sur le port TCP/IP indiqu. chaque fois qu'une demande de connexion est dtecte, le processus postgres lance un nouveau processus serveur. Les tches du serveur communiquent entre elles en utilisant des smaphores et de la mmoire partage pour s'assurer de l'intgrit des donnes lors d'accs simultans aux donnes.
Le processus client est constitu de tout programme comprenant le protocole PostgreSQL dcrit dans le Chapitre 46, Protocole client/serveur. De nombreux clients s'appuient sur la bibliothque C libpq, mais il existe diffrentes implantations indpendantes du protocole, tel que le pilote Java JDBC.
Une fois la connexion tablie, le processus client peut envoyer une requte au serveur (backend). La requte est transmise en
texte simple, c'est--dire qu'aucune analyse n'a besoin d'tre ralise au niveau de l'interface (client). Le serveur analyse la requte, cre un plan d'excution, excute le plan et renvoie les lignes trouves au client par la connexion tablie.

1222

Prsentation des mcanismes internes de


PostgreSQL

44.3. tape d'analyse


L'tape d'analyse est constitue de deux parties :

l'analyseur, dfini dans gram.y et scan.l, est construit en utilisant les outils Unix bison et flex ;

le processus de transformation fait des modifications et des ajouts aux structures de donnes renvoyes par l'analyseur.

44.3.1. Analyseur
L'analyseur doit vrifier que la syntaxe de la chane de la requte (arrivant comme un texte ASCII) est valide. Si la syntaxe est
correcte, un arbre d'analyse est construit et renvoy, sinon une erreur est retourne. Les analyseur et vrificateur syntaxiques sont
dvelopps l'aide des outils Unix bien connus bison et flex.
L'analyseur lexical, dfini dans le fichier scan.l, est responsable de la reconnaissance des identificateurs, des mots cls SQL,
etc. Pour chaque mot cl ou identificateur trouv, un jeton est engendr et renvoy l'analyseur.
L'analyseur est dfini dans le fichier gram.y et consiste en un ensemble de rgles de grammaire et en des actions excuter lorsqu'une rgle est dcouverte. Le code des actions (qui est en langage C) est utilis pour construire l'arbre d'analyse.
Le fichier scan.l est transform en fichier source C scan.c en utilisant le programme flex et gram.y est transform en
gram.c en utilisant bison. Aprs avoir ralis ces transformations, un compilateur C normal peut tre utilis pour crer
l'analyseur. Il est inutile de modifier les fichiers C engendrs car ils sont crass l'appel suivant de flex ou bison.

Note
Les transformations et compilations mentionnes sont normalement ralises automatiquement en utilisant les makefile distribus avec les sources de PostgreSQL.
La description dtaille de bison ou des rgles de grammaire donnes dans gram.y dpasse le cadre de ce document. Il existe de
nombreux livres et documentations en relation avec flex et bison. Il est prfrable d'tre familier avec bison avant de commencer
tudier la grammaire donne dans gram.y, au risque de ne rien y comprendre.

44.3.2. Processus de transformation


L'tape d'analyse cre un arbre d'analyse qui n'utilise que les rgles fixes de la structure syntaxique de SQL. Il ne fait aucune recherche dans les catalogues systme. Il n'y a donc aucune possibilit de comprendre la smantique dtaille des oprations demandes. Lorsque l'analyseur a fini, le processus de transformation prend en entre l'arbre rsultant de l'analyseur et ralise
l'interprtation smantique ncessaire pour connatre les tables, fonctions et oprateurs rfrencs par la requte. La structure de
donnes construite pour reprsenter cette information est appele l'arbre de requte.
La sparation de l'analyse brute et de l'analyse smantique rsulte du fait que les recherches des catalogues systme ne peuvent se
drouler qu' l'intrieur d'une transaction. Or, il n'est pas ncessaire de commencer une transaction ds la rception d'une requte.
L'analyse brute est suffisante pour identifier les commandes de contrle des transactions (BEGIN, ROLLBACK, etc.). Elles
peuvent de plus tre correctement excutes sans analyse complmentaire. Lorsqu'il est tabli qu'une vraie requte doit tre gre
(telle que SELECT ou UPDATE), une nouvelle transaction est dmarre si aucune n'est dj en cours. Ce n'est qu' ce moment-l
que le processus de transformation peut tre invoqu.
La plupart du temps, l'arbre d'une requte cr par le processus de transformation a une structure similaire l'arbre d'analyse brute
mais, dans le dtail, de nombreuses diffrences existent. Par exemple, un nud FuncCall dans l'arbre d'analyse reprsente quelque
chose qui ressemble syntaxiquement l'appel d'une fonction. Il peut tre transform soit en nud FuncExpr soit en nud Aggref
selon que le nom rfrenc est une fonction ordinaire ou une fonction d'agrgat. De mme, des informations sur les types de donnes rels des colonnes et des rsultats sont ajoutes l'arbre de la requte.

44.4. Systme de rgles de PostgreSQL


PostgreSQL supporte un puissant systme de rgles pour la spcification des vues et des mises jour de vues ambigus.
l'origine, le systme de rgles de PostgreSQL tait constitu de deux implantations :

la premire, qui fonctionnait au niveau des lignes, tait implante profondment dans l'excuteur. Le systme de rgles tait
appel chaque fois qu'il fallait accder une ligne individuelle. Cette implantation a t supprime en 1995 quand la dernire
version officielle du projet Berkeley Postgres a t transforme en Postgres95 ;

la deuxime implantation du systme de rgles est une technique appele rcriture de requtes. Le systme de rcriture est
un module qui existe entre l'tape d'analyse et le planificateur/optimiseur. Cette technique est toujours implante.
1223

Prsentation des mcanismes internes de


PostgreSQL
Le systme de rcriture de requtes est vu plus en dtails dans le Chapitre 37, Systme de rgles. Il n'est donc pas ncessaire d'en
parler ici. Il convient simplement d'indiquer qu' la fois l'entre et la sortie du systme sont des arbres de requtes. C'est--dire
qu'il n'y a pas de changement dans la reprsentation ou le niveau de dtail smantique des arbres. La rcriture peut tre imagine
comme une forme d'expansion de macro.

44.5. Planificateur/Optimiseur
La tche du planificateur/optimiseur est de crer un plan d'excution optimal. En fait, une requte SQL donne (et donc, l'arbre
d'une requte) peut tre excute de plusieurs faons, chacune arrivant au mme rsultat. Si ce calcul est possible, l'optimiseur de
la requte examinera chacun des plans d'excution possibles pour slectionner le plan d'excution estim comme le plus rapide.

Note
Dans certaines situations, examiner toutes les faons d'excuter une requte prend beaucoup de temps et de mmoire. En particulier, lors de l'excution de requtes impliquant un grand nombre de jointures. Pour dterminer un
plan de requte raisonnable (mais pas forcment optimal) en un temps raisonnable, PostgreSQL utilise un Genetic Query Optimizer (voir Chapitre 51, Optimiseur gntique de requtes (Genetic Query Optimizer)) ds lors que
le nombre de jointures dpasse une certaine limite (voir geqo_threshold).
La procdure de recherche du planificateur fonctionne avec des structures de donnes appels chemins, simples reprsentations
minimales de plans ne contenant que l'information ncessaire au planificateur pour prendre ses dcisions. Une fois le chemin le
moins coteux dtermin, un arbre plan est construit pour tre pass l'excuteur. Celui-ci reprsente le plan d'excution dsir
avec suffisamment de dtails pour que l'excuteur puisse le lancer. Dans le reste de cette section, la distinction entre chemins et
plans est ignore.

44.5.1. Engendrer les plans possibles


Le planificateur/optimiseur commence par engendrer des plans de parcours de chaque relation (table) invididuelle utilise dans la
requte. Les plans possibles sont dtermins par les index disponibles pour chaque relation. Un parcours squentiel de relation
tant toujours possible, un plan de parcours squentiel est systmatiquement cr. Soit un index dfini sur une relation (par
exemple un index B-tree) et une requte qui contient le filtre relation.attribut OPR constante. Si relation.attribut correspond la cl de l'index B-tree et OPR est un des oprateurs lists dans la classe d'oprateurs de l'index,
un autre plan est cr en utilisant l'index B-tree pour parcourir la relation. S'il existe d'autres index et que les restrictions de la requte font correspondre une cl un index, d'autres plans sont considrs. Des plans de parcours d'index sont galement crs
pour les index dont l'ordre de tri peut correspondre la clause ORDER BY de la requte (s'il y en a une), ou dont l'ordre de tri peut
tre utilis dans une jointure de fusion (cf. plus bas).
Si la requte ncessite de joindre deux, ou plus, relations, les plans de jointure des relations sont considrs aprs la dcouverte de
tous les plans possibles de parcours des relations uniques. Les trois stratgies possibles de jointure sont :

jointure de boucle imbrique (nested loop join) : la relation de droite est parcourue une fois pour chaque ligne trouve dans la
relation de gauche. Cette stratgie est facile implanter mais peut tre trs coteuse en temps. (Toutefois, si la relation de
droite peut tre parcourue l'aide d'un index, ceci peut tre une bonne stratgie. Il est possible d'utiliser les valeurs issues de la
ligne courante de la relation de gauche comme cls du parcours d'index droite.)

jointure de fusion (merge join) : chaque relation est trie selon les attributs de la jointure avant que la jointure ne commence.
Puis, les deux relations sont parcourues en parallle et les lignes correspondantes sont combines pour former des lignes
jointes. Ce type de jointure est plus intressant parce que chaque relation n'est parcourue qu'une seule fois. Le tri requis peut
tre ralis soit par une tape explicite de tri soit en parcourant la relation dans le bon ordre en utilisant un index sur la cl de
la jointure ;

jointure de hachage (hash join) : la relation de droite est tout d'abord parcourue et charge dans une table de hachage en utilisant ses attributs de jointure comme cls de hachage. La relation de gauche est ensuite parcourue et les valeurs appropries de
chaque ligne trouve sont utilises comme cls de hachage pour localiser les lignes correspondantes dans la table.

Quand la requte implique plus de deux relations, le rsultat final doit tre construit l'aide d'un arbre d'tapes de jointure, chacune deux entres. Le planificateur examine les squences de jointure possibles pour trouver le moins cher.
Si la requte implique moins de geqo_threshold relations, une recherche quasi-exhaustive est effectue pour trouver la meilleure
squence de jointure. Le planificateur considre prfrentiellement les jointures entre paires de relations pour lesquelles existe une
clause de jointure correspondante dans la qualification WHERE (i.e. pour lesquelles existe une restriction de la forme where
rel1.attr1=rel2.attr2). Les paires jointes pour lesquelles il n'existe pas de clause de jointure ne sont considres que
lorsqu'il n'y a plus d'autre choix, c'est--dire qu'une relation particulire n'a pas de clause de jointure avec une autre relation. Tous
les plans possibles sont crs pour chaque paire jointe considre par le planificateur. C'est alors celle qui est (estime) la moins
1224

Prsentation des mcanismes internes de


PostgreSQL
coteuse qui est choisie.
Lorsque geqo_threshold est dpass, les squences de jointure sont dtermines par heuristique, comme cela est dcrit dans
Chapitre 51, Optimiseur gntique de requtes (Genetic Query Optimizer). Pour le reste, le processus est le mme.
L'arbre de plan termin est compos de parcours squentiels ou d'index des relations de base, auxquels s'ajoutent les nuds des
jointures en boucle, des jointures de tri fusionn et des jointures de hachage si ncessaire, ainsi que toutes les tapes auxiliaires ncessaires, telles que les nuds de tri ou les nuds de calcul des fonctions d'agrgat. La plupart des types de nud de plan ont la
capacit supplmentaire de faire une slection (rejet des lignes qui ne correspondent pas une condition boolenne indique) et
une projection (calcul d'un ensemble driv de colonnes fond sur des valeurs de colonnes donnes, par l'valuation d'expressions
scalaires si ncessaire). Une des responsabilits du planificateur est d'attacher les conditions de slection issues de la clause
WHERE et le calcul des expressions de sortie requises aux nuds les plus appropris de l'arbre de plan.

44.6. Excuteur
L'excuteur prend le plan cr par le planificateur/optimiseur et l'excute rcursivement pour extraire l'ensemble requis de lignes.
Il s'agit principalement d'un mcanisme de pipeline en demande-envoi. Chaque fois qu'un nud du plan est appel, il doit apporter
une ligne supplmentaire ou indiquer qu'il a fini d'envoyer des lignes.
Pour donner un exemple concret, on peut supposer que le nud suprieur est un nud MergeJoin. Avant de pouvoir faire une
fusion, deux lignes doivent tre rcupres (une pour chaque sous-plan). L'excuteur s'appelle donc rcursivement pour excuter
les sous-plans (en commenant par le sous-plan attach l'arbre gauche). Le nouveau nud suprieur (le nud suprieur du
sous-plan gauche) est, par exemple, un nud Sort (NdT : Tri) et un appel rcursif est une nouvelle fois ncessaire pour obtenir
une ligne en entre. Le nud fils de Sort pourrait tre un nud SeqScan, reprsentant la lecture relle d'une table. L'excution
de ce nud impose l'excuteur de rcuprer une ligne partir de la table et de la retourner au nud appelant. Le nud Sort appelle de faon rpte son fils pour obtenir toutes les lignes trier. Quand l'entre est puise (indiqu par le nud fils renvoyant
un NULL au lieu d'une ligne), le code de Sort est enfin capable de renvoyer sa premire ligne en sortie, c'est--dire le premier
suivant l'ordre de tri. Il conserve les lignes restantes en mmoire de faon les renvoyer dans le bon ordre en rponse des demandes ultrieures.
Le nud MergeJoin demande de la mme faon la premire ligne partir du sous-plan droit. Ensuite, il compare les deux
lignes pour savoir si elles peuvent tre jointes ; si c'est le cas, il renvoie la ligne de jointure son appelant. Au prochain appel, ou
immdiatement, s'il ne peut pas joindre la paire actuelle d'entres, il avance sur la prochaine ligne d'une des deux tables (suivant le
rsultat de la comparaison), et vrifie nouveau la correspondance. ventuellement, un des sous-plans est puis et le nud MergeJoin renvoie NULL pour indiquer qu'il n'y a plus de lignes jointes former.
Les requtes complexes peuvent ncessiter un grand nombre de niveaux de nuds pour les plans, mais l'approche gnrale est la
mme : chaque nud est excut et renvoie sa prochaine ligne en sortie chaque fois qu'il est appel. Chaque nud est responsable aussi de l'application de toute expression de slection ou de projection qui lui a t confie par le planificateur.
Le mcanisme de l'excuteur est utilis pour valuer les quatre types de requtes de base en SQL : SELECT, INSERT, UPDATE
et DELETE. Pour SELECT, le code de l'excuteur de plus haut niveau a uniquement besoin d'envoyer chaque ligne retourne par
l'arbre plan de la requte vers le client. Pour INSERT, chaque ligne renvoye est insre dans la table cible indique par
INSERT. Cela se fait dans un nud spcial haut niveau du plan appel ModifyTable. (Une simple commande INSERT ...
VALUES cre un arbre plan trivial constitu d'un seul nud, Result, calculant une seule ligne de rsultat, et ModifyTable
au-dessus pour raliser l'insertion. Mais INSERT ... SELECT peut demander la pleine puissance du mcanisme de l'excuteur.)
Pour UPDATE, le planificateur s'arrange pour que chaque ligne calcule inclue toutes les valeurs mises jour des colonnes, plus
le TID (tuple ID ou l'identifiant de la ligne) de la ligne de la cible originale ; cette donne est envoye dans un nud ModifyTable, qui utilise l'information pour crer une nouvelle ligne mise jour et marquer l'ancienne ligne comme supprime. Pour
DELETE, la seule colonne renvoye par le plan est le TID, et ModifyTable node utilise simplement le TID pour visiter chaque
ligne cible et la marquer comme supprime.

1225

Chapitre 45. Catalogues systme


Les catalogues systme reprsentent l'endroit o une base de donnes relationnelle stocke les mtadonnes des schmas, telles
que les informations sur les tables et les colonnes, et des donnes de suivi interne. Les catalogues systme de PostgreSQL
sont de simples tables. Elle peuvent tre supprimes et recres. Il est possible de leur ajouter des colonnes, d'y insrer et modifier des valeurs, et de mettre un joyeux bazar dans le systme. En temps normal, l'utilisateur n'a aucune raison de modifier les
catalogues systme, il y a toujours des commandes SQL pour le faire. (Par exemple, CREATE DATABASE insre une ligne
dans le catalogue pg_database -- et cre physiquement la base de donnes sur le disque.) Il y a des exceptions pour certaines
oprations particulirement sotriques, comme l'ajout de mthodes d'accs aux index.

45.1. Aperu
Tableau 45.1, Catalogues systme liste les catalogues systme. Une documentation plus dtaille des catalogues systme
suit.
La plupart des catalogues systme sont recopis de la base de donnes modle lors de la cration de la base de donnes et deviennent alors spcifiques chaque base de donnes. Un petit nombre de catalogues sont physiquement partags par toutes les
bases de donnes d'une installation de PostgreSQL. Ils sont indiqus dans les descriptions des catalogues.
Tableau 45.1. Catalogues systme

Nom du catalogue

Contenu

pg_aggregate

fonctions d'agrgat

pg_am

mthodes d'accs aux index

pg_amop

oprateurs des mthodes d'accs

pg_amproc

procdures de support des mthodes d'accs

pg_attrdef

valeurs par dfaut des colonnes

pg_attribute

colonnes des tables ( attributs )

pg_authid

identifiants d'autorisation (rles)

pg_auth_members

relations d'appartenance aux identifiants d'autorisation

pg_cast

conversions de types de donnes (cast)

pg_class

tables, index, squences, vues ( relations )

pg_constraint

contraintes de vrification, contraintes uniques, contraintes de cls primaires,


contraintes de cls trangres

pg_collation

collationnement (information locale)

pg_conversion

informations de conversions de codage

pg_database

bases de donnes du cluster PostgreSQL

pg_db_role_setting

configuration par rle et par base de donnes

pg_default_acl

droits par dfaut sur des types d'objets

pg_depend

dpendances entre objets de la base de donnes

pg_description

descriptions ou commentaires des objets de base de donnes

pg_enum

dfinitions des labels et des valeurs des enum

pg_extension

extensions installes

pg_foreign_data_wrapper

dfinitions des wrappers de donnes distantes

pg_foreign_server

dfinitions des serveurs distants

pg_foreign_table

informations supplmentaires sur les tables distantes

pg_index

informations supplmentaires des index

pg_inherits

hirarchie d'hritage de tables

pg_language

langages d'criture de fonctions

pg_largeobject

pages de donnes pour les Large Objects

pg_largeobject_metadata

mtadonnes pour les Large Objects


1226

Catalogues systme

Nom du catalogue

Contenu

pg_namespace

schmas

pg_opclass

classes d'oprateurs de mthodes d'accs

pg_operator

oprateurs

pg_opfamily

familles d'oprateurs de mthodes d'accs

pg_pltemplate

donnes modles pour les langages procduraux

pg_proc

fonctions et procdures

pg_rewrite

rgles de rcriture de requtes

pg_seclabel

labels de scurit sur les objets d'une base de donnes

pg_shdepend

dpendances sur les objets partags

pg_shdescription

commentaires sur les objets partags

pg_statistic

statistiques de l'optimiseur de requtes

pg_tablespace

tablespaces du cluster de bases de donnes

pg_trigger

dclencheurs

pg_ts_config

configuration de la recherche plein texte

pg_ts_config_map

configuration de la recherche plein texte pour la correspondance des lexmes (token)

pg_ts_dict

dictionnaires de la recherche plein texte

pg_ts_parser

analyseurs de la recherche plein texte

pg_ts_template

modles de la recherche plein texte

pg_type

types de donnes

pg_user_mapping

correspondance d'utilisateurs sur des serveurs distants

45.2. pg_aggregate
Le catalogue pg_aggregate stocke les informations concernant les fonctions d'agrgat. Une fonction d'agrgat est une fonction qui
opre sur un ensemble de donnes (typiquement une colonne de chaque ligne qui correspond une condition de requte) et retourne une valeur unique calcule partir de toutes ces valeurs. Les fonctions d'agrgat classiques sont sum (somme), count
(compteur) et max (plus grande valeur). Chaque entre de pg_aggregate est une extension d'une entre de pg_proc. L'entre de
pg_proc contient le nom de l'agrgat, les types de donnes d'entre et de sortie, et d'autres informations similaires aux fonctions
ordinaires.
Tableau 45.2. Les colonnes de pg_aggregate

Nom

Type

Rfrences

Description

aggfnoid

regproc

pg_proc.oid

OID pg_proc de la fonction d'agrgat

aggtransfn

regproc

pg_proc.oid

Fonction de transition

aggfinalfn

regproc

pg_proc.oid

Fonction finale (0 s'il n'y en a pas)

aggsortop

oid

.oi
pg_operatord

Oprateur de tri associ (0 s'il n'y en a pas)

aggtranstype

oid

pg_type.oid

Type de la donne interne de transition (tat) de la


fonction d'agrgat

agginitval

text

Valeur initiale de la fonction de transition. C'est un


champ texte qui contient la valeur initiale dans sa
reprsentation externe en chane de caractres. Si
ce champ est NULL, la valeur d'tat de transition
est initialement NULL.

Les nouvelles fonctions d'agrgat sont enregistres avec la commande CREATE AGGREGATE(7). La Section 35.10, Agrgats
utilisateur fournit de plus amples informations sur l'criture des fonctions d'agrgat et sur la signification des fonctions de transition.
1227

Catalogues systme

45.3. pg_am
Le catalogue pg_am stocke les informations concernant les mthodes d'accs aux index. On trouve une ligne par mthode d'accs
supporte par le systme. Le contenu de ce catalogue est discut en dtails dans Chapitre 52, Dfinition de l'interface des mthodes d'accs aux index.
Tableau 45.3. Colonnes de pg_am

Nom

Type

Rfrences

amname

name

Nom de la mthode d'accs

amstrategies

int2

Nombre de stratgies d'oprateur pour cette mthode d'accs, ou zro si la mthode d'accs n'a pas
un ensemble fixe de stratgies oprateurs

amsupport

int2

Nombre de routines de support pour cette mthode


d'accs

amcanorder

bool

La mthode d'accs supporte-t-elle les parcours ordonns par la valeur de la colonne indexe ?

amcanorderbyop

bool

La mthode d'accs supporte-t-elle les parcours ordonns par le rsultat d'un oprateur sur une colonne indexe ?

amcanbackward

bool

La mthode d'accs supporte-t-elle les parcours en


arrire ?

amcanunique

bool

La mthode d'accs supporte-t-elle les index


uniques ?

amcanmulticol

bool

La mthode d'accs supporte-t-elle les index multicolonnes ?

amoptionalkey

bool

La mthode d'accs supporte-t-elle un parcours


sans contrainte pour la premire colonne de
l'index ?

amsearchnulls

bool

La mthode d'accs supporte-t-elle les recherches


IS NULL/NOT NULL ?

amstorage

bool

Le type de donnes de stockage d'index peut-il diffrer du type de donnes de la colonne ?

amclusterable

bool

La commande CLUSTER peut-elle tre utilise


avec un index de ce type ?

ampredlocks

bool

Un index de ce type peut-il grer finement des verrous de prdicat ?

amkeytype

oid

pg_type.oid

Type de donne stocke dans l'index, ou zro si le


type n'est pas de taille fixe

aminsert

regproc

pg_proc.oid

Fonction insrer cette ligne

ambeginscan

regproc

pg_proc.oid

Fonction prparer un nouveau parcours

amgettuple

regproc

pg_proc.oid

Fonction prochaine ligne valide , ou zro si aucune

amgetbitmap

regproc

pg_proc.oid

Fonction rcuprer toutes les lignes valides

amrescan

regproc

pg_proc.oid

Fonction (re)dmarrer le parcours d'index

amendscan

regproc

pg_proc.oid

Fonction nettoyer aprs le parcours d'index

ammarkpos

regproc

pg_proc.oid

Fonction marquer la position actuelle du parcours

amrestrpos

regproc

pg_proc.oid

Fonction restaurer une position de parcours marque

ambuild

regproc

pg_proc.oid

Fonction construire un nouvel index

ambuildempty

regproc

pg_proc.oid

Fonction construire un index vide

ambulkdelete

regproc

pg_proc.oid

Fonction de destruction en masse

1228

Description

Catalogues systme

Nom

Type

Rfrences

Description

amvacuumcleanup

regproc

pg_proc.oid

Fonction de nettoyage post-VACUUM

amcostestimate

regproc

pg_proc.oid

Fonction d'estimation du cot de parcours d'un index

amoptions

regproc

pg_proc.oid

Fonction d'analyse et de validation du champ reloptions d'un index

45.4. pg_amop
Le catalogue pg_amop stocke les informations concernant les oprateurs associs aux familles d'oprateurs des mthodes d'accs
aux index. Il y a une ligne pour chaque oprateur membre d'une famille. Un membre d'une famille peut tre soit un oprateur de
recherche soit un oprateur de tri. Un oprateur peut apparatre dans plus d'une famille, mais ne peut pas apparatre dans plus
d'une position l'intrieur d'une famille.
Tableau 45.4. Colonnes de pg_amop

Nom

Type

Rfrences

Description

amopfamily

oid

.oi
pg_opfamilyd

La famille d'oprateur

amoplefttype

oid

pg_type.oid

Type de donnes en entre, ct gauche, de


l'oprateur

amoprighttype

oid

pg_type.oid

Type de donnes en entre, ct droit, de


l'oprateur

amopstrategy

int2

Numro de stratgie d'oprateur

amoppurpose

char

But de l'oprateur, soit s pour recherche soit o


pour tri

amopopr

oid

.oi
pg_operatord

OID de l'oprateur

amopmethod

oid

pg_am.oid

Mthode d'accs l'index pour cette famille


d'oprateur

amopsortfamily

oid

.oi
pg_opfamilyd

La famille d'oprateur B-tree utilise par cette entre pour trier s'il s'agit d'un oprateur de tri ; zro
s'il s'agit d'un oprateur de recherche

Un oprateur de recherche indique qu'un index de cet oprateur peut tre utilis pour rechercher toutes les lignes satisfaisant
une clause WHERE colonne_index oprateur constante. Cet oprateur doit videmment renvoyer un boolen et le
type de l'entre gauche doit correspondre au type de donnes de la colonne de l'index.
Un oprateur de tri indique qu'un index de cette famille d'oprateur peut tre parcouru pour renvoyer les lignes dans l'ordre reprsent par une clause ORDER BY colonne_index oprateur constante. Cet oprateur peut renvoyer tout type de
donnes triable, bien que le type de l'entre gauche doit correspondre au type de donnes de la colonne de l'index. La smantique
exacte de la clause ORDER BY est spcifi par la colonne amopsortfamily qui doit rfrencer une famille d'oprateur B-tree
pour le type de rsultat de l'oprateur.

Note
Actuellement, il est suppos que l'ordre de tri pour un oprateur de tri est celui par dfaut de la famille d'oprateur
rfrence, c'est--dire ASC NULLS LAST. Ceci pourrait changer en ajoutant des colonnes supplmentaires pour
y indiquer explicitement les options de tri.
Une entre dans amopmethod doit correspondre au opfmethod de sa famille d'oprateur parent (l'inclusion de amopmethod
ce niveau est une dnormalisation intentionnelle de la structure du catalogue pour des raisons de performance). De plus, amoplefttype et amoprighttype doivent correspondre aux champs oprleft et oprright de l'entre pg_operator rfrence.

45.5. pg_amproc
1229

Catalogues systme

Le catalogue pg_amproc stocke les informations concernant les procdures de support associes aux familles d'oprateurs de mthodes d'accs. Il y a une ligne pour chaque procdure de support appartenant une famille.
Tableau 45.5. Colonnes de pg_amproc

Nom

Type

Rfrences

Description

amprocfamily

oid

.oi
pg_opfamilyd

La famille d'oprateur

amproclefttype

oid

pg_type.oid

Type de donnes en entre, ct gauche, de


l'oprateur associ

amprocrighttype

oid

pg_type.oid

Type de donnes en entre, ct droit, de


l'oprateur associ

amprocnum

int2

amproc

regproc

Numro de procdure de support


pg_proc.oid

OID de la procdure

On interprte habituellement les champs amproclefttype et amprocrighttype comme identifiant les types de donnes
des cts gauche et droit d'oprateur(s) support(s) par une procdure particulire. Pour certaines mthodes d'accs, ils correspondent aux types de donnes en entre de la procdure elle-mme. Il existe une notion de procdures de support par dfaut
pour un index, procdures pour lesquelles amproclefttype et amprocrighttype sont tous deux quivalents l'opcintype de l'opclass de l'index.

45.6. pg_attrdef
Le catalogue pg_attrdef stocke les valeurs par dfaut des colonnes. Les informations principales des colonnes sont stockes dans
pg_attribute (voir plus loin). Seules les colonnes pour lesquelles une valeur par dfaut est explicitement indique (quand la table
est cre ou quand une colonne est ajoute) ont une entre dans pg_attrdef.
Tableau 45.6. Colonnes de pg_attrdef

Nom

Type

Rfrences

Description

adrelid

oid

pg_class.oid

La table laquelle appartient la colonne

adnum

int2

pg_attribute.attnum

Numro de la colonne

adbin

pg_node_tree

Reprsentation interne de la valeur par dfaut de la colonne

adsrc

text

Reprsentation lisible de la valeur par dfaut

Le champ adsrc est historique. Il est prfrable de ne pas l'utiliser parce qu'il ne conserve pas de trace des modifications qui
peuvent affecter la reprsentation de la valeur par dfaut. La compilation inverse du champ adbin (avec pg_get_expr par
exemple) est une meilleure faon d'afficher la valeur par dfaut.

45.7. pg_attribute
Le catalogue pg_attribute stocke les informations concernant les colonnes des tables. Il y a exactement une ligne de pg_attribute
par colonne de table de la base de donnes. (Il y a aussi des attributs pour les index et, en fait, tous les objets qui possdent des entres dans pg_class.)
Le terme attribut, quivalent colonne, est utilis pour des raisons historiques.
Tableau 45.7. Colonnes de pg_attribute

Nom

Type

Rfrences

Description

attrelid

oid

pg_class.oid

La table laquelle appartient la colonne

attname

name

atttypid

oid

attstattarget

int4

Le nom de la colonne
pg_type.oid

Le type de donnes de la colonne


Contrle le niveau de dtail des statistiques accumules pour la colonne par ANALYZE(7). Une

1230

Catalogues systme

Nom

Type

Rfrences

Description
valeur 0 indique qu'aucune statistique ne doit tre
collecte. Une valeur ngative indique d'utiliser
l'objectif de statistiques par dfaut. Le sens exact
d'une valeur positive dpend du type de donnes.
Pour les donnes scalaires, attstattarget est
la fois le nombre de valeurs les plus courantes collecter et le nombre d'histogrammes
crer.

attlen

int2

Une copie de pg_type.typlen pour le type de


la colonne.

attnum

int2

Le numro de la colonne. La numrotation des colonnes ordinaires dmarre 1. Les colonnes systme, comme les oid, ont des numros ngatifs
arbitraires.

attndims

int4

Nombre de dimensions, si la colonne est de type


tableau, sinon 0. (Pour l'instant, le nombre de dimensions des tableaux n'est pas contrl, donc une
valeur autre que 0 indique que c'est un
tableau .)

attcacheoff

int4

Toujours -1 sur disque, mais peut tre mis jour


lorsque la ligne est charge en mmoire, pour
mettre en cache l'emplacement de l'attribut dans la
ligne.

atttypmod

int4

Stocke des donnes spcifiques au type de donnes


prcis lors de la cration de la table (par exemple,
la taille maximale d'une colonne de type varchar).
Il est transmis aux fonctions spcifiques au type
d'entre de donnes et de vrification de taille. La
valeur est gnralement -1 pour les types de donnes qui n'ont pas besoin de atttypmod.

attbyval

bool

Une copie de pg_type.typbyval du type de la


colonne.

attstorage

char

Contient
normalement
une
copie
de
pg_type.typstorage du type de la colonne.
Pour les types de donnes TOASTables, cette valeur peut tre modifie aprs la cration de la colonne pour en contrler les rgles de stockage.

attalign

char

Une copie de pg_type.typalign du type de la


colonne.

attnotnull

bool

Indique une contrainte de non-nullit de colonne. Il


est possible de changer cette colonne pour activer
ou dsactiver cette contrainte.

atthasdef

bool

Indique que la colonne a une valeur par dfaut.


Dans ce cas, il y a une entre correspondante dans
le catalogue pg_attrdef pour dfinir cette valeur.

attisdropped

bool

Indique que la colonne a t supprime et n'est


plus valide. Une colonne supprime est toujours
prsente physiquement dans la table, mais elle est
ignore par l'analyseur de requte et ne peut tre
accde en SQL.

attislocal

bool

La colonne est dfinie localement dans la relation.


Une colonne peut tre simultanment dfinie localement et hrite.

attinhcount

int4

Nombre d'anctres directs de la colonne. Une colonne qui a au moins un anctre ne peut tre ni
supprime ni renomme.
1231

Catalogues systme

Nom

Type

Rfrences

Description

attcollation

oid

.o
Le collationnement dfini de la colonne, ou zro si
pg_collationid la colonne n'est pas un type de donnes collationnable.

attacl

aclitem[]

Droits d'accs niveau colonne, s'il y en a qui ont


t spcifiquement accords cette colonne

attoptions

text[]

Options au niveau colonne, en tant que chanes du


type motcl=valeur

Dans l'entre pg_attribute d'une colonne supprime, atttypid est rinitialise 0 mais attlen et les autres champs copis
partir de pg_type sont toujours valides. Cet arrangement est ncessaire pour s'adapter la situation o le type de donnes de la colonne supprime a t ensuite supprim et qu'il n'existe donc plus de ligne pg_type. attlen et les autres champs peuvent tre utiliss pour interprter le contenu d'une ligne de la table.

45.8. pg_authid
Le catalogue pg_authid contient les informations concernant les identifiants pour les autorisations d'accs aux bases de donnes
(rles). Un rle englobe les concepts d' utilisateur et de groupe . Un utilisateur est essentiellement un rle qui a l'attribut de
connexion (rolcanlogin). Tout rle (avec ou sans rolcanlogin) peut avoir d'autres rles comme membres ; voir
pg_auth_members.
Comme ce catalogue contient les mots de passe, il ne doit pas tre lisible par tout le monde. pg_roles est une vue, lisible par tout le
monde, de pg_authid qui masque le champ du mot de passe.
Chapitre 20, Rles de la base de donnes contient des informations dtailles sur les utilisateurs et sur la gestion des droits.
Comme l'identit des utilisateurs est identique pour tout le cluster de bases de donnes, pg_authid est partag par toutes les bases
du cluster ; il n'existe qu'une seule copie de pg_authid par cluster, non une par base de donnes.
Tableau 45.8. Colonnes de pg_authid

Nom

Type

Description

rolname

name

Nom du rle

rolsuper

bool

Le rle est superutilisateur

rolall

bool

Le rle hrite automatiquement des droits des rles dont il est


membre

rolcreaterole

bool

Le rle peut crer d'autres rles

rolcreatedb

bool

Le rle peut crer des bases de donnes

rolcatupdate

bool

Le rle peut mettre jour les catalogues systme directement.


(Mme un superutilisateur ne peut le faire si cette colonne
n'est pas true.)

rolcanlogin

bool

Le rle peut se connecter, c'est--dire qu'il peut tre donn


comme identifiant d'autorisation de session.

rolreplication

bool

Le rle est un rle de rplication, c'est--dire qu'il peut initier


une rplication en flux (voir Section 25.2.5, Streaming Replication ) et lancer/arrter le mode de sauvegarde systme
grce
aux
fonctions
pg_start_backup
et
pg_stop_backup.

rolconnlimit

int4

Pour les rles qui peuvent se connecter, indique le nombre


maximum de connexions concurrentes que le rle peut initier.
-1 signifie qu'il n'y a pas de limite.

rolpassword

text

Le mot de passe (ventuellement chiffr) ; NULL si aucun. Si


le mot de passe est chiffr, cette colonne commence par la
chane md5 suivi par un hachage md5 hexadcimal sur 32 caractres. Le hachage md5 correspondra au mot de passe de
l'utilisateur concatn son nom. Par exemple si l'utilisateur
joe a le mot de passe xyzzy, PostgreSQL enregistrera le
hachage md5 du mot xyzzyjoe). Un mot de passe qui ne
1232

Catalogues systme

Nom

Type

Description
suit pas ce format est suppos non chiffr.

timestamptz

rolvaliduntil

Date d'expiration du mot de passe (utilise uniquement pour


l'authentification par mot de passe) ; NULL si indfiniment
valable

45.9. pg_auth_members
Le catalogue pg_auth_members contient les relations d'appartenance entre les rles. Tout ensemble non circulaire d'appartenances
est autoris.
Parce que les identits de l'utilisateur sont valables sur l'ensemble du cluster, pg_auth_members est partag par toutes les bases de
donnes d'un cluster : il n'existe qu'une seule copie de pg_auth_members par cluster, pas une par base de donnes.
Tableau 45.9. Colonnes de pg_auth_members

Nom

Type

Rfrences

Description

roleid

oid

pg_authid.oid

Identifiant d'un rle qui a un membre

member

oid

pg_authid.oid

Identifiant d'un rle qui est membre d'un roleid

grantor

oid

pg_authid.oid

Identifiant du rle qui a autoris cette appartenance

admin_option

bool

Vrai si member peut donner l'appartenance roleid aux autres

45.10. pg_cast
Le catalogue pg_cast stocke les chemins de conversion de type de donne, qu'il s'agisse de ceux par dfaut ou ceux dfinis avec la
commande CREATE CAST(7).
pg_cast ne reprsente pas toutes les conversions de type que le systme connat, seulement celles qui ne peuvent pas se dduire
partir de rgles gnriques. Par exemple, la conversion entre un domaine et son type de base n'est pas reprsente explicitement
dans pg_cast. Autre exception importante : les conversions automatiques d'entre/sortie , celles ralises en utilisant les propres
fonctions d'entre/sortie du type de donnes pour convertir vers ou partir du text ou des autres types de chanes de caractres, ne
sont pas reprsentes explicitement dans pg_cast.
Tableau 45.10. Colonnes de pg_cast

Nom

Type

Rfrences

Description

castsource

oid

pg_type.oid

OID du type de donnes source

casttarget

oid

pg_type.oid

OID du type de donnes cible

castfunc

oid

pg_proc.oid

OID de la fonction utiliser pour raliser la


conversion. 0 si la mthode ne requiert pas une
fonction.

castcontext

char

Indique dans quel contexte la conversion peut tre


utilise. e si seules les conversions explicites sont
autorises (avec CAST ou ::). a si les conversions
implicites lors de l'affectation une colonne sont
autorises, en plus des conversions explicites. i si
les conversions implicites dans les expressions
sont autorises en plus des autres cas.

castmethod

char

Indique comment la conversion est effectue. f signifie que la fonction indique dans le champ
castfunc est utilise. i signifie que les fonctions d'entre/sortie sont utilises. b signifie que
les types sont binairement coercibles, et que par
consquent aucune conversion n'est ncessaire.

1233

Catalogues systme

Les fonctions de transtypage listes dans pg_cast doivent toujours prendre le type source de la conversion comme type du premier
argument et renvoyer le type de destination de la conversion comme type de retour. Une fonction de conversion peut avoir jusqu'
trois arguments. Le deuxime argument, s'il est prsent, doit tre de type integer ; il reoit le modificateur de type associ avec le
type de destination ou 1 s'il n'y en a pas. Le troisime argument, s'il est prsent, doit tre de type boolean ; il reoit true si la
conversion est une conversion explicite, false sinon.
Il est possible de crer une entre pg_cast dans laquelle les types source et cible sont identiques si la fonction associe prend plus
d'un argument. De telles entres reprsentent les fonctions de forage de longueur qui forcent la validit des valeurs de ce type
pour une valeur particulire du modificateur de type.
Quand une entre pg_cast possde des types diffrents pour la source et la cible et une fonction qui prend plus d'un argument, le
transtypage et le forage de longueur s'effectuent en une seule tape. Lorsqu'une telle entre n'est pas disponible, le forage vers
un type qui utilise un modificateur de type implique deux tapes, une de transtypage, l'autre pour appliquer le modificateur.

45.11. pg_class
Le catalogue pg_class liste les tables, et peu prs tout ce qui contient des colonnes ou ressemble de prs ou de loin une table.
Cela inclut les index (mais il faut aussi aller voir dans pg_index), les squences, les vues, les types composites et les tables
TOAST ; voir relkind. Par la suite, lorsque l'on parle de relation , on sous-entend tous ces types d'objets. Les colonnes ne
sont pas toutes significatives pour tous les types de relations.
Tableau 45.11. Colonnes de pg_class

Nom

Type

Rfrences

Description

relname

name

relnamespace

oid

pg_namespace.oid

OID du namespace qui contient la relation.

reltype

oid

pg_type.oid

OID du type de donnes qui correspond au type de ligne


de la table, s'il y en a un. 0 pour les index qui n'ont pas
d'entre dans pg_type.

reloftype

oid

pg_type.oid

Pour les tables types, l'OID du type composite sous-jacent. Sinon, 0 dans tous les autres cas.

relowner

oid

pg_authid.oid

Propritaire de la relation.

relam

oid

pg_am.oid

S'il s'agit d'un index, OID de la mthode d'accs utilise


(B-tree, hash, etc.)

relfilenode

oid

reltablespace

oid

relpages

int4

Taille du fichier disque, exprime en pages (de taille


BLCKSZ). Ce n'est qu'une estimation utilise par le planificateur. Elle est mise jour par les commandes VACUUM, ANALYZE et quelques commandes DDL
comme CREATE INDEX.

reltuples

float4

Nombre de lignes de la table. Ce n'est qu'une estimation


utilise par le planificateur. Elle est mise jour par les
commandes VACUUM, ANALYZE et quelques commandes DDL comme CREATE INDEX.

reltoastrelid

oid

pg_class.oid

OID de la table TOAST associe cette table. 0 s'il n'y


en a pas. La table TOAST stocke les attributs de grande
taille hors ligne dans une table secondaire.

reltoastidxid

oid

pg_class.oid

Pour une table TOAST, OID de son index. 0 si ce n'est


pas une table TOAST.

relhasindex

bool

Vrai si c'est une table et qu'elle possde (ou possdait encore rcemment) quelque index.

relisshared

bool

Vrai si cette table est partage par toutes les bases de

Nom de la table, vue, index, etc.

Nom du fichier disque de la relation ; zro signifie que


c'est une relation mapped dont le nom de fichier est
dtermin par un statut de bas niveau.
pg_tablespace.oid

1234

Le tablespace dans lequel est stock la relation. Si 0, il


s'agit du tablespace par dfaut de la base de donnes.
(Sans intrt si la relation n'est pas lie un fichier
disque.)

Catalogues systme

Nom

Type

Rfrences

Description
donnes du cluster. Seuls certains catalogues systme
(comme pg_database) sont partags.

relpersistence char

p = table permanente, u = table non trace dans les journaux de transactions, t = table temporaire

relkind

char

r = table ordinaire, i = index, S = squence, v = vue, c


= type composite, t = table TOAST, f = table distante.

relnatts

int2

Nombre de colonnes utilisateur dans la relation (sans


compter les colonnes systme). Il doit y avoir le mme
nombre d'entres dans pg_attribute. Voir aussi
pg_attribute.attnum.

relchecks

int2

Nombre de contraintes de vrification (CHECK) sur la


table ; voir le catalogue pg_constraint.

relhasoids

bool

Vrai si un OID est engendr pour chaque ligne de la relation.

relhaspkey

bool

Vrai si la table a (ou a eu) une cl primaire.

relhasrules

bool

Vrai si la table contient (ou a contenu) des rgles ; voir le


catalogue pg_rewrite.

relhastriggers bool

Vrai si la table a (ou a eu) des triggers ; voir le catalogue


pg_trigger

relhassubclass bool

Vrai si au moins une table hrite ou a hrit de la table


considre.

relfrozenxid

xid

Tous les ID de transaction avant celui-ci ont t remplacs par un ID de transaction permanent ( frozen ). Ceci
est utilis pour dterminer si la table doit tre nettoye
(VACUUM) pour viter un bouclage des ID de transaction (ID wraparound) ou pour compacter pg_clog. 0
(InvalidTransactionId) si la relation n'est pas une table.

relacl

aclitem[]

Droits d'accs ; voir GRANT(7) et REVOKE(7) pour


plus de dtails.

reloptions

text[]

Options spcifiques de la mthode d'accs, reprsentes


par des chanes du type motcl=valeur

Plusieurs des drapeaux boolens dans pg_class sont maintenus faiblement : la valeur true est garantie s'il s'agit du bon tat, mais
elle pourrait ne pas tre remise false immdiatement quand la condition n'est plus vraie. Par exemple, relhasindex est configure par CREATE INDEX mais n'est jamais remise false par DROP INDEX. C'est VACUUM qui le fera relhasindex s'il
dcouvre que la table n'a pas d'index. Cet arrangement vite des fentres de vulnrabilit et amliore la concurrence.

45.12. pg_constraint
Le catalogue pg_constraint stocke les vrifications, cls primaires, cls uniques, trangres et d'exclusion des tables. (Les
contraintes de colonnes ne sont pas traites de manire particulire. Elles sont quivalentes des contraintes de tables.) Les
contraintes NOT NULL sont reprsentes dans le catalogue pg_attribute, pas ici.
Les triggers de contraintes dfinies par des utilisateurs (crs avec CREATE CONSTRAINT TRIGGER) ont aussi une entre
dans cette table.
Les contraintes de vrification de domaine sont galement stockes dans ce catalogue.
Tableau 45.12. Colonnes de pg_constraint

Nom

Type

conname

name

connamespace

oid

contype

char

Rfrences

Description
Nom de
unique !)

la

contrainte

(pas

ncessairement

.o
OID du namespace qui contient la contrainte.
pg_namespaceid
c = contrainte de vrification, f = contrainte de cl
1235

Catalogues systme

Nom

Type

Rfrences

Description
trangre, p = contrainte de cl primaire, u =
contrainte d'unicit, t = contrainte trigger, x =
contrainte d'exclusion

condeferrable

bool

La contrainte peut-elle tre retarde (deferable) ?

condeferred

bool

La contrainte est-elle retarde par dfaut ?

convalidated

bool

La contrainte a-t-elle t valide ? actuellement,


peut seulement valoir false pour les cls trangres

conrelid

oid

pg_class.oid

Table laquelle appartient la contrainte ; 0 si ce


n'est pas une contrainte de table.

contypid

oid

pg_type.oid

Domaine auquel appartient la contrainte ; 0 si ce


n'est pas une contrainte de domaine.

conindid

oid

pg_class.oid

L'index qui force cette contrainte (unique, cl primaire, cl trangre, d'exclusion) ; sinon 0

confrelid

oid

pg_class.oid

Si c'est une cl trangre, la table rfrence ; sinon 0

confupdtype

char

Code de l'action de mise jour de la cl trangre :


a = no action, r = restrict, c = cascade, n = set
null, d = set default

confdeltype

char

Code de l'action de suppression de cl trangre :


a = no action, r = restrict, c = cascade, n = set
null, d = set default

confmatchtype

char

Type de concordance de la cl trangre : f = full,


p = partial, u = simple (non spcifi)

conislocal

bool

Cette contrainte est dfinie localement dans la relation. Notez qu'une contrainte peut tre dfinie localement et hrite simultanment

coninhcount

int4

Le nombre d'anctres d'hritage directs que cette


contraite possde. Une contrainte avec un nombre
non nul d'anctres ne peut tre ni supprime ni renomme.

conkey

int2[]

.a
tt
nu
pg_attributem

S'il s'agit d'une contrainte de table (incluant les


cls trangres mais pas les triggers de
contraintes), liste des colonnes contraintes

confkey

int2[]

.a
tt
nu
pg_attributem

S'il s'agit d'une cl trangre, liste des colonnes rfrences

conpfeqop

oid[]

.oi
pg_operatord

S'il s'agit d'une cl trangre, liste des oprateurs


d'galit pour les comparaisons cl primaire/cl
trangre

conppeqop

oid[]

.oi
pg_operatord

S'il s'agit d'une cl trangre, liste des oprateurs


d'galit pour les comparaisons cl primaire/cl
primaire

conffeqop

oid[]

.oi
pg_operatord

S'il s'agit d'une cl trangre, liste des oprateurs


d'galit pour les comparaisons cl trangre/cl
trangre

conexclop

oid[]

.oi
pg_operatord

Si une contrainte d'exclusion, liste les oprateurs


d'exclusion par colonne

conbin

pg_node_tree

S'il s'agit d'une contrainte de vrification, reprsentation interne de l'expression

consrc

text

S'il s'agit d'une contrainte de vrification, reprsentation comprhensible de l'expression


1236

Catalogues systme

Dans le cas d'une contrainte d'exclusion, conkey est seulement utile pour les lments contraints qui sont de simples rfrences
de colonnes. Dans les autres cas, un zro apparat dans conkey et l'index associ doit tre consult pour dcouvrir l'expression
contrainte. (du coup, conkey a le mme contenu que pg_index.indkey pour l'index.)

Note
consrc n'est pas actualis lors de la modification d'objets rfrencs ; par exemple, il ne piste pas les renommages
de colonnes. Plutt que se fier ce champ, il est prfrable d'utiliser pg_get_constraintdef() pour extraire
la dfinition d'une contrainte de vrification.

Note
pg_class.relchecks doit accepter le mme nombre de contraintes de vrification pour chaque relation.

45.13. pg_collation
Le catalogue pg_collation dcrit les collationnements disponibles, qui sont essentiellement des correspondances entre un nom
SQL et des catgories de locales du systme d'exploitation. Voir Section 22.2, Support des collations pour plus d'informations.
Tableau 45.13. Colonnes de pg_collation

Nom

Type

collname

name

Rfrences

Description

collnamespace

oid

pg_namespace.oid

L'OID du schma contenant ce


collationnement

collowner

oid

pg_authid.oid

Propritaire du collationnement

collencoding

int4

Encodage pour lequel le collationnement est disponible. -1


s'il fonctionne pour tous les encodages

collcollate

name

LC_COLLATE pour ce collationnement

collctype

name

LC_CTYPE pour ce collationnement

Nom
du
collationnement
(unique par schma et encodage)

Notez que la cl unique de ce catalogue est (collname, collencoding, collnamespace) et non pas seulement (collname, collnamespace). PostgreSQL ignore habituellement tous les collationnement qui n'ont pas de colonne collencoding gale soit l'encodage de la base de donnes en cours ou -1. La cration de nouvelles entres de mme nom qu'une autre
entre dont collencoding vaut -1 est interdite. Du coup, il suffit d'utiliser un nom SQL qualifi du schma (schma.nom)
pour identifier un collationnement bien que cela ne soit pas unique d'aprs la dfinition du catalogue. Ce catalogue a t dfini ainsi car initdb le remplit au moment de l'initialisation de l'instance avec les entres pour toutes les locales disponibles sur le systme,
donc il doit tre capable de contenir les entres de tous les encodages qui pourraient tre utiliss dans l'instance.
Dans la base de donnes template0, il pourrait tre utile de crer les collationnement dont l'encodage ne correspond pas
l'encodage de la base ded onnes car ils pourraient correspondre aux encodages de bases de donnes cres par la suite partir de
ce modle de base de donnes. Cela doit tre fait manuellement actuellement.

45.14. pg_conversion
Le catalogue pg_conversion dcrit les procdures de conversion de codage. Voir la commande CREATE CONVERSION(7) pour
plus d'informations.
Tableau 45.14. Colonnes de pg_conversion

Nom

Type

conname

name

Rfrences

Description
Nom de la conversion (unique au sein d'un names-

1237

Catalogues systme

Nom

Type

Rfrences

Description
pace)

connamespace

oid

.o
OID du namespace qui contient la conversion.
pg_namespaceid

conowner

oid

pg_authid.oid

conforencoding

int4

ID du codage source

contoencoding

int4

ID du codage de destination

conproc

regproc

condefault

bool

pg_proc.oid

Propritaire de la conversion

Procdure de conversion
Vrai s'il s'agit de la conversion par dfaut

45.15. pg_database
Le catalogue pg_database stocke les informations concernant les bases de donnes disponibles. Celles-ci sont cres avec la commande CREATE DATABASE(7). Consulter le Chapitre 21, Administration des bases de donnes pour les dtails sur la signification de certains paramtres.
Contrairement la plupart des catalogues systme, pg_database est partag par toutes les bases de donnes d'un cluster : il n'y a
qu'une seule copie de pg_database par cluster, pas une par base.
Tableau 45.15. Colonnes de pg_database

Nom

Type

Rfrences

Description

datname

name

datdba

oid

encoding

int4

Encodage de la base de donnes (la fonction


pg_encoding_to_char() peut convertir ce nombre
en nom de l'encodage)

datcollate

name

LC_COLLATE pour cette base de donnes

datctype

name

LC_CTYPE pour cette base de donnes

datistemplate

bool

Si ce champ est vrai, alors la base peut tre utilise dans


la clause TEMPLATE de la commande CREATE DATABASE pour crer une nouvelle base comme clone de
celle-ci.

datallowconn

bool

Si ce champ est faux, alors personne ne peut se connecter


cette base de donnes. Ceci est utilis pour interdire
toute modification de la base template0.

datconnlimit

int4

Nombre maximum de connexions concurrentes autorises sur la base de donnes. -1 indique l'absence de limite.

datlastsysoid

oid

Dernier OID systme de la base de donnes ; utile en particulier pour pg_dump.

datfrozenxid

xid

Tous les ID de transaction avant celui-ci ont t remplacs par un ID de transaction permanent ( frozen ). Ceci
est utilis pour dterminer si la table doit tre nettoye
(VACUUM) pour viter un bouclage des ID de transaction (ID wraparound) ou pour compacter pg_clog.
C'est la valeur minimale des valeurs par table de
pg_class.relfrozenxid.

dattablespace

oid

datacl

aclitem[]

Nom de la base de donnes


Propritaire de la base, gnralement l'utilisateur qui l'a
cre

pg_authid.oid

pg_tablespace.oid

Le tablespace par dfaut de la base de donnes. Dans


cette base de donnes, toutes les tables pour lesquelles
pg_class.reltablespace vaut 0 sont stockes dans
celui-ci ; en particulier, tous les catalogues systme non
partags s'y trouvent.
Droits d'accs ; voir GRANT(7) et REVOKE(7) pour les

1238

Catalogues systme

Nom

Type

Rfrences

Description
dtails.

45.16. pg_db_role_setting
Le catalogue pg_db_role_setting enregistre les valeurs par dfaut qui ont t configures pour les variables de configuration, pour
chaque combinaison de rle et de base.
Contrairement la plupart des catalogues systmes, pg_db_role_setting est partag parmi toutes les bases de donnes de
l'instance : il n'existe qu'une copie de pg_db_role_setting par instance, pas une par base de donnes.
Tableau 45.16. Colonnes de pg_db_role_setting

Nom

Type

Rfrences

Description

setdatabase

oid

pg_database.oid

L'OID de la base de donnes


pour laquelle la configuration
est applicable ; zro si cette
configuration n'est pas spcifique une base de donnes

setrole

oid

pg_authid.oid

L'OID du rle pour laquelle la


configuration est applicable ;
zro si cette configuration n'est
pas spcifique un rle

setconfig

text[]

Valeurs par dfaut pour les variables de configuration

45.17. pg_default_acl
Le catalogue pg_default_acl enregistre les droits initiaux affecter aux nouveaux objets crs.
Tableau 45.17. Colonnes de pg_default_acl

Nom

Type

Rfrences

Description

defaclrole

oid

pg_authid.oid

OID du rle associ cette entre

defaclnamespace

oid

pg_namespace.oid

OID du schma associ cette


entre, 0 si aucun

defaclobjtype

char

Type de l'objet pour cette entre : r = relation (table, vue),


S = squence, f = fonction

defaclacl

aclitem[]

Droits d'accs qu'auront les


nouveaux objets de ce type

Une entre pg_default_acl affiche les droits initiaux affects un objet appartenant l'utilisateur indiqu. Il existe actuellement
deux types d'entres : des entres globales avec defaclnamespace = 0, et des entres par schma qui rfrencent un
schma. Si une entre globale est prsente, alors elle surcharge les droits par dfaut cods en dur pour le type de l'objet. Une entre par schma, si prsente, reprsente les droits ajouter aux droits par dfaut globaux ou aux droits cods en dur.
Notez que quand une entre de droits (ACL) dans un autre catalogue est NULL, cela veut dire que les droits par dfaut cods en
dur sont utiliss pour cet objet, et non pas ce qui pourrait tre dans pg_default_acl ce moment. pg_default_acl est seulement
consult durant la cration de l'objet.

45.18. pg_depend
Le catalogue pg_depend enregistre les relations de dpendances entre les objets de la base de donnes. Cette information permet
la commande DROP de trouver les objets qui doivent tre supprims conjointement par la commande DROP CASCADE ou au
contraire empchent la suppression dans le cas de DROP RESTRICT.
1239

Catalogues systme

Voir aussi pg_shdepend, qui remplit la mme fonction pour les dpendances impliquant des objets partags sur tout le cluster.
Tableau 45.18. Colonnes de pg_depend

Nom

Type

Rfrences

Description

classid

oid

pg_class.oid

OID du catalogue systme dans lequel l'objet dpendant se trouve.

objid

oid

toute colonne OID

OID de l'objet dpendant

objsubid

int4

refclassid

oid

pg_class.oid

OID du catalogue systme dans lequel l'objet rfrenc se trouve.

refobjid

oid

toute colonne OID

OID de l'objet rfrenc

refobjsubid

int4

Pour une colonne de table, ce champ indique le numro de colonne (les champs refobjid et refclassid font rfrence la table elle mme).
Pour tous les autres types d'objets, cette colonne
est 0.

deptype

char

Code dfinissant la smantique particulire de la


relation de dpendance. Voir le texte.

Pour une colonne de table, ce champ indique le numro de colonne (les champs objid et classid
font rfrence la table elle-mme). Pour tous les
autres types d'objets, cette colonne est 0.

Dans tous les cas, une entre de pg_depend indique que l'objet de rfrence ne peut pas tre supprim sans supprimer aussi l'objet
dpendant. Nanmoins, il y a des nuances, identifies par deptype :
DEPENDENCY_NORMAL (n)
Une relation normale entre des objets crs sparment. L'objet dpendant peut tre supprim sans affecter l'objet rfrenc.
Ce dernier ne peut tre supprim qu'en prcisant l'option CASCADE, auquel cas l'objet dpendant est supprim lui-aussi.
Exemple : une colonne de table a une dpendance normale avec ses types de donnes.
DEPENDENCY_AUTO (a)
L'objet dpendant peut tre supprim sparment de l'objet rfrenc, mais il l'est automatiquement avec la suppression de ce
dernier, quel que soit le mode RESTRICT ou CASCADE. Exemple : une contrainte nomme sur une table est auto-dpendante
de la table, elle est automatiquement supprime avec celle-ci.
DEPENDENCY_INTERNAL (i)
L'objet dpendant est cr conjointement l'objet rfrenc et fait partie intgrante de son implantation interne. Un DROP de
l'objet dpendant est interdit (l'utilisateur est averti qu'il peut effectuer un DROP de l'objet rfrenc la place). La suppression de l'objet rfrenc est propage l'objet dpendant que CASCADE soit prcis ou non. Exemple : un trigger cr pour
vrifier une contrainte de cl trangre est rendu dpendant de l'entre de la contrainte dans pg_constraint.
DEPENDENCY_EXTENSION (e)
L'objet dpendant est un membre de l'extension qui est l'objet rfrenc (voir pg_extension). L'objet dpendant peut tre supprim seulement via l'instruction DROP EXTENSION sur l'objet rfrence. Fonctionnellement, ce type de dpendance agit
de la mme faon qu'une dpendance interne mais il est spar pour des raisons de clart et pour simplifier pg_dump.
DEPENDENCY_PIN (p)
Il n'y a pas d'objet dpendant ; ce type d'entre signale que le systme lui-mme dpend de l'objet rfrenc, et donc que
l'objet ne doit jamais tre supprim. Les entres de ce type sont cres uniquement par initdb. Les colonnes de l'objet dpendant contiennent des zros.
D'autres types de dpendance peuvent apparatre dans le futur.

45.19. pg_description
Le catalogue pg_description stocke les descriptions (commentaires) optionnelles de chaque objet de la base de donnes. Les descriptions sont manipules avec la commande COMMENT(7) et lues avec les commandes \d de psql. pg_description contient les
descriptions prdifinies de nombreux objets internes.
Voir aussi pg_shdescription, qui offre la mme fonction pour les descriptions des objets partags au sein d'un cluster.
1240

Catalogues systme

Tableau 45.19. Colonnes de pg_description

Nom

Type

Rfrences

Description

objoid

oid

toute colonne OID

OID de l'objet comment

classoid

oid

pg_class.oid

OID du catalogue systme dans lequel apparat


l'objet

objsubid

int4

Pour un commentaire de colonne de table, le numro de la colonne. Les champs objoid et


classoid font rfrence la table elle-mme.
Pour tous les autres types de donnes, cette colonne est 0.

description

text

Texte quelconque commentant l'objet

45.20. pg_enum
Le catalogue systme pg_enum contient des entres indiquant les valeurs et labels de chaque type enum. La reprsentation interne
d'une valeur enum donne est en fait l'OID de sa ligne associe dans pg_enum.
Tableau 45.20. Colonnes de pg_enum

Nom

Type

Rfrences

Description

enumtypid

oid

pg_type.oid

OID de l'entre pg_type correspondant cette valeur d'enum

enumsortorder

float4

La position de tri de cette valeur enum dans son


type enum

enumlabel

name

Le label texte pour cette valeur d'enum

Les OID des lignes de pg_enum suivent une rgle spciale : les OID pairs sont garantis tris de la mme faon que l'ordre de tri de
leur type enum. Autrement dit, si deux OID pairs appartiennent au mme type enum, l'OID le plus petit doit avoir la plus petite valeur dans la colonne enumsortorder. Les valeurs d'OID impaires n'ont pas d'ordre de tri. Cette rgle permet que les routines de
comparaison d'enum vitent les recherches dans les catalogues dans la plupart des cas standards. Les routines qui crent et modifient les types enum tentent d'affecter des OID paires aux valeurs enum tant que c'est possible.
Quand un type enum est cr, ses membres sont affects dans l'ordre des positions 1..n. Les membres ajouts par la suite doivent
se voir affecter des valeurs ngatives ou fractionnelles de enumsortorder. Le seul prrequis pour ces valeurs est qu'elles soient
correctement tries et uniques pour chaque type enum.

45.21. pg_extension
Le catalogue pg_extension stocke les informations sur les extensions installes. Voir Section 35.15, Empaqueter des objets dans
une extension pour des dtails sur les extensions.
Tableau 45.21. Colonnes de pg_extension

Nom

Type

Rfrences

Description

extname

name

extowner

oid

pg_authid.oid

Propritaire de l'extension

extnamespace

oid

pg_namespace.oid

Schma contenant les objets


exports de l'extension

extrelocatable

bool

True si l'extension peut tre dplace dans un autre schma

extversion

text

Nom de
l'extension

extconfig

oid[]

Nom de l'extension

pg_class.oid

1241

la

version

de

Tableaux d'OID de type regclass pour la table de configu-

Catalogues systme

Nom

Type

Rfrences

Description
ration de l'extension, ou NULL
si aucun

extcondition

text[]

Tableau de conditions de filtre


(clauses WHERE) pour la table
de configuration de l'extension,
ou NULL si aucun

Notez que, contrairement aux autres catalogues ayant une colonne de schma , extnamespace n'est pas le schma contenant
l'extension. Les noms des extensions ne sont jamais qualifis d'un schma. En fait, extnamespace indique le schma qui
contient la plupart ou tous les objets de l'extension. Si extrelocatable vaut true, alors ce schma doit en fait contenir tous les
objets de l'extension, dont le nom peut tre qualifi avec le nom du schma.

45.22. pg_foreign_data_wrapper
Le catalogue pg_foreign_data_wrapper stocke les dfinitions des wrappers de donnes distantes. Un wrapper de donnes distantes
est le mcanisme par lequel des donnes externes, stockes sur des serveurs distants, sont accdes.
Tableau 45.22. Colonnes de pg_foreign_data_wrapper

Nom

Type

Rfrences

Description

fdwname

name

fdwowner

oid

pg_authid.oid

Propritaire du wrapper de
donnes distantes

fdwhandler

oid

pg_proc.oid

Rfrence une fonction de gestion responsable de la fourniture de routines d'excution


pour le wrapper de donnes
distantes. Zro si aucune fonction n'est fournie.

fdwvalidator

oid

pg_proc.oid

Rfrence le validateur de
fonction qui est responsable de
vrifier la validit des options
passes au wrapper de donnes
distantes, ainsi que les options
des serveurs distants et les correspondances utilisateurs du
wrapper de donnes distantes.
Zro si aucun validateur n'est
fourni.

fdwacl

aclitem[]

Droits
d'accs
;
voir
GRANT(7) et REVOKE(7)
pour plus de dtails

fdwoptions

text[]

Options spcifiques pour un


wrapper de donnes distantes,
sous la forme de chanes
motcl=valeur

Nom du wrapper de donnes


distantes

45.23. pg_foreign_server
Le catalogue pg_foreign_server stocke les dfinitions de serveurs distants. Un serveur distant dcrit une source de donnes externes, comme un serveur distant. Les serveurs distants sont accds via des wrappers de donnes distantes.
Tableau 45.23. Colonnes pg_foreign_server

1242

Catalogues systme

Nom

Type

Refrence

Description

srvname

name

srvowner

oid

pg_authid.oid

srvfdw

oid

pg_foreign_data_wrapp OID du wrapper de donnes


er.oid
distantes pour ce serveur distant

srvtype

text

Type du serveur (optionnel)

srvversion

text

Version du serveur (optionnel)

srvacl

aclitem[]

Droits
d'accs
;
voir
GRANT(7) et REVOKE(7)
pour les dtails

srvoptions

text[]

Options pour le serveur distant,


sous la forme de chanes
motcl=valeur .

Nom du serveur distant


Propritaire du serveur distant

45.24. pg_foreign_table
Le catalogue pg_foreign_table contient des informations supplmentaires sur les tables distantes. Une table distante est principalement reprsente par une entre dans le catalogue pg_class, comme toute table ordinaire. Son entre dans pg_foreign_table
contient les informations pertinentes aux seules tables distantes, et pas aux autres types de relation.
Tableau 45.24. Colonnes de pg_foreign_table

Nom

Type

Rfrences

Description

ftrelid

oid

pg_class.oid

OID de l'entre dans le catalogue pg_class pour cette table


distante

ftserver

oid

pg_foreign_server.oid OID du serveur distant pour


cette table distante

ftoptions

text[]

Options de la table distante,


sous la forme de chanes
cl=valeur

45.25. pg_index
Le catalogue pg_index contient une partie des informations concernant les index. Le reste se trouve pour l'essentiel dans pg_class.
Tableau 45.25. Colonnes de pg_index

Nom

Type

Rfrences

Description

indexrelid

oid

pg_class.oid

OID de l'entre dans pg_class de l'index

indrelid

oid

pg_class.oid

OID de l'entre dans pg_class de la table sur laquelle


porte l'index

indnatts

int2

Nombre
de
colonnes
pg_class.relnatts)

indisunique

bool

Vrai s'il s'agit d'un index d'unicit

indisprimary

bool

Vrai s'il s'agit de l'index de cl primaire de la table (indisunique doit toujours tre vrai quand ce champ
l'est.)

indisexclusion bool

Vrai s'il s'agit de l'index supportant une contrainte


d'exclusion

bool

Si vrai, la vrification de l'unicit est force immdiatement lors de l'insertion (inutile si indisunique ne
vaut pas true)

indimmediate

1243

de

l'index

(duplique

Catalogues systme

Nom

Type

Rfrences

Description

indisclustered bool

Vrai si la table a t rorganise en fonction de l'index

indisvalid

bool

Si vrai, l'index est valide pour les requtes. Faux signifie


que l'index peut tre incomplet : les oprations INSERT/
UPDATE peuvent toujours l'utiliser, mais il ne peut pas
tre utilis sans risque pour les requtes, et, dans le cas
d'un index d'unicit, celle-ci n'est plus non-plus garantie.

indcheckxmin

bool

Si vrai, les requtes ne doivent pas utiliser l'index tant


que le xmin de cette ligne de pg_index est en-dessous de
leur horizon d'vnements TransactionXmin, car la table
peut contenir des chanes HOT casses avec des lignes
incompatibles qu'elles peuvent voir.

indisready

bool

Si vrai, l'index est actuellement prt pour les insertions.


Faux indique que l'index doit tre ignor par les oprations INSERT/UPDATE

indkey

int2vector

pg_attribute.attnum

C'est un tableau de valeurs indnatts qui indique les


colonnes de la table indexes. Par exemple, une valeur 1
3 signifie que la premire et la troisime colonne de la
table composent la cl de l'index. Un 0 dans ce tableau
indique que l'attribut de l'index correspondant est une expression sur les colonnes de la table plutt qu'une simple
rfrence de colonne.

indcollation

oidvector

pg_collation.oid

Pour chaque colonne dans la cl de l'index, cette colonne


contient l'OID du collationnement utiliser pour l'index.

indclass

oidvector

pg_opclass.oid

Pour chaque colonne de la cl d'indexation, contient


l'OID de la classe d'oprateur utiliser. Voir pg_opclass
pour plus de dtails.

indoption

int2vector

C'est un tableau de valeurs indnatts qui enregistrent


des drapeaux d'information par colonne. La signification
de ces drapeaux est dfinie par la mthode d'accs
l'index.

indexprs

pg_node_tree

Arbres d'expression (en reprsentation nodeToString()) pour les attributs d'index qui ne sont pas de
simples rfrences de colonnes. Il s'agit d'une liste qui
contient un lment par entre 0 dans indkey. Nul si
tous les attributs d'index sont de simples rfrences.

indpred

pg_node_tree

Arbre d'expression (en reprsentation nodeToString()) pour les prdicats d'index partiels. Nul s'il ne
s'agit pas d'un index partiel.

45.26. pg_inherits
Le catalogue pg_alls enregistre l'information sur la hirarchie d'hritage des tables. Il existe une entre pour chaque table enfant
direct dans la base de donnes. (L'hritage indirect peut tre dtermin en suivant les chanes d'entres.)
Tableau 45.26. Colonnes de pg_alls

Nom

Type

Rfrences

Description

inhrelid

oid

pg_class.oid

OID de la table fille

inhparent

oid

pg_class.oid

OID de la table mre

inhseqno

int4

S'il y a plus d'un parent direct pour une table fille


(hritage multiple), ce nombre indique dans quel
ordre les colonnes hrites doivent tre arranges.
Le compteur commence 1.

1244

Catalogues systme

45.27. pg_language
Le catalogue pg_language enregistre les langages utilisables pour l'criture de fonctions ou procdures stockes. Voir CREATE
LANGUAGE(7) et dans le Chapitre 38, Langages de procdures pour plus d'information sur les gestionnaires de langages.
Tableau 45.27. Colonnes de pg_language

Nom

Type

Rfrences

Description

lanname

name

lanowner

oid

lanispl

bool

Faux pour les langages internes (comme SQL) et


vrai pour les langages utilisateur. l'heure actuelle, pg_dump utilise ce champ pour dterminer
les langages sauvegarder mais cela peut tre un
jour remplac par un mcanisme diffrent.

lanpltrusted

bool

Vrai s'il s'agit d'un langage de confiance (trusted),


ce qui signifie qu'il est suppos ne pas donner accs ce qui dpasse l'excution normale des requtes SQL. Seuls les superutilisateurs peuvent
crer des fonctions dans des langages qui ne sont
pas dignes de confiance.

lanplcallfoid

oid

pg_proc.oid

Pour les langages non-internes, ceci rfrence le


gestionnaire de langage, fonction spciale en
charge de l'excution de toutes les fonctions crites
dans ce langage.

laninline

oid

pg_proc.oid

Ceci rfrence une fonction qui est capable


d'excuter des blocs de code anonyme en ligne
(blocs DO(7)). Zro si les blocs en ligne ne sont
pas supports

lanvalidator

oid

pg_proc.oid

Ceci rfrence une fonction de validation de langage, en charge de vrifier la syntaxe et la validit
des nouvelles fonctions lors de leur cration. 0 si
aucun validateur n'est fourni.

lanacl

aclitem[]

Nom du langage
pg_authid.oid

Propritaire du langage

Droits d'accs ;; voir GRANT(7) et REVOKE(7)


pour les dtails.

45.28. pg_largeobject
Le catalogue pg_largeobject contient les donnes qui dcrivent les objets volumineux (large objects). Un objet volumineux est
identifi par un OID qui lui est affect lors de sa cration. Chaque objet volumineux est coup en segments ou pages suffisamment petits pour tre facilement stocks dans des lignes de pg_largeobject. La taille de donnes par page est dfinie par LOBLKSIZE, qui vaut actuellement BLCKSZ/4, soit habituellement 2 Ko).
Avant PostgreSQL 9.0, il n'existait pas de droits associs aux Large Objects . Du coup, pg_largeobject tait lisible par tout le
monde et pouvait tre utilis pour obtenir les OID (et le contenu) de tous les Large Objects du systme. Ce n'est plus le cas ;
utilisez pg_largeobject_metadata pour obtenir une liste des OID des Large Objects .
Tableau 45.28. Colonnes de pg_largeobject

Nom

Type

References

Description

loid

oid

pg_largeobject_metadata.oid

Identifiant de l'objet volumineux qui contient la page

pageno

int4

Numro de la page au sein


de l'objet volumineux, en
partant de 0

data

bytea

Donnes effectivement stockes dans l'objet volumineux. Il ne fait jamais plus


1245

Catalogues systme

Nom

Type

References

Description
de LOBLKSIZE mais peut
faire moins.

Chaque ligne de pg_largeobject contient les donnes d'une page de l'objet volumineux, en commenant au dcalage d'octet (pageno * LOBLKSIZE) dans l'objet. Ceci permet un stockage diffus : des pages peuvent manquer, d'autres faire moins de LOBLKSIZE octets mme s'il ne s'agit pas de la dernire de l'objet. Les parties manquantes sont considres comme des suites de zro.

45.29. pg_largeobject_metadata
Le catalogue pg_largeobject_metadata contient des mta-donnes associes aux Larges Objects . Les donnes des Larges Objects sont rellement stockes dans pg_largeobject.
Tableau 45.29. Colonnes de pg_largeobject_metadata

Nom

Type

Description

lomowner

oid

pg_authid.oid

lomacl

aclitem[]

45.30. pg_namespace
Le catalogue pg_namespace stocke les namespace. Un namespace est la structure sous-jacente aux schmas SQL : chaque namespace peut contenir un ensemble spar de relations, types, etc. sans qu'il y ait de conflit de nommage.
Tableau 45.30. Colonnes de pg_namespace

Nom

Type

nspname

name

nspowner

oid

nspacl

aclitem[]

Rfrences

Description
Nom du namespace

pg_authid.oid

Propritaire du namespace
Droits d'accs ; voir GRANT(7) et REVOKE(7)
pour les dtails.

45.31. pg_opclass
Le catalogue pg_opclass dfinit les classes d'oprateurs de mthodes d'accs aux index. Chaque classe d'oprateurs dfinit la smantique pour les colonnes d'index d'un type particulier et d'une mthode d'accs particulire. Une classe d'oprateur dfinit essentiellement qu'une famille d'oprateur particulier est applicable un type de donnes indexable particulier. L'ensemble des oprateurs de la famille actuellement utilisables avec la colonne indexe sont tous ceux qui acceptent le type de donnes de la colonne
en tant qu'entre du ct gauche.
Les classes d'oprateurs sont longuement dcrites dans la Section 35.14, Interfacer des extensions d'index .
Tableau 45.31. Colonnes de pg_opclass

Nom

Type

Rfrences

Description

opcmethod

oid

pg_am.oid

Mthode d'accs l'index pour laquelle est dfinie


la classe d'oprateurs

opcname

name

opcnamespace

oid

.o
Namespace de la classe d'oprateurs
pg_namespaceid

opcowner

oid

pg_authid.oid

Propritaire de la classe d'oprateurs

opcfamily

oid

.oi
pg_opfamilyd

Famille d'oprateur contenant la classe d'oprateur

opcintype

oid

pg_type.oid

Type de donnes que la classe d'oprateurs indexe

Nom de la classe d'oprateurs

1246

Catalogues systme

Nom

Type

opcdefault

bool

opckeytype

oid

Rfrences

Description
Vrai si la classe d'oprateurs est la classe par dfaut pour opcintype

pg_type.oid

Type de donnes stock dans l'index ou 0 s'il s'agit


du mme que opcintype

L'opcmethod d'une classe d'oprateurs doit concider avec l'opfmethod de la famille d'oprateurs qui le contient. Il ne doit pas
non plus y avoir plus d'une ligne pg_opclass pour laquelle opcdefault est vrai, quelque soit la combinaison de opcmethod et opcintype.

45.32. pg_operator
Le catalogue pg_operator stocke les informations concernant les oprateurs. Voir la commande CREATE OPERATOR(7) et la
Section 35.12, Oprateurs dfinis par l'utilisateur pour plus d'informations.
Tableau 45.32. Colonnes de pg_operator

Nom

Type

oprname

name

Rfrences

Description

oprnamespace

oid

.o
OID du namespace qui contient l'oprateur
pg_namespaceid

oprowner

oid

pg_authid.oid

oprkind

char

b = infix ( les deux ), l = prefix ( gauche ), r


= postfix ( droit )

oprcanmerge

bool

L'oprateur supporte les jointures de fusion

oprcanhash

bool

L'oprateur supporte les jointures par dcoupage

oprleft

oid

pg_type.oid

Type de l'oprande de gauche

oprright

oid

pg_type.oid

Type de l'oprande de droite

oprresult

oid

pg_type.oid

Type du rsultat

oprcom

oid

.oi
pg_operatord

Commutateur de l'oprateur, s'il existe

oprnegate

oid

.oi
pg_operatord

Ngateur de l'oprateur, s'il existe

oprcode

regproc

pg_proc.oid

Fonction codant l'oprateur

oprrest

regproc

pg_proc.oid

Fonction d'estimation de la slectivit de restriction de l'oprateur

oprjoin

regproc

pg_proc.oid

Fonction d'estimation de la slectivit de jointure


de l'oprateur

Nom de l'oprateur

Propritaire de l'oprateur

Les colonnes inutilises contiennent des zros. oprleft vaut, par exemple, 0 pour un oprateur prfixe.

45.33. pg_opfamily
Le catalogue pg_opfamily dfinit les familles d'oprateur. Chaque famille d'oprateur est un ensemble d'oprateurs et de routines
de support associes codant les smantiques dfinies pour une mthode d'accs particulire de l'index. De plus, les oprateurs
d'une famille sont tous compatibles , au sens dfini par la mthode d'accs. Le concept de famille d'oprateur autorise
l'utilisation des oprateurs inter-type de donnes avec des index et l'utilisation des smantiques de mthode d'accs.
Les familles d'oprateur sont dcrites dans Section 35.14, Interfacer des extensions d'index .
Tableau 45.33. Colonnes de pg_opfamily

Nom

Type

Rfrences

Description

opfmethod

oid

pg_am.oid

Mthode d'accs l'index pour la famille


d'oprateur

1247

Catalogues systme

Nom

Type

Rfrences

Description

opfname

name

opfnamespace

oid

.o
namespace de la famille d'oprateur
pg_namespaceid

opfowner

oid

pg_authid.oid

Nom de la famille d'oprateur

Propritaire de la famille d'oprateur

La majorit des informations dfinissant une famille d'oprateur n'est pas dans la ligne correspondante de pg_opfamily mais dans
les lignes associes de pg_amop, pg_amproc, et pg_opclass.

45.34. pg_pltemplate
Le catalogue pg_pltemplate stocke les informations squelettes ( template ) des langages procduraux. Un squelette de langage
permet la cration de ce langage dans une base de donnes particulire l'aide d'une simple commande CREATE LANGUAGE,
sans qu'il soit ncessaire de spcifier les dtails de l'implantation.
Contrairement la plupart des catalogues systme, pg_pltemplate est partag par toutes les bases de donnes d'un cluster : il
n'existe qu'une seule copie de pg_pltemplate par cluster, et non une par base de donnes. L'information est de ce fait accessible
toute base de donnes.
Tableau 45.34. Colonnes de pg_pltemplate

Nom

Type

Description

tmplname

name

Nom du langage auquel est associ le modle

tmpltrusted

boolean

True s'il s'agit d'un langage de confiance

tmpldbacreate

boolean

True s'il s'agit d'un langage cr par le propritaire de la base

tmplhandler

text

Nom de la fonction de gestion des appels

tmplinline

text

Nom de la fonction de gestion des blocs anonymes. NULL sinon

tmplvalidator

text

Nom de la fonction de validation, ou NULL si aucune

tmpllibrary

text

Chemin de la bibliothque partage qui code le langage

tmplacl

aclitem[]

Droits d'accs au modle (inutilis)

Il n'existe actuellement aucune commande de manipulation des modles de langages procduraux ; pour modifier l'information intgre, un superutilisateur doit modifier la table en utilisant les commandes INSERT, DELETE ou UPDATE habituelles.

Note
Il est probable que pg_pltemplate sera supprim dans une prochaine version de PostgreSQL, pour conserver cette
information des langages de procdure dans leur scripts d'installation respectifs.

45.35. pg_proc
Le catalogue pg_proc stocke les informations concernant les fonctions (ou procdures). Voir CREATE FUNCTION(7) et Section 35.3, Fonctions utilisateur pour plus d'informations.
Cette table contient des donnes sur les fonctions d'agrgat et les fonctions simples. Si proisagg est vrai, il doit y avoir une
ligne correspondante dans pg_aggregate.
Tableau 45.35. Colonnes de pg_proc

Nom

Type

Rfrences

Description

proname

name

pronamespace

oid

.o
OID du namespace auquel appartient la fonction
pg_namespaceid

proowner

oid

pg_authid.oid

Nom de la fonction

1248

Propritaire de la fonction

Catalogues systme

Nom

Type

Rfrences

Description

prolang

oid

.oi
pg_languaged

Langage de codage ou interface d'appel de la fonction

procost

float4

Cot d'excution estim (en unit de


cpu_operator_cost) ; si proretset, il s'agit d'un
cot par ligne

prorows

float4

Nombre estim de ligne de rsultat (zro si proretset est faux)

provariadic

oid

proisagg

bool

Si vrai, la fonction est une fonction d'agrgat

proiswindow

bool

La fonction est une fonction window

prosecdef

bool

Si vrai, la fonction dfinit la scurit (c'est une


fonction setuid )

proisstrict

bool

Si vrai, la fonction retourne NULL si l'un de ses


arguments est NULL. Dans ce cas, la fonction n'est
en fait pas appele du tout. Les fonctions qui ne
sont pas strictes doivent traiter les paramtres
NULL.

proretset

bool

Si vrai, la fonction retourne un ensemble


(c'est--dire des valeurs multiples du type dfini)

provolatile

char

Indique si le rsultat de la fonction dpend uniquement de ses arguments ou s'il est affect par des
facteurs externes. Il vaut i pour les fonctions
immuables , qui, pour un jeu de paramtres
identique en entre, donnent toujours le mme rsultat. Il vaut s pour les fonctions stables , dont
le rsultat (pour les mmes paramtres en entre)
ne change pas au cours du parcours (de table). Il
vaut v pour les fonctions volatiles , dont le rsultat peut varier tout instant. (v est galement
utilis pour les fonctions qui ont des effets de bord,
afin que les appels ces fonctions ne soient pas
optimiss.)

pronargs

int2

Nombre d'arguments en entre

pronargdefaults

int2

Nombre d'arguments qui ont des valeurs par dfaut

prorettype

oid

pg_type.oid

Type de donnes renvoy

proargtypes

oidvector

pg_type.oid

Un tableau contenant les types de donnes des arguments de la fonction. Ceci n'inclut que les arguments en entre (dont les arguments INOUT et
VARIADIC) et reprsente, du coup, la signature
d'appel de la fonction.

proallargtypes

oid[]

pg_type.oid

Un tableau contenant les types de donnes des arguments de la fonction. Ceci inclut tous les arguments (y compris les arguments OUT et INOUT) ;
nanmoins, si tous les arguments sont IN, ce
champ est NULL. L'indice commence 1 alors
que, pour des raisons historiques, proargtypes
commence 0.

proargmodes

char[]

pg_type.oid

Type des donnes des lments du tableau de paramtres variadic, ou zro si la fonction n'a pas de
paramtres variadiques.

Un tableau contenant les modes des arguments de


la fonction, cods avec i pour les arguments IN, o
pour les arguments OUT, b pour les arguments
INOUT, v pour les arguments VARIADIC, t pour
les arguments TABLE. Si tous les arguments sont
des arguments IN, ce champ est NULL. Les indices correspondent aux positions de proal1249

Catalogues systme

Nom

Type

Rfrences

Description
largtypes, et non celles de proargtypes.

proargnames

text[]

Un tableau contenant les noms des arguments de la


fonction. Les arguments sans nom sont initialiss
des chanes vides dans le tableau. Si aucun des arguments n'a de nom, ce champ est NULL. Les indices correspondent aux positions de proallargtypes, et non celles de proargtypes.

proargdefaults

pg_node_tree

Arbres d'expression (en reprsentation nodeToString()) pour les valeurs par dfaut. C'est une
liste avec pronargdefaults lments, correspondant aux N derniers arguments d'entre
(c'est--dire, les N dernires positions proargtypes). Si aucun des arguments n'a de valeur par
dfaut, ce champ vaudra null.

prosrc

text

Ce champ indique au gestionnaire de fonctions la


faon d'invoquer la fonction. Il peut s'agir du code
source pour un langage interprt, d'un symbole de
lien, d'un nom de fichier ou de toute autre chose,
en fonction du langage ou de la convention
d'appel.

probin

text

Information supplmentaire sur la faon d'invoquer


la fonction. Encore une fois, l'interprtation dpend du langage.

proconfig

text[]

Configuration locale la fonction pour les variables configurables l'excution

proacl

aclitem[]

Droits d'accs ; voir GRANT(7) et REVOKE(7)


pour plus de dtails.

Pour les fonctions compiles, intgres ou charges dynamiquement, prosrc contient le nom de la fonction en langage C
(symbole de lien). Pour tous les autres types de langages, prosrc contient le code source de la fonction. probin est inutilis,
sauf pour les fonctions C charges dynamiquement, pour lesquelles il donne le nom de fichier de la bibliothque partage qui
contient la fonction.

45.36. pg_rewrite
Le catalogue pg_rewrite stocke les rgles de rcriture pour les tables et les vues.
Tableau 45.36. Colonnes de pg_rewrite

Nom

Type

Rfrences

Description

rulename

name

ev_class

oid

ev_attr

int2

Colonne sur laquelle porte la rgle. Actuellement,


cette colonne vaut toujours -1 pour indiquer qu'il
s'agit de la table entire.

ev_type

char

Type d'vnement associ la rgle : 1 = SELECT, 2 = UPDATE, 3 = INSERT, 4 = DELETE

ev_enabled

char

Contrle l'excution de la rgle suivant le mode


session_replication_role. O = la rgle se dclenche
dans les modes origin et local , D = la rgle
est dsactive, R = la rgle s'excute en mode
replica , A = la rgle s'excute chaque fois.

is_instead

bool

Vrai s'il s'agit d'une rgle INSTEAD ( la place


de).

ev_qual

pg_node_tree

Arbre d'expression (sous la forme d'une reprsen-

Nom de la rgle
pg_class.oid

1250

Table sur laquelle porte la rgle

Catalogues systme

Nom

Type

Rfrences

Description
tation nodeToString()) pour la condition qualifiant la rgle.

ev_action

pg_node_tree

Arbre de requte (sous la forme d'une reprsentation nodeToString()) pour l'action de la rgle.

Note
pg_class.relhasrules doit tre vrai si une table possde une rgle dans ce catalogue.

45.37. pg_seclabel
Le catalogue pg_seclabel stocke les informations sur les labels de scurit des objets de la base de donnes. Les labels de scurit
peuvent tre manipuls avec la commande SECURITY LABEL(7). Pour visualiser plus facilement les labels de scurit, voir Section 45.61, pg_seclabels .
Tableau 45.37. Colonnes de pg_seclabel

Nom

Type

Rfrences

Description

objoid

oid

toute colonne OID

L'OID de l'objet concern par


ce label de scurit

classoid

oid

pg_class.oid

L'OID du catalogue systme o


cet objet apparat

objsubid

int4

Pour un label de scurit sur la


colonne d'une table, cette colonne correspond au numro de
colonne (objoid et classoid font rfrence la table
elle-mme). Pour tous les
autres types d'objet, cette colonne vaut zro.

provider

text

Le fournisseur du label associ


avec ce label.

label

text

Le label de scurit appliqu


sur cet objet.

45.38. pg_shdepend
Le catalogue pg_shdepend enregistre les relations de dpendance entre les objets de la base de donnes et les objets partags,
comme les rles. Cette information permet PostgreSQL de s'assurer que tous ces objets sont drfrencs avant toute tentative
de suppression.
Voir aussi pg_depend, qui ralise une fonction similaire pour les dpendances impliquant les objets contenus dans une seule base
de donnes.
Contrairement la plupart des catalogues systme, pg_shdepend est partag par toutes les bases de donnes d'un cluster : il
n'existe qu'une seule copie de pg_shdepend par cluster, pas une par base de donnes.
Tableau 45.38. Colonnes de pg_shdepend

Nom

Type

Rfrences

Description

dbid

oid

.oi
pg_databased

L'OID de la base de donnes dont fait partie l'objet


dpendant. 0 pour un objet partag

classid

oid

pg_class.oid

L'OID du catalogue systme dont fait partie l'objet


dpendant

objid

oid

toute colonne OID

L'OID de l'objet dpendant

1251

Catalogues systme

Nom

Type

Rfrences

Description

objsubid

int4

refclassid

oid

pg_class.oid

L'OID du catalogue systme dont fait partie l'objet


rfrenc (doit tre un catalogue partag)

refobjid

oid

toute colonne OID

L'OID de l'objet rfrenc

deptype

char

Pour une colonne de table, c'est le numro de colonne (les objid et classid font rfrence la
table elle-mme). Pour tous les autres types
d'objets, cette colonne vaut zro

Un code dfinissant les smantiques spcifiques


des relations de cette dpendance ; voir le texte.

Dans tous les cas, une entre pg_shdepend indique que l'objet rfrenc ne peut pas tre supprim sans supprimer aussi l'objet dpendant. Nanmoins, il existe quelques diffrences identifies par le deptype :
SHARED_DEPENDENCY_OWNER (o)
L'objet rfrenc (qui doit tre un rle) est le propritaire de l'objet dpendant.
SHARED_DEPENDENCY_ACL (a)
L'objet rfrenc (qui doit tre un rle) est mentionn dans la liste de contrle des accs (ACL, acronyme de access control
list) de l'objet dpendant. (Une entre SHARED_DEPENDENCY_ACL n'est pas cre pour le propritaire de l'objet car ce
dernier a toujours une entre SHARED_DEPENDENCY_OWNER.)
SHARED_DEPENDENCY_PIN (p)
Il n'existe pas d'objet dpendant ; ce type d'entre est un signal indiquant que le systme lui-mme dpend de l'objet rfrenc
et que, cet objet ne doit donc jamais tre supprim. Les entres de ce type ne sont cres que par initdb. Les colonnes pour
l'objet dpendant contiennent des zros.
D'autres types de dpendances peuvent s'avrer ncessaires dans le futur. La dfinition actuelle ne supporte que les rles comme
objets rfrencs.

45.39. pg_shdescription
Le catalogue pg_shdescription stocke les descriptions optionelles (commentaires) des objets partags de la base. Les descriptions
peuvent tre manipules avec la commande COMMENT(7) et visualises avec les commandes \d de psql.
Voir aussi pg_description, qui assure les mmes fonctions, mais pour les objets d'une seule base.
Contrairement la plupart des catalogues systmes, pg_shdescription est partage par toutes les bases d'un cluster : il n'existe
qu'une seule copie de pg_shdescription par cluster, et non une par base.
Tableau 45.39. Colonnes de pg_shdescription

Nom

Type

Rfrences

Description

objoid

oid

toute colonne OID

L'OID de l'objet concern par


la description

classoid

oid

pg_class.oid

L'OID du catalogue systme o


cet objet apparat

description

text

Texte arbitraire servant de description de l'objet

45.40. pg_statistic
Le catalogue pg_statistic stocke des donnes statistiques sur le contenu de la base de donnes. Les entres sont cres par ANALYZE(7), puis utilises par le planificateur de requtes. Les donnes statistiques sont, par dfinition des approximations, mme si
elles sont jour.
D'habitude, il existe une entre, avec staall = false, pour chaque colonne de table qui a t analyse. Si la table a des enfants,
une seconde entre avec staall = true est aussi cr. Cette ligne reprsente les statistiques de la colonne sur l'arbre d'hritage,
autrement dit les statistiques pour les donnes que vous voyez avec SELECT colonne FROM table*, alors que la ligne
staall = false reprsente le rsultat de SELECT column FROM ONLY table.
1252

Catalogues systme

pg_statistic stocke aussi les donnes statistiques des valeurs des expressions d'index. Elles sont dcrites comme si elles taient de
vraies colonnes ; en particulier, starelid rfrence l'index. Nanmoins, aucune entre n'est effectue pour une colonne d'index
ordinaire sans expression car cela est redondant avec l'entre correspondant la colonne sous-jacente de la table. Actuellement, les
entres pour les expressions d'index ont toujours staall = false.
Comme des statistiques diffrentes peuvent tre appropries pour des types de donnes diffrents, pg_statistic ne fait qu'un minimum de suppositions sur les types de statistiques qu'il stocke. Seules des statistiques extrmement gnrales (comme les valeurs
NULL) ont des colonnes ddies. Tout le reste est stock dans des connecteurs , groupes de colonnes associes dont le contenu
est identifi par un numro de code dans l'une des colonnes du connecteur. Pour plus d'information, voir src/include/catalog/pg_statistic.h.
pg_statistic ne doit pas tre lisible par le public, car mme les donnes statistiques sont sensibles. (Exemple : les valeurs maximales et minimales d'une colonne de salaire peuvent tre intressantes). pg_stats est une vue sur pg_statistic accessible tous, qui
n'expose que les informations sur les tables accessibles l'utilisateur courant.
Tableau 45.40. Colonnes de pg_statistic

Nom

Type

Rfrences

Description

starelid

oid

pg_class.oid

Table ou index qui la colonne dcrite appartient

staattnum

int2

.a
tt
nu
pg_attributem

Numro de la colonne dcrite

staall

bool

Si vrai, les statistiques incluent les colonnes enfants de l'hritage, pas uniquement les valeurs de la
relation spcifie

stanullfrac

float4

Fraction des entres de la colonne qui ont une valeur NULL

stawidth

int4

Taille moyenne, en octets, des entres non NULL

stadistinct

float4

Nombre de valeurs distinctes non NULL dans la


colonne. Une valeurs positive est le nombre rel de
valeurs distinctes. Une valeur ngative est le ngatif d'un multiplieur pour le nombre de lignes dans
la table ; par exemple, une colonne dans laquelle
les valeurs apparaissent environ deux fois en
moyenne peut tre reprsente par stadistinct = -0.5. 0 indique que le nombre de valeurs
distinctes est inconnu.

stakindN

int2

Numro de code indiquant le type de statistiques


stockes dans le connecteur numro N de la
ligne de pg_statistic.

staopN

oid

stanumbersN

float4[]

Statistiques numriques du type appropri pour


le connecteur numro N ou NULL si le type de
connecteur n'implique pas de valeurs numriques.

stavaluesN

anyarray

Valeurs de donnes de la colonne du type appropri pour le connecteur numro N ou NULL si


le type de connecteur ne stocke aucune valeur de
donnes. Chaque valeur d'lment du tableau est
en fait du type de donnes de la colonne indique,
si bien qu'il n'y a aucun moyen de dfinir le type
de ces colonnes plus prcisment qu'avec le type
anyarray (tableau quelconque).

.oi
pg_operatord

1253

Oprateur utilis pour driver les statistiques stockes dans le connecteur numro N. Par
exemple, un connecteur d'histogramme montre
l'oprateur <, qui dfinit l'ordre de tri des donnes.

Catalogues systme

45.41. pg_tablespace
Le catalogue pg_tablespace enregistre les informations des tablespaces disponibles. Les tables peuvent tre places dans des tablespaces particuliers pour faciliter l'administration des espaces de stockage.
Contrairement la plupart des catalogues systme, pg_tablespace est partage par toutes les bases de donnes du cluster : il n'y a
donc qu'une copie de pg_tablespace par cluster, et non une par base.
Tableau 45.41. Colonnes de pg_tablespace

Nom

Type

Rfrences

Description

spcname

name

spcowner

oid

spclocation

text

Emplacement (chemin vers le rpertoire) du tablespace

spcacl

aclitem[]

Droits d'accs ; voir GRANT(7) et REVOKE(7)


pour les dtails.

spcoptions

text[]

Options au niveau tablespace, sous la forme de


chanes motcl=valeur

Nom du tablespace
pg_authid.oid

Propritaire du tablespace,
l'utilisateur qui l'a cr

habituellement

45.42. pg_trigger
Le catalogue pg_trigger stocke les informations concernant les dclencheurs des tables et des vues. Voir la commande CREATE
TRIGGER(7) pour plus d'informations.
Tableau 45.42. Colonnes de pg_trigger

Nom

Type

Rfrences

Description

tgrelid

oid

pg_class.oid

Table sur laquelle porte le dclencheur

tgname

name

tgfoid

oid

tgtype

int2

Masque de bits identifiant les conditions de dclenchement

tgenabled

char

Contrle l'excution du trigger suivant le mode


session_replication_role. O = le trigger se dclenche dans les modes origin et local , D =
le trigger est dsactiv, R = le trigger s'excute en
mode replica , A = le trigger s'excute chaque
fois.

tgisinternal

bool

Vrai si le trigger est gnr en interne


(habituellement pour forcer la contrainte identifie
par tgconstraint)

tgconstrrelid

oid

pg_class.oid

La table rfrence par une contrainte d'intgrit


rfrentielle

tgconstrindid

oid

pg_class.oid

L'index supportant une contrainte unique, cl primaire ou d'intgrit rfrentielle

tgconstraint

oid

.
L'entre pg_constraint associ au trigger, si elle
o
existe
i
pg_constraintd

tgdeferrable

bool

Vrai si le dclencheur contrainte est retardable

tginitdeferred

bool

Vrai si le dclencheur de contrainte est initialement retard

Nom du dclencheur (doit tre unique parmi les


dclencheurs d'une table)
pg_proc.oid

1254

Fonction appeler

Catalogues systme

Nom

Type

Rfrences

Description

tgnargs

int2

tgattr

int2vector

tgargs

bytea

Chanes d'arguments passer au dclencheur, chacune termine par un NULL

tgqual

pg_node_tree

Arbre d'expression (d'aprs la reprsentation de


nodeToString() pour la condition WHEN du
trigger, ou NULL si aucune

Nombre de chanes d'arguments passes la fonction du dclencheur


.a
tt
nu
pg_attributem

numros de colonne, si le trigger est spcifique la


colonne ; sinon un tableau vide

Actuellement, les triggers spcifiques par colonne sont supports seulement pour les vnements UPDATE et, du coup, tgattr
est valable seulement pour ce type d'vnements. tgtype pourrait contenir des informations pour d'autres types d'vnement
mais ils sont supposs valides pour la table complte, quel que soit le contenu de tgattr.

Note
Quand tgconstraint est diffrent de zro, tgconstrrelid, tgconstrindid, tgdeferrable et tginitdeferred sont grandement redondants avec l'entre pg_constraint rfrence. Nanmoins, il est possible
qu'un trigger non dferrable soit associ une contrainte dferrable : les contraintes de cl trangre peuvent avoir
quelques triggers dferrables et quelques triggers non dferrables.

Note
pg_class.relhastriggers doit valoir true si la relation possde au moins un trigger dans ce catalogue.

45.43. pg_ts_config
Le catalogue pg_ts_config contient des entres reprsentant les configurations de la recherche plein texte. Une configuration spcifie un analyseur et une liste de dictionnaires utiliser pour chacun des types d'lments en sortie de l'analyseur. L'analyseur est
prsent dans l'entre de pg_ts_config mais la correspondance lment/dictionnaire est dfinie par des entres supplmentaires
dans pg_ts_config_map.
Les fonctionnalits de recherche plein texte de PostgreSQL sont expliques en dtail dans Chapitre 12, Recherche plein texte.
Tableau 45.43. Colonnes de pg_ts_config

Nom

Type

Rfrences

Description

cfgname

name

cfgnamespace

oid

.o
OID du namespace qui contient la configuration
pg_namespaceid

cfgowner

oid

pg_authid.oid

cfgparser

oid

.o
OID de l'analyseur pour la configuration
pg_ts_parserid

Nom de la configuration

Propritaire de la configuration

45.44. pg_ts_config_map
Le catalogue pg_ts_config_map contient des entres prsentant les dictionnaires de recherche plein texte consulter et l'ordre de
consultation, pour chaque type de lexme en sortie de chaque analyseur de configuration.
Les fonctionnalits de la recherche plein texte de PostgreSQL sont expliques en dtail dans Chapitre 12, Recherche plein texte.
Tableau 45.44. Colonnes de pg_ts_config_map

1255

Catalogues systme

Nom

Type

Rfrences

Description

mapcfg

oid

.o
OID de l'entre pg_ts_config qui possde l'entre
pg_ts_configid

maptokentype

integer

Un type de lexme mis par l'analyseur de configuration

mapseqno

integer

Ordre dans lequel consulter l'entre (les plus petits


mapseqno en premier)

mapdict

oid

pg_ts_dict.oid OID du dictionnaire de recherche plein texte


consulter

45.45. pg_ts_dict
Le catalogue pg_ts_dict contient des entres dfinissant les dictionnaires de recherche plein texte. Un dictionnaire dpend d'un
modle de recherche plein texte qui spcifie toutes les fonctions d'implantation ncessaires ; le dictionnaire lui-mme fournit des
valeurs pour les paramtres utilisateur supports par le modle. Cette division du travail permet la cration de dictionnaires par des
utilisateurs non privilgis. Les paramtres sont indiqus par une chane, dictinitoption, dont le format et la signification
dpendent du modle.
Les fonctionnalits de la recherche plein texte de PostgreSQL sont expliques en dtail dans Chapitre 12, Recherche plein texte.
Tableau 45.45. Colonnes de pg_ts_dict

Nom

Type

Rfrences

Description

dictname

name

dictnamespace

oid

pg_namespace.oid

OID du namespace contenant le dictionnaire

dictowner

oid

pg_authid.oid

Propritaire du dictionnaire

dicttemplate

oid

pg_ts_template.oid

OID du modle de recherche plein texte du dictionnaire

dictinitoption

text

Nom du dictionnaire de recherche plein texte

Chane d'options d'initialisation du modle

45.46. pg_ts_parser
Le catalogue pg_ts_parser contient des entres dfinissant les analyseurs de la recherche plein texte. Un analyseur est responsable
du dcoupage du texte en entre en lexmes et de l'assignation d'un type d'lment chaque lexme. Puisqu'un analyseur doit tre
cod l'aide de fonctions crites en langage C, la cration de nouveaux analyseurs est restreinte aux superutilisateurs des bases de
donnes.
Les fonctionnalits de la recherche plein texte de PostgreSQL sont expliques en dtail dans Chapitre 12, Recherche plein texte.
Tableau 45.46. Colonnes de pg_ts_parser

Nom

Type

prsname

name

Rfrences

Description

prsnamespace

oid

.o
OID du namespace qui contient l'analyseur
pg_namespaceid

prsstart

regproc

pg_proc.oid

OID de la fonction de dmarrage de l'analyseur

prstoken

regproc

pg_proc.oid

OID de la fonction next-token de l'analyseur

prsend

regproc

pg_proc.oid

OID de la fonction d'arrt de l'analyseur

prsheadline

regproc

pg_proc.oid

OID de la fonction headline de l'analyseur

prslextype

regproc

pg_proc.oid

OID de la fonction lextype de l'analyseur

Nom de l'analyseur de recherche plein texte

45.47. pg_ts_template
1256

Catalogues systme

Le catalogue pg_ts_template contient des entres dfinissant les modles de recherche plein texte. Un modle est le squelette
d'implantation d'une classe de dictionnaires de recherche plein texte. Puisqu'un modle doit tre cod l'aide de fonctions codes
en langage C, la cration de nouveaux modles est restreinte aux superutilisateurs des bases de donnes.
Les fonctionnalits de la recherche plein texte de PostgreSQL sont expliques en dtail dans Chapitre 12, Recherche plein texte.
Tableau 45.47. Colonnes de pg_ts_template

Nom

Type

Rfrences

Description

tmplname

name

tmplnamespace

oid

.o
OID du namespace qui contient le modle
pg_namespaceid

tmplinit

regproc

pg_proc.oid

OID de la fonction d'initialisation du modle

tmpllexize

regproc

pg_proc.oid

OID de la fonction lexize du modle

Nom du modle de recherche plein texte

45.48. pg_type
Le catalogue pg_type stocke les informations concernant les types de donnes. Les types basiques et d'numration (types scalaires) sont crs avec la commande CREATE TYPE(7) et les domaines avec CREATE DOMAIN(7). Un type composite est cr
automatiquement pour chaque table de la base pour reprsenter la structure des lignes de la table. Il est aussi possible de crer des
types composites avec CREATE TYPE AS.
Tableau 45.48. Colonnes de pg_type

Nom

Type

Rfrences

Description

typname

name

typnamespace

oid

.o
OID du namespace qui contient le type
pg_namespaceid

typowner

oid

pg_authid.oid

typlen

int2

Pour les types de taille fixe, typlen est le


nombre d'octets de la reprsentation interne du
type. Mais pour les types de longueur variable,
typlen est ngatif. -1 indique un type varlena
(qui a un attribut de longueur), -2 indique une
chane C termine par le caractre NULL.

typbyval

bool

typbyval dtermine si les routines internes


passent une valeur de ce type par valeur ou par rfrence. typbyval doit tre faux si typlen ne
vaut pas 1, 2 ou 4 (ou 8 sur les machines dont le
mot-machine est de 8 octets). Les types de longueur variable sont toujours passs par rfrence.
typbyval peut tre faux mme si la longueur
permet un passage par valeur.

typtype

char

typtype vaut b pour un type de base, c pour un


type composite (le type d'une ligne de table, par
exemple), d pour un domaine, e pour un enum ou
p pour un pseudo-type. Voir aussi typrelid et
typbasetype.

typcategory

char

typcategory est une classification arbitraire de


types de donnes qui est utilise par l'analyseur
pour dterminer la conversion implicite devant tre
prfre . Voir Tableau 45.49, Codes typcategory

typispreferred

bool

Vrai si ce type est une cible de conversion prfre


dans sa typcategory

typisdefined

bool

Vrai si le type est dfini et faux s'il ne s'agit que

Nom du type

1257

Propritaire du type

Catalogues systme

Nom

Type

Rfrences

Description
d'un conteneur pour un type qui n'est pas encore
dfini. Lorsque typisdefined est faux, rien,
part le nom du type, le namespace et l'OID, n'est
fiable.

typdelim

char

Caractre qui spare deux valeurs de ce type


lorsque le programme lit les valeurs d'un tableau
en entre. Le dlimiteur est associ au type
d'lment du tableau, pas au type tableau.

typrelid

oid

pg_class.oid

S'il s'agit d'un type composite (voir typtype),


alors cette colonne pointe vers la ligne de pg_class
qui dfinit la table correspondante. Pour un type
composite sans table, l'entre dans pg_class ne reprsente pas vraiment une table, mais elle est nanmoins ncessaire pour trouver les lignes de
pg_attribute lies au type. 0 pour les types autres
que composites.

typelem

oid

pg_type.oid

Si typelem est diffrent de zro, alors il identifie


une autre ligne de pg_type. Le type courant peut
alors tre utilis comme un tableau contenant des
valeurs de type typelem. Un vrai type tableau a une longueur variable (typlen = -1),
mais certains types de longueur fixe (typlen > 0)
ont aussi un typelem non nul, par exemple name
et point. Si un type de longueur fixe a un typelem, alors sa reprsentation interne est compose
d'un certain nombre de valeurs du type typelem,
sans autre donne. Les types de donnes tableau de
taille variable ont un en-tte dfini par les sousroutines de tableau.

typarray

oid

pg_type.oid

Si typarray est diffrent de zro, alors il identifie une autre ligne dans pg_type, qui est le type tableau true disposant de ce type en lment.

typinput

regproc

pg_proc.oid

Fonction de conversion en entre (format texte)

typoutput

regproc

pg_proc.oid

Fonction de conversion en sortie (format texte)

typreceive

regproc

pg_proc.oid

Fonction de conversion en entre (format binaire),


ou 0 s'il n'y en a pas

typsend

regproc

pg_proc.oid

Fonction de conversion en sortie (format binaire),


ou 0 s'il n'y en a pas

typmodin

regproc

pg_proc.oid

Fonction en entre de modification du type ou 0 si


le type ne supporte pas les modificateurs

typmodout

regproc

pg_proc.oid

Fonction en sortie de modification du type ou 0


pour utiliser le format standard

typanalyze

regproc

pg_proc.oid

Fonction ANALYZE personnalise ou 0 pour utiliser la fonction standard

typalign

char

typalign est l'alignement requis pour stocker


une valeur de ce type. Cela s'applique au stockage
sur disque ainsi qu' la plupart des reprsentations
de cette valeur dans PostgreSQL. Lorsque des
valeurs multiples sont stockes conscutivement,
comme dans la reprsentation d'une ligne complte
sur disque, un remplissage est insr avant la donne de ce type pour qu'elle commence
l'alignement indiqu. La rfrence de l'alignement
est le dbut de la premire donne de la squence.
Les valeurs possibles sont :
1258

Catalogues systme

Nom

Type

Rfrences

Description

c = alignement char, aucun alignement n'est


ncessaire ;

s = alignement short (deux octets sur la plupart


des machines) ;

i = alignement int (quatre octets sur la plupart


des machines) ;

d = alignement double (huit octets sur la plupart des machines, mais pas sur toutes).

Note
Pour les types utiliss dans les
tables systmes il est indispensable
que les tailles et alignements dfinis
dans pg_type soient en accord avec
la faon dont le compilateur dispose
la colonne dans une structure reprsentant une ligne de table.
typstorage

char

typstorage indique, pour les types varlena


(ceux pour lesquels typlen = -1), si le type accepte le TOASTage et la stratgie par dfaut utiliser pour les attributs de ce type. Les valeurs possibles sont :

p : la valeur doit tre stocke normalement ;

e : la valeur peut tre stocke dans une relation


secondaire (si la relation en a une, voir
pg_class.reltoastrelid) ;

m : la valeur peut tre stocke compresse sur


place ;

x : la valeur peut tre stocke compresse sur


place ou stocke dans une relation
secondaire .

Les colonnes m peuvent aussi tre dplaces dans


une table de stockage secondaire, mais seulement
en dernier recours (les colonnes e et x sont dplaces les premires).
typnotnull

bool

typbasetype

oid

typtypmod

int4

typndims

int4

Reprsente une contrainte non NULL pour le type.


Ceci n'est utilis que pour les domaines.
pg_type.oid

S'il s'agit d'un domaine (voir typtype), alors


typbasetype identifie le type sur lequel celui-ci
est fond. 0 s'il ne s'agit pas d'un domaine.
Les domaines utilisent ce champ pour enregistrer
le typmod appliquer leur type de base (-1 si le
type de base n'utilise pas de typmod). -1 si ce
type n'est pas un domaine.
Le nombre de dimensions de tableau pour un domaine sur un tableau (c'est--dire dont typbasetype est un type tableau). 0 pour les types autres
que les domaines sur des types tableaux.

1259

Catalogues systme

Nom

Type

Rfrences

Description

typcollation

oid

.o
pg_collationid typcollation spcifie le collationnement du
type. Si le type ne supporte pas les collationnemens, cette colonne vaut zro. Un type de base qui
supporte les collationnements aura DEFAULT_COLLATION_OID ici. Un domaine sur
un type collationnable peut avoir un autre OID de
collationnement si ce dernier a t prcis pour le
domaine.

typdefaultbin

pg_node_tree

typdefault

text

Si typdefaultbin n'est pas NULL, ce champ


est la reprsentation nodeToString() d'une expression par dfaut pour le type. Ceci n'est utilis
que pour les domaines.
NULL si le type n'a pas de valeur par dfaut associe. Si typdefaultbin est non NULL, ce
champ doit contenir une version lisible de
l'expression par dfaut reprsente par typdefaultbin. Si typdefaultbin est NULL et si
ce champ ne l'est pas, alors il stocke la reprsentation externe de la valeur par dfaut du type, qui
peut tre passe la fonction de conversion en entre du type pour produire une constante.

Tableau 45.49, Codes typcategory liste les valeurs de typcategory dfinies par le systme. Tout ajout futur la liste
sera aussi une lettre ASCII majuscule. Tous les autres caractres ASCII sont rservs pour les catgories dfinies par l'utilisateur.
Tableau 45.49. Codes typcategory

Code

Catgorie

Types tableaux

Types boolens

Types composites

Types date/time

Types enum

Types gometriques

Types adresses rseau

Types numriques

Pseudo-types

Types chanes

Types 'Timespan' (tendue de temps, intervalle)

Types dfinis par l'utilisateur

Types Bit-string

Type unknown

45.49. pg_user_mapping
Le catalogue pg_user_mapping stocke les correspondances entre utilisateurs locaux et distants. L'accs ce catalogue est interdite
aux utilisateurs normaux, utilisez la vue pg_user_mappings la place.
Tableau 45.50. Colonnes de pg_user_mapping

1260

Catalogues systme

Nom

Type

Rference

Description

umuser

oid

pg_authid.oid

OID du rle faire correspondre, 0 si l'utilisateur correspondre est public.

umserver

oid

pg_foreign_server.oid L'OID du serveur distant qui


contient cette correspondance

umoptions

text[]

Options spcifiques la correspondance d'utilisateurs, sous


forme
de
chanes
motcl=valeur .

45.50. Vues systme


En plus des catalogues systme, PostgreSQL fournit un certain nombre de vues internes. Certaines fournissent un moyen simple
d'accder des requtes habituellement utilises dans les catalogues systmes. D'autres vues donnent accs l'tat interne du serveur.
Le schma d'information (Chapitre 34, Schma d'information) fournit un autre ensemble de vues qui recouvrent les fonctionnalits
des vues systme. Comme le schma d'information fait parti du standard SQL, alors que les vues dcrites ici sont spcifiques
PostgreSQL, il est gnralement prfrable d'utiliser le schma d'information si celui-ci apporte toutes les informations ncessaires.
Tableau 45.51, Vues systme liste les vues systmes dcrites plus en dtails dans la suite du document. Il existe de plus des
vues permettant d'accder aux rsultats du collecteur de statistiques elles sont dcrites dans le Tableau 27.1, Vues statistiques
standards .
Sauf lorsque c'est indiqu, toutes les vues dcrites ici sont en lecture seule.
Tableau 45.51. Vues systme

Nom de la vue

But

pg_available_extensions

extensions disponibles

pg_available_extension_versions

versions disponibles des extensions

pg_cursors

curseurs ouverts

pg_group

groupe d'utilisateurs de la base de donnes

pg_indexes

index

pg_locks

verrous poss au moment de la consultation

pg_prepared_statements

instructions prpares

pg_prepared_xacts

transactions prpares

pg_roles

rles des bases de donnes

pg_rules

rgles

pg_seclabels

labels de scurit

pg_settings

configuration

pg_shadow

utilisateurs des bases de donnes

pg_stats

statistiques du planificateur

pg_tables

tables

pg_timezone_abbrevs

abrviations des fuseaux horaires

pg_timezone_names

noms des fuseaux horaires

pg_user

utilisateurs des bases de donnes

pg_user_mappings

user mappings

pg_views

vues

1261

Catalogues systme

45.51. pg_available_extensions
La vue pg_available_extensions liste les extensions disponibles pour cette installation. Voir aussi le catalogue pg_extension qui
affiche les extensions actuellement installes.
Tableau 45.52. Colonnes de pg_available_extensions

Nom

Type

Description

name

name

Nom de l'extension

default_version

text

Nom de la version par dfaut, ou NULL si


aucune version n'est indique

installed_version

text

Version actuellement installe pour cette


extension, ou NULL si elle n'est pas installe

comment

text

Chane de commentaire partir du fichier


de contrle de l'extension

La vue pg_available_extensions est en lecture seule.

45.52. pg_available_extension_versions
La vue pg_available_extension_versions liste les versions spcifiques des extensions disponibles sur cette installation. Voir aussi
le catalogue pg_extension qui affiche les extensions actuellement installes.
Tableau 45.53. Colonnes de pg_available_extension_versions

Nom

Type

Description

name

name

Nom de l'extension

version

text

Nom de la version

installed

bool

True si cette version de l'extension est actuellement installe

superuser

bool

True si seuls les superutilisateurs sont autoriss installer cette extension

relocatable

bool

True si l'extension peut tre dplace dans


un autre schma

schema

name

Nom du schma dans lequel l'extension


doit tre installe ou NULL si elle est dplaable partiellement ou compltement

requires

name[]

Noms des extensions requises, ou NULL si


aucune extension supplmentaire n'est ncessaire

comment

text

Chane de commentaire provenant du fichier de contrle de l'extension

La vue pg_available_extension_versions est en lecture seule.

45.53. pg_cursors
La vue pg_cursors liste les curseurs actuellement disponibles. Les curseurs peuvent tre dfinis de plusieurs faons :

via l'instruction SQL DECLARE(7) ;

via le message Bind du protocole frontend/backend, dcrit dans le Section 46.2.3, Requte tendue ;

via l'interface de programmation du serveur (SPI), dcrite dans le Section 43.1, Fonctions d'interface .

La vue pg_cursors affiche les curseurs crs par tout moyen prcdent. Les curseurs n'existent que pour la dure de la transaction
1262

Catalogues systme

qui les dfinit, sauf s'ils ont t dclars avec WITH HOLD. De ce fait, les curseurs volatils (non-holdable) ne sont prsents dans la
vue que jusqu' la fin de la transaction qui les a crs.

Note
Les curseurs sont utiliss en interne pour coder certains composants de PostgreSQL, comme les langages procduraux. La vue pg_cursors peut ainsi inclure des curseurs qui n'ont pas t crs explicitement par l'utilisateur.
Tableau 45.54. Colonnes de pg_cursors

Nom

Type

Description

name

text

Le nom du curseur

statement

text

La chane utilise comme requte pour


crer le curseur

is_holdable

boolean

true si le curseur est persistant


(holdable) (c'est--dire s'il peut tre accd aprs la validation de la transaction qui
l'a dclar) ; false sinon

is_binary

boolean

true si le curseur a t dclar binaire


(BINARY) ; false sinon

is_scrollable

boolean

true si le curseur autorise une rcupration non squentielle des lignes ; false
sinon

creation_time

timestamptz

L'heure laquelle le curseur a t dclar

La vue pg_cursors est en lecture seule.

45.54. pg_group
La vue pg_group existe pour des raisons de compatibilit ascendante : elle mule un catalogue qui a exist avant la version 8.1 de
PostgreSQL. Elle affiche les noms et membres de tous les rles dont l'attribut rolcanlogin est dvalid, ce qui est une approximation des rles utiliss comme groupes.
Tableau 45.55. Colonnes de pg_group

Nom

Type

Rfrences

Description

groname

name

.roln
pg_authidame

Nom du groupe

grosysid

oid

pg_authid.oid

Identifiant du groupe

grolist

oid[]

pg_authid.oid

Un tableau contenant les identifiants des rles du


groupe

45.55. pg_indexes
La vue pg_indexes fournit un accs aux informations utiles sur chaque index de la base de donnes.
Tableau 45.56. Colonnes de pg_indexes

Nom

Type

Rfrences

Description

schemaname

name

pg_namespace.nspname

Nom du schma contenant les tables et index

tablename

name

pg_class.relname

Nom de la table portant l'index

indexname

name

pg_class.relname

Nom de l'index

tablespace

name

pg_tablespace.spcname

Nom du tablespace contenant l'index (NULL s'il


s'agit de celui par dfaut pour la base de donnes)

1263

Catalogues systme

Nom

Type

indexdef

text

Rfrences

Description
Dfinition de l'index (une commande CREATE
INDEX reconstruite)

45.56. pg_locks
La vue pg_locks fournit un accs aux informations concernant les verrous dtenus par les transactions ouvertes sur le serveur de
bases de donnes. Voir le Chapitre 13, Contrle d'accs simultan pour une discussion plus importante sur les verrous.
pg_locks contient une ligne par objet verrouillable actif, type de verrou demand et transaction associe. Un mme objet verrouillable peut apparatre plusieurs fois si plusieurs transactions ont pos ou attendent des verrous sur celui-ci. Toutefois, un objet
qui n'est pas actuellement verrouill n'apparat pas.
Il existe plusieurs types distincts d'objets verrouillables : les relations compltes (tables, par exemple), les pages individuelles de
relations, des tuples individuels de relations, les identifiants de transaction (virtuels et permanents) et les objets gnraux de la
base de donnes (identifis par l'OID de la classe et l'OID de l'objet, de la mme faon que dans pg_description ou pg_depend).
De plus, le droit d'tendre une relation est reprsent comme un objet verrouillable distinct. Et enfin, les verrous informatifs
peuvent tre pris sur les numros qui ont la signification dfinie par l'utilisateur.
Tableau 45.57. Colonnes pg_locks

Nom

Type

Rfrences

Description

locktype

text

database

oid

.oi
pg_databased

L'OID de la base de donnes dans laquelle existe


l'objet, 0 si l'objet est partag ou NULL si l'objet
est un identifiant de transaction

relation

oid

pg_class.oid

L'OID de la relation ou NULL si l'objet n'est pas


une relation ni une partie de relation

page

integer

Le numro de page l'intrieur de cette relation ou


NULL si l'objet n'est pas un tuple ou une page de
relation

tuple

smallint

Le numro du tuple dans la page ou NULL si


l'objet n'est pas un tuple

virtualxid

text

L'identifiant virtuel d'une transaction, ou NULL si


l'objet n'est pas un identifiant virtuel de transaction

transactionid

xid

L'identifiant d'une transaction ou NULL si l'objet


n'est pas un identifiant de transaction

classid

oid

pg_class.oid

objid

oid

n'importe quelle co- L'OID de l'objet dans son catalogue systme ou


lonne OID
NULL si l'objet n'est pas un objet gnral de la
base de donnes.

objsubid

smallint

Numro de la colonne cible par le verrou (classid et objid font rfrence la table ellemme), ou 0 si la cible est un autre objet de la base
de donnes, ou NULL si l'objet n'est pas un objet
de la base de donnes.

virtualtransaction

text

L'identifiant virtuel de la transaction qui dtient ou


attend le verrou.

pid

integer

L'identifiant du processus serveur qui dtient ou attend le verrou. NULL si le verrou est possd par
une transaction prpare.

mode

text

Nom du type de verrou dtenu ou attendu par ce


processus (voir la Section 13.3.1, Verrous de ni-

Type de l'objet verrouillable : relation, extend, page, tuple, transactionid, virtualxid, object, userlock ou advisory

1264

L'OID du catalogue systme contenant l'objet ou


NULL si l'objet n'est pas un objet gnral de la
base de donnes

Catalogues systme

Nom

Type

Rfrences

Description
veau table et Section 13.2.3, Niveau d'Isolation
Serializable )

granted

boolean

True si le verrou est dtenu, false s'il est attendu

granted est true sur une ligne reprsentant un verrou tenu par la transaction indique. Une valeur false indique que cette
transaction attend l'acquisition du verrou, ce qui implique qu'une autre transaction a choisi un mode de verrouillage conflictuel sur
le mme objet verrouillable. La transaction en attente dort jusqu'au relchement du verrou (ou jusqu' ce qu'une situation de blocage soit dtecte). Une transaction unique peut attendre l'acquisition d'au plus un verrou la fois.
Chaque transaction dtient un verrou exclusif sur son identifiant virtuel de transaction pour toute sa dure. Si un identifiant permanent est affect la transaction (ce qui arrive habituellement si la transaction change l'tat de la base de donnes), il dtient aussi
un verrou exclusif sur son identifiant de transaction permanent jusqu' sa fin. Quand une transaction trouve ncessaire d'attendre
spcifiquement une autre transaction, elle le fait en essayant d'acqurir un verrou partag sur l'identifiant de l'autre transaction
(identifiant virtuel ou permanent selon la situation). Ceci n'est couronn de succs que lorsque l'autre transaction termine et relche son verrou.
Bien que les lignes constituent un type d'objet verrouillable, les informations sur les verrous de niveau ligne sont stockes sur
disque, et non en mmoire. Ainsi, les verrous de niveau ligne n'apparaissent normalement pas dans cette vue. Si une transaction attend un verrou de niveau ligne, elle apparat sur la vue comme en attente de l'identifiant permanent de la transaction actuellement
dtentrice de ce verrou de niveau ligne.
Les verrous consultatifs peuvent tre acquis par des cls constitues soit d'une seule valeur bigint, soit de deux valeurs integer.
Une cl bigint est affiche avec sa moiti haute dans la colonne classid, sa partie basse dans la colonne objid et objsubid
1. Les cls integer sont affiches avec la premire cl dans la colonne classid, la deuxime cl dans la colonne objid et
objsubid 2. La signification relle des cls est laisse l'utilisateur. Les verrous consultatifs sont locaux chaque base, la colonne database a donc un sens dans ce cas.
pg_locks fournit une vue globale de tous les verrous du cluster, pas seulement de ceux de la base en cours d'utilisation. Bien que la
colonne relation puisse tre jointe avec pg_class.oid pour identifier les relations verrouilles, ceci ne fonctionne correctement qu'avec les relations de la base accde (celles pour lesquelles la colonne database est l'OID de la base actuelle ou 0).
La vue pg_locks affiche des donnes provenant du gestionnaire de verrous standards et du gestionnaire de verrous de prdicats,
qui sont des systmes autrement spars. Quand un utilisateur accde cette vue, les structures de donnes internes de chaque gestionnaire de verrous sont temporairement verrouilles, et des copies sont faites que la vue va afficher. Chaque gestionnaire de verrous produira du coup un ensemble cohrent de rsultats mais, comme nous ne verrouillons pas les deux gestionnaires simultanment, il est possible que des verrous soient donns ou relachs aprs avoir interrog le gestionnaire de verrous standard et avant
avoir interrog le gestionnaire de verrous de prdicat. Chaque gestionnaire est verrouill le moins de temps possible pour rduire
l'impact sur les performances mais un impact sur les performances du serveur peut nanmoins tre observ si la vue est utilise
frquemment.
La colonne pid peut tre jointe la colonne procpid de la vue pg_stat_activity pour obtenir plus d'informations sur la session
qui dtient ou attend un verrou, par exemple :
SELECT * FROM pg_locks pl LEFT JOIN pg_stat_activity psa
ON pl.pid = psa.procpid;
. De plus, si des transactions prpares sont utilises, la colonne virtualtransaction peut tre jointe la colonne transaction de la vue pg_prepared_xacts pour obtenir plus d'informations sur les transactions prpares qui dtiennent des verrous.
(Une transaction prpare ne peut jamais tre en attente d'un verrou mais elle continue dtenir les verrous qu'elle a acquis pendant son excution.) Par exemple :
SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
ON pl.virtualtransaction = '-1/' || ppx.transaction;

45.57. pg_prepared_statements
La vue pg_prepared_statements affiche toutes les instructions prpares disponibles pour la session en cours. Voir PREPARE(7)
pour de plus amples informations sur les instructions prpares.
pg_prepared_statements contient une ligne pour chaque instruction prpare. Les lignes sont ajoutes la vue quand une nouvelle
instruction prpare est cre et supprime quand une instruction prpare est abandonne (par exemple, via la commande DEALLOCATE(7)).

1265

Catalogues systme

Tableau 45.58. Colonnes de pg_prepared_statements

Nom

Type

Description

name

text

L'identifiant
prpare

statement

text

La requte soumise par le


client pour crer cette instruction prpare. Pour les instructions prpares cres en SQL,
c'est l'instruction PREPARE
soumise par le client. Pour les
instructions prpares cres
via le protocole frontend/backend, c'est le texte de
l'intruction
prpare
ellemme.

prepare_time

timestamptz

L'heure
de
cration
l'instruction prpare

parameter_types

regtype[]

Les types des paramtres attendus par l'instruction prpare


sous la forme d'un tableau de
regtype. L'OID correspondant
un lment de ce tableau peut
tre obtenu en convertissant la
valeur regtype en oid.

from_sql

boolean

true si l'instruction prpare


a t cre via l'instruction
SQL PREPARE ; false si
l'instruction a t prpare via
le protocole frontend/backend

de

l'instruction

de

La vue pg_prepared_statements est en lecture seule.

45.58. pg_prepared_xacts
La vue pg_prepared_xacts affiche les informations concernant les transactions actuellement prpares pour une validation en deux
phases (voir PREPARE TRANSACTION(7) pour les dtails).
pg_prepared_xacts contient une ligne par transaction prpare. L'entre est supprime quand la transaction est valide ou annule.
Tableau 45.59. Colonnes de pg_prepared_xacts

Nom

Type

Rfrences

Description

transaction

xid

L'identifiant numrique de la transaction prpare

gid

text

L'identifiant global de transaction assign la transaction

prepared

timestamp
with time zone

L'heure de prparation de la transaction pour validation

owner

name

pg_authid.rolname

Le nom de l'utilisateur qui a excut la transaction

database

name

pg_database.datname

Nom de la base de donnes dans laquelle a t excute


la transaction

Lors d'un accs la vue pg_prepared_xacts, les structures de donnes du gestionnaire interne des transactions sont momentanment verrouilles et une copie de la vue est faite pour affichage. Ceci assure que la vue produit un ensemble cohrent de rsultats
tout en ne bloquant pas les oprations normales plus longtemps que ncessaire. Nanmoins, si la vue est accde frquemment, les
performances de la base de donnes peuvent tre impactes.

1266

Catalogues systme

45.59. pg_roles
La vue pg_roles fournit un accs aux informations des rles de base de donnes. C'est tout simplement une vue accessible de
pg_authid qui n'affiche pas le champ du mot de passe.
Cette vue expose explicitement la colonne OID de la table sous-jacente car elle est ncessaire pour raliser des jointures avec les
autres catalogues.
Tableau 45.60. Colonnes de pg_roles

Nom

Type

Rfrences

Description

rolname

name

Nom du rle

rolsuper

bool

Le rle est un superutilisateur

rolall

bool

Le rle hrite automatiquement des droits des rles dont


il est membre

rolcreaterole

bool

Le rle peut crer d'autres rles

rolcreatedb

bool

Le rle peut crer des bases de donnes

rolcatupdate

bool

Le rle peut mettre jour explicitement les catalogues


systme. (Mme un superutilisateur ne peut pas le faire si
cette colonne n'est pas positionne true.)

rolcanlogin

bool

Le rle peut se connecter, c'est--dire que ce rle peut


tre indiqu comme identifiant initial d'autorisation de
session.

rolreplication bool

Le rle est un rle de rplication. Autrement dit, ce rle


peut tre utilis pour lancer une rplication en flux (voir
Section 25.2.5, Streaming Replication ) et peut mettre
en place le mode de sauvegarde systme en utilisant les
fonctions pg_start_backup et pg_stop_backup.

rolconnlimit

int4

Pour les rles autoriss se connecter, ceci indique le


nombre maximum de connexions concurrentes autorises
par rle. -1 signifie qu'il n'y a pas de limite.

rolpassword

text

Ce n'est pas le mot de passe (toujours ********)

rolvaliduntil

timestamptz

Estampille temporelle d'expiration du mot de passe


(utilise uniquement pour l'authentification par mot de
passe) ; NULL s'il est indfiniment valable

rolconfig

text[]

Valeurs par dfaut de certaines variables spcifiques pour


ce rle

oid

oid

Identifiant du rle

pg_authid.oid

45.60. pg_rules
La vue pg_rules fournit un accs des informations utiles sur les rgles de rcriture des requtes.
Tableau 45.61. Colonnes de pg_rules

Nom

Type

Rfrences

Description

schemaname

name

pg_namespace.nspname

Nom du schma contenant la table

tablename

name

pg_class.relname

Nom de la table pour laquelle est cre la rgle

rulename

name

pg_rewrite.rulename

Nom de la rgle

definition

text

Dfinition de la rgle (une commande de cration reconstruite)

La vue pg_rules exclut les rgles ON SELECT des vues ; elles sont accessibles dans pg_views.

1267

Catalogues systme

45.61. pg_seclabels
La vue pg_seclabels fournit des informations sur les labels de scurit. C'est une version du catalogue pg_seclabel bien plus lisible.
Tableau 45.62. Colonnes de pg_seclabels

Nom

Type

Rfrence

Description

objoid

oid

toute colonne OID

L'OID de l'objet concern par


ce label de scurit

classoid

oid

pg_class.oid

L'OID du catalogue systme o


cet objet apparat

objsubid

int4

Pour un label de scurit sur


une colonne d'une table, cette
colonne correspond au numro
de colonne (les colonnes objoid et classoid font rfrence la table). Pour tous les
autres types d'objets, cette colonne vaut zro.

objtype

text

Le
type
d'objet
auquel
s'applique ce label, en texte.

objnamespace

oid

objname

text

provider

text

pg_seclabel.provider

Le fournisseur associ ce label.

label

text

pg_seclabel.label

Le label de scurit appliqu


cet objet.

pg_namespace.oid

L'OID du schma de cet objet


si applicable ; NULL dans les
autres cas.
Le nom de l'objet auquel
s'applique ce label, en texte.

45.62. pg_settings
La vue pg_settings fournit un accs aux paramtres d'excution du serveur. C'est essentiellement une interface alternative aux
commandes SHOW(7) et SET(7). Elle fournit aussi un accs certaines informations des paramtres qui ne sont pas directement
accessibles avec SHOW, telles que les valeurs minimales et maximales.
Tableau 45.63. Colonnes de pg_settings

Nom

Type

Description

name

text

Nom du paramtre d'excution

setting

text

Valeur actuelle du paramtre

unit

text

Unit implicite du paramtre

category

text

Groupe logique du paramtre

short_desc

text

Description brve du paramtre

extra_desc

text

Information supplmentaire, plus dtaille, sur le paramtre

context

text

Contexte requis pour positionner la valeur du paramtre (voir ci-dessous)

vartype

text

Type du paramtre (bool, enum, integer, real ou string)

source

text

Source de la valeur du paramtre actuel

min_val

text

Valeur minimale autorise du paramtre (NULL pour les valeurs non numriques)

max_val

text

Valeur maximale autorise du paramtre (NULL pour les valeurs non numriques)
1268

Catalogues systme

Nom

Type

Description

enumvals

text[]

Valeurs autorises pour un paramtre enum (NULL pour les valeurs non
enum)

boot_val

text

Valeur de paramtre prise au dmarrage du serveur si le paramtre n'est pas


positionn d'une autre faon

reset_val

text

Valeur laquelle RESET ramnerait le paramtre dans la session courante

sourcefile

text

Fichier de configuration dans lequel ce fichier a t positionn (NULL pour


les valeurs positionnes ailleurs que dans un fichier de configuration, ou
quand interrog par un utilisateur standard). Pratique quand on utilise des directives d'inclusion de configuration

sourceline

integer

Numro de ligne du fichier de configuration laquelle cette valeur a t positionne (NULL pour des valeurs positionnes ailleurs que dans un fichier de
configuration, ou quand interrog par un non-superutilisateur).

Il existe diffrentes valeurs de context. Les voici, classes dans l'ordre de difficult dcroissante pour la modification d'un paramtre :
internal
Ces paramtres ne peuvent pas tre modifis directement ; ils refltent des valeurs internes. Certaines sont modifiables en
compilant le serveur avec des options diffrentes pour l'tape de configuration, ou en changeant des options lors de l'tape du
initdb.
postmaster
Ces paramtres sont seulement appliqus au dmarrage du serveur, donc toute modification ncessite un redmarrage du serveur. Les valeurs sont typiquement conserves dans le fichier postgresql.conf ou passes sur la ligne de commande
lors du lancement du serveur. Bien sr, tout paramtre dont la colonne context est infrieure peut aussi tre configur au
dmarrage du serveur.
sighup
Les modifications sur ces paramtres peuvent se faire dans le fichier postgresql.conf sans avoir redmarrer le serveur. L'envoi d'un signal SIGHUP au processus pre (historiquement appel postmaster) le forcera relire le fichier postgresql.conf et appliquer les modifications. Ce processus enverra aussi le signal SIGHUP aux processus fils pour qu'ils
tiennent compte des nouvelles valeurs.
backend
Les modifications sur ces paramtres peuvent se faire dans le fichier postgresql.conf sans avoir redmarrer le serveur ; ils peuvent aussi tre configurs pour une session particulire dans le paquet de demande de connexion (par exemple,
via la variable d'environnement PGOPTIONS gre par la bibliothque libpq). Nanmoins, ces modifications ne changent jamais une fois que la session a dmarr. Si vous les changez dans le fichier postgresql.conf, envoyez un signal SIGHUP
postmaster car a le forcera relire le fichier postgresql.conf. Les nouvelles valeurs affecteront seulement les sessions lances aprs la relecture de la configuration.
superuser
Ces paramtres sont configurables partir du fichier postgresql.conf ou l'intrieur d'une session via la commande
SET ; mais seuls les superutilisateurs peuvent les modifier avec SET. Les modifications apportes dans le fichier postgresql.conf affecteront aussi les sessions existantes si aucune valeur locale la session n'a t tablie avec une commande SET.
user
Ces paramtres peuvent tre configurs partir du fichier postgresql.conf ou l'intrieur d'une session via la commande SET. Tout utilisateur est autoris modifier la valeur sur sa session. les modifi Any user is allowed to change his session-local value. Les modifications apportes dans le fichier postgresql.conf affecteront aussi les sessions existantes si
aucune valeur locale la session n'a t tablie avec une commande SET.
Voir Section 18.1, Paramtres de configuration pour plus d'informations sur les diffrentes faons de modifier ces paramtres.
La vue pg_settings n'accepte ni insertion ni suppression mais peut tre actualise. Une requte UPDATE applique une ligne de
pg_settings est quivalente excuter la commande SET(7) sur ce paramtre. Le changement affecte uniquement la valeur utilise
par la session en cours. Si un UPDATE est lanc l'intrieur d'une transaction annule par la suite, les effets de la commande UPDATE disparaissent l'annulation de la transaction. Lorsque la transaction est valide, les effets persistent jusqu' la fin de la session, moins qu'un autre UPDATE ou SET ne modifie la valeur.

1269

Catalogues systme

45.63. pg_shadow
La vue pg_shadow existe pour des raisons de compatibilit ascendante : elle mule un catalogue qui a exist avant la version 8.1
de PostgreSQL. Elle affiche les proprits de tous les rles marqus rolcanlogin dans pg_authid.
Cette table tire son nom de la ncessit de ne pas tre publiquement lisible, car elle contient les mots de passe. pg_user est une vue
sur pg_shadow, publiquement accessible, car elle masque le contenu du champ de mot de passe.
Tableau 45.64. Colonnes de pg_shadow

Nom

Type

Rfrences

Description

usename

name

pg_authid.rolname

Nom de l'utilisateur

usesysid

oid

pg_authid.oid

Identifiant de l'utilisateur

usecreatedb

bool

L'utilisateur peut crer des bases de donnes

usesuper

bool

L'utilisateur est un superutilisateur

usecatupd

bool

L'utilisateur peut mettre jour les catalogues systme.


(Mme un superutilisateur ne peut pas le faire si cette colonne ne vaut pas true.)

passwd

text

Mot de passe (ventuellement chiffr) ; NULL si aucun.


Voir pg_authid pour des dtails sur le stockage des mots
de passe chiffrs.

valuntil

abstime

Estampille temporelle d'expiration du mot de passe


(utilise uniquement pour l'authentification par mot de
passe)

useconfig

text[]

Valeurs de session par dfaut des variables de configuration

45.64. pg_stats
La vue pg_stats fournit un accs aux informations stockes dans la table systme pg_statistic. Cette vue n'autorise l'accs qu'aux
seules lignes de pg_statistic correspondant aux tables sur lesquelles l'utilisateur a un droit de lecture. Elle peut donc sans risque
tre publiquement accessible en lecture.
pg_stats est aussi conue pour afficher l'information dans un format plus lisible que le catalogue sous-jacent -- au prix de
l'extension du schma lorsque de nouveaux types de connecteurs sont dfinis dans pg_statistic.
Tableau 45.65. Colonnes de pg_stats

Nom

Type

Rfrences

Description

schemaname

name

pg_namespace.nspname

Nom du schma contenant la table

tablename

name

pg_class.relname

Nom de la table

attname

name

pg_attribute.attname

Nom de la colonne dcrite par la ligne

alled

bool

Si vrai, cette ligne inclut les colonnes enfant de l'hritage,


pas seulement les valeurs de la table spcifie

null_frac

real

Fraction d'entres de colonnes qui sont NULL

avg_width

integer

Largeur moyenne en octets des entres de la colonne

n_distinct

real

Si positif, nombre estim de valeurs distinctes dans la colonne. Si ngatif, nombre de valeurs distinctes divis par
le nombre de lignes, le tout mulipli par -1. (La forme ngative est utilise quand ANALYZE croit que le nombre
de valeurs distinctes a tendance grossir au fur et mesure que la table grossit ; la forme positive est utilise
lorsque la commande semble avoir un nombre fixe de valeurs possibles.) Par exemple, -1 indique une colonne
unique pour laquelle le nombre de valeurs distinctes est
identique au nombre de lignes.
1270

Catalogues systme

Nom

Type

Rfrences

Description

most_common_va anyarray
ls

Liste de valeurs habituelles de la colonne. (NULL si aucune valeur ne semble identique aux autres.) Pour certains types de donnes comme tsvector, c'est une liste
d'lments les plus frquents, plutt que des valeurs du
type lui-mme.

most_common_fr real[]
eqs

Liste de frquences des valeurs ou lments les plus courants, c'est--dire le nombre d'occurrences de chacune divis par le nombre total de lignes. (NULL lorsque
most_common_vals l'est.) Pour certains types de donnes comme tsvector, il peut aussi stocker des informations supplmentaires, le rendant plus long que le tableau
most_common_vals.

histogram_bounds

anyarray

Liste de valeurs qui divisent les valeurs de la colonne en


groupes de population approximativement identiques.
Les valeurs dans most_common_vals, s'il y en a, sont
omises de ce calcul d'histogramme. (Cette colonne est
NULL si le type de donnes de la colonne ne dispose pas
de l'oprateur < ou si la liste most_common_vals
compte la population complte.)

correlation

real

Corrlation statistique entre l'ordre physique des lignes et


l'ordre logique des valeurs de la colonne. Ceci va de -1
+1. Lorsque la valeur est proche de -1 ou +1, un parcours
de l'index sur la colonne est estim moins coteux que si
cette valeur tend vers 0, cause de la rduction du
nombre d'accs alatoires au disque. (Cette colonne est
NULL si le type de donnes de la colonne ne dispose pas
de l'oprateur <.)

Le nombre maximum d'entres dans most_common_vals et histogram_bounds est configurable colonne par colonne en
utilisant la commande ALTER TABLE SET STATISTICS ou globalement avec le paramtre d'excution default_statistics_target.

45.65. pg_tables
La vue pg_tables fournit un accs aux informations utiles de chaque table de la base de donnes.
Tableau 45.66. Colonnes de pg_tables

Nom

Type

Rfrences

Description

schemaname

name

pg_namespace.nspname

Nom du schma qui possde la table

tablename

name

pg_class.relname

Nom de la table

tableowner

name

pg_authid.rolname

Nom du propritaire de la table

tablespace

name

pg_tablespace.spcname Nom du tablespace qui contient la table (NULL s'il s'agit


du tablespace par dfaut de la base)

hasindexes

boolean

pg_class.relhasindex

Vrai si la table comporte (ou a rcemment comport) des


index

hasrules

boolean

pg_class.relhasrules

Vrai si la table dispose (ou disposait) de rgles

hastriggers

boolean

pg_class.reltriggers

Vrai si la table dispose (ou disposait) de dclencheurs

45.66. pg_timezone_abbrevs
La vue pg_timezone_abbrevs fournit la liste des abrviations de fuseaux horaires actuellement reconnues par les routines de saisie
date/heure. Le contenu de cette vue change avec la modification du paramtre d'excution timezone_abbreviations.
Tableau 45.67. Colonnes de pg_timezone_abbrevs

1271

Catalogues systme

Nom

Type

Description

abbrev

text

Abrviation du fuseau horaire

utc_offset

interval

Dcalage de l'UTC (positif signifiant


l'est de Greenwich)

is_dst

boolean

true s'il s'agit d'une abrviation de fuseau horaire soumis aux changements
d'heure hiver/t

45.67. pg_timezone_names
La vue pg_timezone_names fournit la liste des noms de fuseaux horaires reconnus par SET TIMEZONE, avec les abrviations
acceptes, les dcalages UTC, et l'tat du changement d'heure. (Techniquement, PostgreSQL utilise UT1 plutt que UTC car les
secondes intercalaires ne sont pas gres.) Contrairement aux abrviations indiques dans pg_timezone_abbrevs, la majorit des
noms impliquent des rgles concernant les dates de changement d'heure. De ce fait, l'information associe change en fonction des
frontires de changement d'heure locales. L'information affiche est calcule suivant la valeur courante de CURRENT_TIMESTAMP.
Tableau 45.68. Colonnes de pg_timezone_names

Nom

Type

Description

name

text

Nom du fuseau horaire

abbrev

text

Abrviation du fuseau horaire

utc_offset

interval

Dcalage partir d'UTC (positif signifiant


l'est de Greenwich)

is_dst

boolean

true si les changements d'heure hiver/t


sont suivis

45.68. pg_user
La vue pg_user fournit un accs aux informations concernant les utilisateurs de la base de donnes. C'est une simple vue publiquement lisible de pg_shadow qui masque la valeur du champ de mot de passe.
Tableau 45.69. Colonnes de pg_user

Nom

Type

Description

usename

name

Nom de l'utilisateur

usesysid

int4

Identifiant de l'utilisateur (un nombre arbitraire utilis en rfrence cet utilisateur)

usecreatedb

bool

L'utilisateur peut crer des bases de donnes

usesuper

bool

L'utilisateur est un superutilisateur

usecatupd

bool

L'utilisateur peut mettre jour les tables systmes. (Mme un superutilisateur


ne peut pas le faire si cette colonne n'est pas positionne true.)

passwd

text

Ce n'est pas le mot de passe (toujours ********)

valuntil

abstime

Estampille temporelle d'expiration du mot de passe (utilise uniquement pour


l'authentification par mot de passe)

useconfig

text[]

Variables d'excution par dfaut de la session

45.69. pg_user_mappings
La vue pg_user_mappings donne accs aux informations sur les correspondances d'utilisateurs. C'est essentiellement une vue accessible tous sur pg_user_mapping qui cache le champ d'options si l'utilisateur n'a pas le droit de l'utiliser.

1272

Catalogues systme

Tableau 45.70. Colonnes de pg_user_mappings

Nom

Type

Rference

umid

oid

pg_user_mapping.oid

srvid

oid

pg_foreign_server.oid

srvname

text

umuser

oid

usename

name

umoptions

text[]

pg_authid.oid

45.70. pg_views
La vue pg_views donne accs des informations utiles propos de chaque vue de la base.
Tableau 45.71. Colonnes de pg_views

Nom

Type

Rfrences

Description

schemaname

name

pg_namespace.nspname

Nom du schma contenant la vue

viewname

name

pg_class.relname

Nom de la vue

viewowner

name

pg_authid.rolname

Nom du propritaire de la vue

definition

text

Dfinition de la vue (une requte SELECT reconstruite)

1273

Chapitre 46. Protocole client/serveur


postgresql utilise un protocole messages pour la communication entre les clients et les serveurs ( frontend et backend ).
le protocole est support par tcp/ip et par les sockets de domaine Unix. Le numro de port 5432 a t enregistr par l'IANA
comme numro de port TCP personnalis pour les serveurs supportant ce protocole mais en pratique tout numro de port non
privilgi peut tre utilis.
Ce document dcrit la version 3.0 de ce protocole, telle qu'implante dans postgresql depuis la version 7.4. pour obtenir la
description des versions prcdentes du protocole, il faudra se reporter aux versions antrieures de la documentation de postgresql. un mme serveur peut supporter plusieurs versions du protocole. Lors de l'tablissement de la communication le client
indique au serveur la version du protocole qu'il souhaite utiliser. Le serveur suivra ce protocole s'il en est capable.
Pour rpondre efficacement de multiples clients, le serveur lance un nouveau serveur ( backend ) pour chaque client. dans
l'implmentation actuelle, un nouveau processus fils est cr immdiatement aprs la dtection d'une connexion entrante. Et cela
de faon transparente pour le protocole. Pour le protocole, les termes backend et serveur sont interchangeables ; comme
frontend , interface et client .

46.1. Aperu
Le protocole utilise des phases distinctes pour le lancement et le fonctionnement habituel. Dans la phase de lancement, le client
ouvre une connexion au serveur et s'authentifie (ce qui peut impliquer un message simple, ou plusieurs messages, en fonction de
la mthode d'authentification utilise). En cas de russite, le serveur envoie une information de statut au client et entre dans le
mode normal de fonctionnement. Exception faite du message initial de demande de lancement, cette partie du protocole est
conduite par le serveur.
En mode de fonctionnement normal, le client envoie requtes et commandes au serveur et celui-ci retourne les rsultats de requtes et autres rponses. Il existe quelques cas (comme notify) pour lesquels le serveur enverra des messages non sollicits.
Mais dans l'ensemble, cette partie de la session est conduite par les requtes du client.
En gnral, c'est le client qui dcide de la clture de la session. Il arrive, cependant, qu'elle soit force par le moteur. Dans tous
les cas, lors de la fermeture de la connexion par le serveur, toute transaction ouverte (non termine) sera annule.
En mode oprationnel normal, les commandes SQL peuvent tre excutes via deux sous-protocoles. Dans le protocole des
requtes simples , le client envoie juste une chane, la requte, qui est analyse et excute immdiatement par le serveur.
Dans le protocole des requtes tendues , le traitement des requtes est dcoup en de nombreuses tapes : l'analyse, le lien
avec les valeurs de paramtres et l'excution. Ceci offre flexibilit et gains en performances au prix d'une complexit supplmentaire.
Le mode oprationnel normal offre des sous-protocoles supplmentaires pour certaines oprations comme copy.

46.1.1. Aperu des messages


Toute la communication s'effectue au travers d'un flux de messages. Le premier octet d'un message identifie le type de message
et les quatre octets suivants spcifient la longueur du reste du message (cette longueur inclut les 4 octets de longueur, mais pas
l'octet du type de message). Le reste du contenu du message est dtermin par le type de message. Pour des raisons historiques,
le tout premier message envoy par le client (le message de lancement) n'a pas l'octet initial de type du message.
Pour viter de perdre la synchronisation avec le flux de messages, le serveur et le client stocke le message complet dans un tampon (en utilisant le nombre d'octets) avant de tenter de traiter son contenu. Cela permet une rcupration simple si une erreur est
dtecte lors du traitement du contenu. Dans les situations extrmes (telles que de ne pas avoir assez de mmoire pour placer le
message dans le tampon), le rcepteur peut utiliser le nombre d'octets pour dterminer le nombre d'entres ignorer avant de
continuer la lecture des messages.
En revanche, serveurs et clients doivent tre attentifs ne pas envoyer de message incomplet. Ceci est habituellement obtenu en
plaant le message complet dans un tampon avant de commencer l'envoi. Si un chec de communications survient pendant
l'envoi ou la rception d'un message, la seule rponse plausible est l'abandon de la connexion. Il y a, en effet, peu d'espoir de resynchronisation des messages.

46.1.2. Aperu des requtes tendues


Dans le protocole des requtes tendues, l'excution de commandes SQL est scinde en plusieurs tapes. L'tat retenu entre les
tapes est reprsent par deux types d'objets : les instructions prpares et les portails. une instruction prpare reprsente le rsultat de l'analyse syntaxique, de l'analyse smantique et de la planification d'une chane de requte textuelle. Une instruction
prpare n'est pas ncessairement prte tre excute parce qu'il peut lui manquer certaines valeurs de paramtres. un portail
reprsente une instruction prte tre excute ou dj partiellement excute, dont toutes les valeurs de paramtres manquant
1274

Protocole client/serveur

sont donnes (pour les instructions select, un portail est quivalent un curseur ouvert. il est choisi d'utiliser un terme diffrent car
les curseurs ne grent pas les instructions autres que select)
Le cycle d'excution complet consiste en une tape d'analyse syntaxique, qui cre une instruction prpare partir d'une chane de
requte textuelle ; une tape de liaison, qui cre un portail partir d'une instruction prpare et des valeurs pour les paramtres ncessaires ; et une tape d'excution qui excute une requte du portail. Dans le cas d'une requte qui renvoie des lignes (select,
show, etc), il peut tre signal l'tape d'excution que seul un certain nombre de lignes doivent tre retournes, de sorte que de
multiples tapes d'excution seront ncessaires pour terminer l'opration.
Le serveur peut garder la trace de multiples instructions prpares et portails (qui n'existent qu' l'intrieur d'une session, et ne sont
jamais partags entre les sessions). Les instructions prpares et les portails sont rfrencs par les noms qui leur sont affects la
cration. De plus, il existe une instruction prpare et un portail non nomms . bien qu'ils se comportent comme des objets
nomms, les oprations y sont optimises en vue d'une excution unique de la requte avant son annulation puis est annule. En
revanche, les oprations sur les objets nomms sont optimises pour des utilisations multiples.

46.1.3. Formats et codes de format


Les donnes d'un type particulier pouvaient tre transmises sous diffrents formats. depuis postgresql 7.4, les seuls formats supports sont le texte et le binaire mais le protocole prvoit des extensions futures. Le format dsir pour toute valeur est spcifi par un code de format. les clients peuvent spcifier un code de format pour chaque valeur de paramtre transmise et pour
chaque colonne du rsultat d'une requte. Le texte a zro pour code de format zro, le binaire un. Tous les autres codes de format
sont rservs pour des dfinitions futures.
La reprsentation au format texte des valeurs est toute chane produite et accepte par les fonctions de conversion en entre/sortie
pour le type de donnes particulier. Dans la reprsentation transmise, il n'y a pas de caractre nul de terminaison de chane ; le
client doit en ajouter un s'il souhaite traiter les valeurs comme des chanes C (le format texte n'autorise pas les valeurs nulles intgres).
Les reprsentations binaires des entiers utilisent l'ordre d'octet rseau (octet le plus significatif en premier). Pour les autres types
de donnes, il faudra consulter la documentation ou le code source pour connatre la reprsentation binaire. Les reprsentations binaires des types de donnes complexes changent parfois entre les versions du serveur ; le format texte reste le choix le plus portable.

46.2. Flux de messages


Cette section dcrit le flux des messages et la smantique de chaque type de message (les dtails concernant la reprsentation
exacte de chaque message apparaissent dans Section 46.5, Formats de message ). il existe diffrents sous-protocoles en fonction de l'tat de la connexion : lancement, requte, appel de fonction, COPY et clture. Il existe aussi des provisions spciales pour
les oprations asynchrones (incluant les rponses aux notifications et les annulations de commande), qui peuvent arriver tout
moment aprs la phase de lancement.

46.2.1. Lancement
Pour dbuter une session, un client ouvre une connexion au serveur et envoie un message de dmarrage. Ce message inclut les
noms de l'utilisateur et de la base de donnes laquelle le client souhaite se connecter ; il identifie aussi la version particulire du
protocole utiliser (optionnellement, le message de dmarrage peut inclure des prcisions supplmentaires pour les paramtres
d'excution). Le serveur utilise ces informations et le contenu des fichiers de configuration (tels que pg_hba.conf) pour dterminer si la connexion est acceptable et quelle ventuelle authentification supplmentaire est requise.
Le serveur envoie ensuite le message de demande d'authentification appropri, auquel le client doit rpondre avec le message de
rponse d'authentification adapt (tel un mot de passe). Pour toutes les mthodes d'authentification, sauf GSSAPI et SSPI, il y a au
maximum une requte et une rponse. Avec certaines mthodes, aucune rponse du client n'est ncessaire aucune demande
d'authentification n'est alors effectue. Pour GSSAPI et SSPI, plusieurs changes de paquets peuvent tre ncessaire pour terminer
l'authentification.
Le cycle d'authentification se termine lorsque le serveur rejette la tentative de connexion (ErrorResponse) ou l'accepte
(AuthenticationOk).
Les messages possibles du serveur dans cette phase sont :
errorresponse
La tentative de connexion a t rejete. Le serveur ferme immdiatement la connexion.
authenticationok
L'change d'authentification s'est termin avec succs.
authenticationkerberosv5
1275

Protocole client/serveur

Le client doit alors prendre part un dialogue d'authentification Kerberos V5 (spcification Kerberos, non dcrite ici) avec le
serveur. En cas de succs, le serveur rpond AuthenticationOk, ErrorResponse sinon.
authenticationcleartextpassword
Le client doit alors envoyer un PasswordMessage contenant le mot de passe en clair. Si le mot de passe est correct, le serveur
rpond AuthenticationOk, ErrorResponse sinon.
authenticationmd5password
Le client doit alors envoyer un PasswordMessage contenant le mot de passe chiffr l'aide de MD5, en utilisant le composant
salt de quatre caractres spcifi dans le message AuthenticationMD5Password. Si le mot de passe est correct, le serveur rpond AuthenticationOk, ErrorResponse sinon.
authenticationscmcredential
Cette rponse est possible uniquement pour les connexions locales de domaine Unix sur les plateformes qui supportent les
messages de lgitimation SCM. Le client doit fournir un message de lgitimation SCM, puis envoyer une donne d'un octet.
Le contenu de cet octet importe peu ; il n'est utilis que pour s'assurer que le serveur attend assez longtemps pour recevoir le
message de lgitimation. Si la lgitimation est acceptable, le serveur rpond AuthenticationOk, ErrorResponse sinon. (Ce type
de message n'est envoy que par des serveurs dont la version est antrieure la 9.1. Il pourrait tre supprim de la spcification du protocole.)
AuthenticationGSS
L'interface doit maintenant initier une ngociation GSSAPI. L'interface doit envoyer un PasswordMessage avec la premire
partie du flux de donnes GSSAPI en rponse ceci. Si plus de messages sont ncessaires, le serveur rpondra avec AuthenticationGSSContinue.
AuthenticationSSPI
L'interface doit maintenant initier une ngociation SSPI. L'interface doit envoyer un PasswordMessage avec la premire partie
du flux de donnes SSPI en rponse ceci. Si plus de messages sont ncessaires, le serveur rpondra avec AuthenticationGSSContinue.
AuthenticationGSSContinue
Ce message contient les donnes de la rponse de l'tape prcdente pour la ngociation GSSAPI ou SSPI
(AuthenticationGSS ou un prcdent AuthenticationGSSContinue). Si les donnes GSSAPI dans ce message indique que plus
de donnes sont ncessaire pour terminer l'authentification, l'interface doit envoyer cette donne dans un autre PasswordMessage. Si l'authentification GSSAPI ou SSPI est termine par ce message, le serveur enverra ensuite AuthenticationOk pour indiquer une authentification russie ou ErrorResponse pour indiquer l'chec.
Si le client ne supporte pas la mthode d'authentification demande par le serveur, il doit immdiatement fermer la connexion.
Aprs la rception du message AuthenticationOk, le client attend d'autres messages du serveur. Au cours de cette phase, un processus serveur est lanc et le client est simplement en attente. Il est encore possible que la tentative de lancement choue
(ErrorResponse) mais, dans la plupart des cas, le serveur enverra les messages ParameterStatus, BackendKeyData et enfin ReadyForQuery.
Durant cette phase, le serveur tentera d'appliquer tous les paramtres d'excution supplmentaires qui ont t fournis par le message de lancement. En cas de succs, ces valeurs deviennent les valeurs par dfaut de la session. Une erreur engendre ErrorResponse et dclenche la sortie.
Les messages possibles du serveur dans cette phase sont :
backendkeydata
Ce message fournit une cl secrte que le client doit conserver s'il souhaite envoyer des annulations de requtes par la suite.
Le client ne devrait pas rpondre ce message, mais continuer attendre un message ReadyForQuery.
parameterstatus
Ce message informe le client de la configuration actuelle (initiale) des paramtres du serveur, tels client_encoding ou
datestyle. le client peut ignorer ce message ou enregistrer la configuration pour ses besoins futurs ; voir Section 46.2.6,
Oprations asynchrones pour plus de dtails. le client ne devrait pas rpondre ce message mais continuer attendre un
message ReadyForQuery.
readyforquery
Le lancement est termin. Le client peut ds lors envoyer des commandes.
errorresponse
Le lancement a chou. La connexion est ferme aprs l'envoi de ce message.
noticeresponse
Un message d'avertissement a t envoy. Le client devrait afficher ce message mais continuer attendre un ReadyForQuery
ou un ErrorResponse.
1276

Protocole client/serveur

Le mme message ReadyForQuery est envoy chaque cycle de commande. En fonction des besoins de codage du client, il est
possible de considrer ReadyForQuery comme le dbut d'un cycle de commande, ou de le considrer comme terminant la phase
de lancement et chaque cycle de commande.

46.2.2. Requte simple


Un cycle de requte simple est initi par le client qui envoie un message Query au serveur. Le message inclut une commande SQL
(ou plusieurs) exprime comme une chane texte. Le serveur envoie, alors, un ou plusieurs messages de rponse dpendant du
contenu de la chane reprsentant la requte et enfin un message ReadyForQuery. ReadyForQuery informe le client qu'il peut envoyer une nouvelle commande. Il n'est pas ncessaire que le client attende ReadyForQuery avant de lancer une autre commande
mais le client prend alors la responsabilit de ce qui arrive si la commande prcdente choue et que les commandes suivantes, dj lances, russissent.
Les messages de rponse du serveur sont :
commandcomplete
Commande SQL termine normalement.
copyinresponse
Le serveur est prt copier des donnes du client vers une table voir Section 46.2.5, Oprations copy .
copyoutresponse
Le serveur est prt copier des donnes d'une table vers le client ; voir Section 46.2.5, Oprations copy .
rowdescription
Indique que des lignes vont tre envoyes en rponse une requte select, fetch... Le contenu de ce message dcrit le placement des colonnes dans les lignes. Le contenu est suivi d'un message DataRow pour chaque ligne envoye au client.
datarow
Un des ensembles de lignes retourns par une requte select, fetch...
emptyqueryresponse
Une chane de requte vide a t reconnue.
errorresponse
Une erreur est survenue.
readyforquery
Le traitement d'une requte est termin. Un message spar est envoy pour l'indiquer parce qu'il se peut que la chane de la
requte contienne plusieurs commandes SQL. CommandComplete marque la fin du traitement d'une commande SQL, pas de
la chane complte. ReadyForQuery sera toujours envoy que le traitement se termine avec succs ou non.
noticeresponse
Un message d'avertissement concernant la requte a t envoy. Les avertissements sont complmentaires des autres rponses, le serveur continuera traiter la commande.
La rponse une requte select (ou d'autres requtes, telles explain ou show, qui retournent des ensembles de donnes) consiste
normalement en un RowDescription, plusieurs messages DataRow (ou aucun) et pour finir un CommandComplete. copy depuis
ou vers le client utilise un protocole spcial dcrit dans Section 46.2.5, Oprations copy . tous les autres types de requtes produisent uniquement un message CommandComplete.
Puisqu'une chane de caractres peut contenir plusieurs requtes (spares par des points virgules), il peut y avoir plusieurs squences de rponses avant que le serveur ne finisse de traiter la chane. ReadyForQuery est envoy lorsque la chane complte a
t traite et que le serveur est prt accepter une nouvelle chane de requtes.
Si une chane de requtes compltement vide est reue (aucun contenu autre que des espaces fines), la rponse sera EmptyQueryResponse suivie de ReadyForQuery.
En cas d'erreur, ErrorResponse est envoy suivi de ReadyForQuery. Tous les traitements suivants de la chane sont annuls par ErrorResponse (quelque soit le nombre de requtes restant traiter). Ceci peut survenir au milieu de la squence de messages engendrs par une requte individuelle.
En mode de requtage simple, les valeurs rcupres sont toujours au format texte, sauf si la commande est un fetch sur un curseur dclar avec l'option binary. dans ce cas, les valeurs rcupres sont au format binaire. Les codes de format donns dans le
message RowDescription indiquent le format utilis.
La planification de requtes pour des instructions prpares survient lorsque le message Parse est reu. Si une requte sera excut
de faon rpt avec diffrents paramtres, il pourrait tre bnfique d'envoyer un seul message Parse contenant une requte avec
paramtres, suivie de plusieurs messages Bind et Execute. Ceci vitera de planifier de nouveau la requte pour chaque excution.
1277

Protocole client/serveur

L'instruction prpare non nomme est planifie lors du traitement de Parse si le message Parse ne dfinit aucun paramtre. Mais
s'il existe des paramtres, la planification de la requte est repousse jusqu' ce que le premier message Bind de cette instruction
est reu. Le planificateur considrera les valeurs relles des paramtres fournies dans le message Bind lors de la planification de la
requte.

Note
Les plans de requtes gnrs partir d'une requte avec paramtres pourraient tre moins efficaces que les plans
de requtes gnrs partir d'une requte quivalente dont les valeurs de paramtres relles ont t places. Le planificateur de requtes ne peut pas prendre les dcisions suivant les valeurs relles des paramtres (par exemple, la
slectivit de l'index) lors de la planification d'une requte avec paramtres affecte un objet instruction prpare
nomme. La pnalit possible est vite lors de l'utilisation d'une instruction non nomme car elle n'est pas planifie jusqu' ce que des valeurs relles de paramtres soient disponibles.
Si un autre Bind rfrenant l'objet instruction prpare non nomme est reu, la requte n'est pas de nouveau planifie. Les valeurs de paramtres utilises dans le premier message Bind pourrait produire un plan de requte qui
est seulement efficace pour un sous-ensemble des valeurs de paramtres possibles. Pour forcer une nouvelle planification de la requte pour un ensemble nouveau de paramtres, envoyez un autre message Parse pour remplacer
l'objet instruction prpare non nomme.
Un client doit tre prpar accepter des messages ErrorResponse et NoticeResponse quand bien mme il s'attendrait un autre
type de message. Voir aussi Section 46.2.6, Oprations asynchrones concernant les messages que le client pourrait engendrer
du fait d'vnements extrieurs.
La bonne pratique consiste coder les clients dans un style machine-tat qui acceptera tout type de message tout moment plutt
que de parier sur la squence exacte des messages.

46.2.3. Requte tendue


Le protocole de requte tendu divise le protocole de requtage simple dcrit ci-dessus en plusieurs tapes. Les rsultats des tapes
de prparation peuvent tre rutiliss plusieurs fois pour plus d'efficacit. De plus, des fonctionnalits supplmentaires sont disponibles, telles que la possibilit de fournir les valeurs des donnes comme des paramtres spars au lieu d'avoir les insrer directement dans une chane de requtes.
Dans le protocole tendu, le client envoie tout d'abord un message Parse qui contient une chane de requte, optionnellement
quelques informations sur les types de donnes aux emplacements des paramtres, et le nom de l'objet de destination d'une instruction prpare (une chane vide slectionne l'instruction prpare sans nom). La rponse est soit ParseComplete soit ErrorResponse.
Les types de donnes des paramtres peuvent tre spcifis par l'OID ; dans le cas contraire, l'analyseur tente d'infrer les types de
donnes de la mme faon qu'il le ferait pour les constantes chanes littrales non types.

Note
Un type de paramtre peut tre laiss non spcifi en le positionnant O, ou en crant un tableau d'OID de type
plus court que le nombre de paramtres ($n) utiliss dans la chane de requte. Un autre cas spcial est d'utiliser
void comme type de paramtre (c'est dire l'OID du pseudo-type void). Cela permet d'utiliser des paramtres dans
des fonctions en tant qu'argument OUT. Gnralement, il n'y a pas de contexte dans lequel void peut tre utilis,
mais si un tel paramtre apparat dans les arguments d'une fonction, il sera simplement ignor. Par exemple, un appel de fonction comme foo($1,$2,$3,$4) peu correspondre une fonction avec 2 arguments IN et 2 autres
OUT si $3 et $4 sont spcifis avec le type void.

Note
La chane contenue dans un message Parse ne peut pas inclure plus d'une instruction SQL, sinon une erreur de syntaxe est rapporte. Cette restriction n'existe pas dans le protocole de requte simple, mais est prsente dans le protocole tendu. En effet, permettre aux instructions prpares ou aux portails de contenir de multiples commandes
compliquerait inutilement le protocole.
En cas de succs de sa cration, une instruction prpare nomme dure jusqu' la fin de la session courante, sauf si elle est dtruite
explicitement. Une instruction prpare non nomme ne dure que jusqu' la prochaine instruction Parse spcifiant l'instruction non
nomme comme destination. Un simple message Query dtruit galement l'instruction non nomme. Les instructions prpares
nommes doivent tre explicitement closes avant de pouvoir tre redfinies par un message Parse. Ce n'est pas obligatoire pour
une instruction non nomme. Il est galement possible de crer des instructions prpares nommes, et d'y accder, en ligne de
1278

Protocole client/serveur

commandes SQL l'aide des instructions prepare et execute.


Ds lors qu'une instruction prpare existe, elle est dclare excutable par un message Bind. Le message Bind donne le nom de
l'instruction prpare source (une chane vide dsigne l'instruction prpare non nomme), le nom du portail destination (une
chane vide dsigne le portail non nomm) et les valeurs utiliser pour tout emplacement de paramtres prsent dans l'instruction
prpare. L'ensemble des paramtres fournis doit correspondre ceux ncessaires l'instruction prpare. Bind spcifie aussi le
format utiliser pour toutes les donnes renvoyes par la requte ; le format peut tre spcifi compltement ou par colonne. La
rponse est, soit BindComplete, soit ErrorResponse.

Note
Le choix entre sortie texte et binaire est dtermin par les codes de format donns dans Bind, quelque soit la commande SQL implique. L'attribut BINARY dans les dclarations du curseur n'est pas pertinent lors de l'utilisation du
protocole de requte tendue.
La planification d'un requte prpare nomme se fait lorsque le message Parse est trait. Si une requte est excute plusieurs
fois, avec diffrents paramtres, il peut tre bnfique d'envoyer un seul message Parse contenant la requte paramtre, suivie de
plusieurs messages Bind et Execute. Cette mthode permet d'viter de replanifier la requte chaque excution.
Une requte prpare non nomme est aussi planifie lors du traitement de Parse si ce dernier ne dfini pas de paramtres. Si des
paramtres sont utiliss, la planification se fera chaque fois que les valeurs des paramtres seront transmis par le message Bind.
Ce comportement permet au planificateur de prendre en compte les valeurs des paramtres du Bind au moment de crer son plan
d'excution plutt que d'utiliser un plan gnrique estim.

Note
Les plans d'excution gnrs pour une requte paramtre peuvent tre moins efficaces que ceux gnrs pour une
requte quivalente avec les paramtres directement substitus. Le planificateur de requte ne peut pas prendre de
dcision se basant sur les valeurs relles des paramtres (par exemple, la slectivit d'un index) lors de la planification d'une requte paramtre nomme. Cette pnalit potentielle peut tre vite en utilisant des requtes prpare
non nommes, puisque'elles ne seront pas planifies avant que les valeurs des paramtres soient disponibles. La
contrepartie est que la planification doit alors tre effectue chaque message Bind, mme si la requte reste la
mme.
En cas de succs de sa cration, un objet portail nomm dure jusqu' la fin de la transaction courante sauf s'il est explicitement dtruit. Un portail non nomm est dtruit la fin de la transaction ou ds la prochaine instruction Bind spcifiant le portail non nomm comme destination. Un simple message Query dtruit galement le portail non nomm. Les portails nomms doivent tre explicitement ferms avant de pouvoir tre redfinis par un message Bind. Cela n'est pas obligatoire pour le portail non nomm. Il
est galement possible de crer des portails nomms, et d'y accder, en ligne de commandes SQL l'aide des instructions declare
cursor et fetch.
Ds lors qu'un portail existe, il peut tre excut l'aide d'un message Execute. Ce message spcifie le nom du portail (une chane
vide dsigne le portail non nomm) et un nombre maximum de lignes de rsultat (zro signifiant la rcupration de toutes les
lignes ). le nombre de lignes de rsultat a seulement un sens pour les portails contenant des commandes qui renvoient des ensembles de lignes ; dans les autres cas, la commande est toujours excute jusqu' la fin et le nombre de lignes est ignor. Les rponses possibles d'Execute sont les mme que celles dcrites ci-dessus pour les requtes lances via le protocole de requte
simple, si ce n'est qu'Execute ne cause pas l'envoi de ReadyForQuery ou de RowDescription.
Si Execute se termine avant la fin de l'excution d'un portail (du fait d'un nombre de lignes de rsultats diffrent de zro), il enverra un message PortalSuspended ; la survenue de ce message indique au client qu'un autre Execute devrait tre lanc sur le mme
portail pour terminer l'opration. Le message CommandComplete indiquant la fin de la commande SQL n'est pas envoy avant
l'excution complte du portail. Une phase Execute est toujours termine par la survenue d'un seul de ces messages : CommandComplete, EmptyQueryResponse (si le portail a t cr partir d'une chane de requte vide), ErrorResponse ou PortalSuspended.
la ralisation complte de chaque srie de messages de requtes tendues, le client doit lancer un message Sync. Ce message
sans paramtre oblige le serveur fermer la transaction courante si elle n'est pas l'intrieur d'un bloc de transaction begin/commit ( fermer signifiant valider en l'absence d'erreur ou annuler sinon). Une rponse ReadyForQuery est alors envoye. Le but
de Sync est de fournir un point de resynchronisation pour les rcuprations d'erreurs. Quand une erreur est dtecte lors du traitement d'un message de requte tendue, le serveur lance ErrorResponse, puis lit et annule les messages jusqu' ce qu'un Sync soit
atteint. Il envoie ensuite ReadyForQuery et retourne au traitement normal des messages. Aucun chappement n'est ralis si une
erreur est dtecte lors du traitement de sync -- l'unicit du ReadyForQuery envoy pour chaque Sync est ainsi assure.

1279

Protocole client/serveur

Note
Sync n'impose pas la fermeture d'un bloc de transactions ouvert avec begin. cette situation est dtectable car le
message ReadyForQuery inclut le statut de la transaction.
En plus de ces oprations fondamentales, requises, il y a plusieurs oprations optionnelles qui peuvent tre utilises avec le protocole de requte tendue.
Le message Describe (variante de portail) spcifie le nom d'un portail existant (ou une chane vide pour le portail non nomm). La
rponse est un message RowDescription dcrivant les lignes qui seront renvoyes par l'excution du portail ; ou un message NoData si le portail ne contient pas de requte renvoyant des lignes ; ou ErrorResponse le portail n'existe pas.
Le message Describe (variante d'instruction) spcifie le nom d'une instruction prpare existante (ou une chane vide pour
l'instruction prpare non nomme). La rponse est un message ParameterDescription dcrivant les paramtres ncessaires
l'instruction, suivi d'un message RowDescription dcrivant les lignes qui seront renvoyes lors de l'ventuelle excution de
l'instruction (ou un message NoData si l'instruction ne renvoie pas de lignes). ErrorResponse est retourn si l'instruction prpare
n'existe pas. Comme Bind n'a pas encore t excut, les formats utiliser pour les lignes retournes ne sont pas encore connues
du serveur ; dans ce cas, les champs du code de format dans le message RowDescription seront composs de zros.

Astuce
Dans la plupart des scnarios, le client devra excuter une des variantes de Describe avant de lancer Execute pour
s'assurer qu'il sait interprter les rsultats reus.
Le message Close ferme une instruction prpare ou un portail et libre les ressources. L'excution de Close sur une instruction ou
un portail inexistant ne constitue pas une erreur. La rponse est en gnral CloseComplete mais peut tre ErrorResponse si une
difficult quelconque est rencontre lors de la libration des ressources. Clore une instruction prpare ferme implicitement tout
autre portail ouvert construit partir de cette instruction.
Le message Flush n'engendre pas de sortie spcifique, mais force le serveur dlivrer toute donne restante dans les tampons de
sortie. Un Flush doit tre envoy aprs toute commande de requte tendue, l'exception de Sync, si le client souhaite examiner le
rsultat de cette commande avant de lancer d'autres commandes. Sans Flush, les messages retourns par le serveur seront combins en un nombre minimum de paquets pour minimiser la charge rseau.

Note
Le message Query simple est approximativement quivalent aux sries Parse, Bind, Describe sur un portail, Execute, Close, Sync utilisant les objets de l'instruction prpare ou du portail, non nomms et sans paramtres. Une
diffrence est l'acceptation de plusieurs instructions SQL dans la chane de requtes, la squence bind/describe/execute tant automatiquement ralise pour chacune, successivement. Il en diffre galement en ne retournant pas les messages ParseComplete, BindComplete, CloseComplete ou NoData.

46.2.4. Appel de fonction


Le sous-protocole d'appel de fonction (NDT : Function Call dans la version originale) permet au client d'effectuer un appel direct
toute fonction du catalogue systme pg_proc de la base de donnes. Le client doit avoir le droit d'excution de la fonction.

Note
Le sous-protocole d'appel de fonction est une fonctionnalit qu'il vaudrait probablement mieux viter dans tout
nouveau code. Des rsultats similaires peuvent tre obtenus en initialisant une instruction prpare qui lance select function($1, ...). le cycle de l'appel de fonction peut alors tre remplac par Bind/Execute.
Un cycle d'appel de fonction est initi par le client envoyant un message FunctionCall au serveur. Le serveur envoie alors un ou
plusieurs messages de rponse en fonction des rsultats de l'appel de la fonction et finalement un message de rponse ReadyForQuery. ReadyForQuery informe le client qu'il peut envoyer en toute scurit une nouvelle requte ou un nouvel appel de fonction.
Les messages de rponse possibles du serveur sont :
errorresponse
Une erreur est survenue.
functioncallresponse
1280

Protocole client/serveur

L'appel de la fonction est termin et a retourn le rsultat donn dans le message. Le protocole d'appel de fonction ne peut grer qu'un rsultat scalaire simple, pas un type ligne ou un ensemble de rsultats.
readyforquery
Le traitement de l'appel de fonction est termin. ReadyForQuery sera toujours envoy, que le traitement se termine avec succs ou avec une erreur.
noticeresponse
Un message d'avertissement relatif l'appel de fonction a t retourn. Les avertissements sont complmentaires des autres
rponses, c'est--dire que le serveur continuera traiter la commande.

46.2.5. Oprations copy


La commande copy permet des transferts rapides de donnes en lot vers ou partir du serveur. Les oprations Copy-in et Copyout basculent chacune la connexion dans un sous-protocole distinct qui existe jusqu' la fin de l'opration.
Le mode Copy-in (transfert de donnes vers le serveur) est initi quand le serveur excute une instruction SQL copy from stdin.
le serveur envoie une message CopyInResponse au client. Le client peut alors envoyer zro (ou plusieurs) message(s) CopyData,
formant un flux de donnes en entre (il n'est pas ncessaire que les limites du message aient un rapport avec les limites de la
ligne, mais cela est souvent un choix raisonnable). Le client peut terminer le mode Copy-in en envoyant un message CopyDone
(permettant une fin avec succs) ou un message CopyFail (qui causera l'chec de l'instruction SQL copy avec une erreur). Le serveur retourne alors au mode de traitement de la commande prcdant le dbut de copy, protocole de requte simple ou tendu. il
enverra enfin CommandComplete (en cas de succs) ou ErrorResponse (sinon).
Si le serveur dtecte un erreur en mode copy-in (ce qui inclut la rception d'un message CopyFail), il enverra un message ErrorResponse. Si la commande copy a t lance l'aide d'un message de requte tendue, le serveur annulera les messages du client
jusqu' ce qu'un message Sync soit reu. Il enverra alors un message ReadyForQuery et retournera dans le mode de fonctionnement normal. Si la commande copy a t lance dans un message simple Query, le reste de ce message est annul et ReadyForQuery est envoy. Dans tous les cas, les messages CopyData, CopyDone ou CopyFail suivants envoys par l'interface seront simplement annuls.
Le serveur ignorera les messages Flush et Sync reus en mode copy-in. La rception de tout autre type de messages hors-copie
constitue une erreur qui annulera l'tat Copy-in, comme cela est dcrit plus haut. L'exception pour Flush et Sync est faite pour les
bibliothques clientes qui envoient systmatiquement Flush ou Sync aprs un message Execute sans vrifier si la commande
excuter est copy from stdin.
Le mode Copy-out (transfert de donnes partir du serveur) est initi lorsque le serveur excute une instruction SQL copy to stdout. Le moteur envoie un message CopyOutResponse au client suivi de zro (ou plusieurs) message(s) CopyData (un par ligne),
suivi de CopyDone. Le serveur retourne ensuite au mode de traitement de commande dans lequel il se trouvait avant le lancement
de copy et envoie commandcomplete. Le client ne peut pas annuler le transfert (sauf en fermant la connexion ou en lanant une requte d'annulation, Cancel), mais il peut ignorer les messages CopyData et CopyDone non souhaits.
Si le serveur dtecte une erreur en mode Copy-out, il enverra un message ErrorResponse et retournera dans le mode de traitement
normal. Le client devrait traiter la rception d'un message ErrorResponse comme terminant le mode copy-out .
Il est possible que les messages NoticeResponse et ParameterStatus soient entremls avec des messages CopyData ; les interfaces
doivent grer ce cas, et devraient tre aussi prpares d'autres types de messages asynchrones (voir Section 46.2.6, Oprations
asynchrones ). Sinon, tout type de message autre que CopyData et CopyDone pourrait tre trait comme terminant le mode copyout.
Il existe un autre mode relatif Copy appel Copy-both. Il permet un tansfert de donnes en flot grande vitesse vers et partir du
serveur. Le mode Copy-both est initi quand un processus serveur en mode walsender excute une instruction
START_REPLICATION. Le processus serveur envoie un message CopyBothResponse au client. Le processus serveur et le
client peuvent ensuite envoyer des messages CopyData jusqu' la fin de la connexion. Voir Section 46.4, Protocole de rplication en continu .
Les messages CopyInResponse, CopyOutResponse et CopyBothResponse incluent des champs qui informent le client du nombre
de colonnes par ligne et les codes de format utiliss par chaque colonne. (Avec l'implmentation courante, toutes les colonnes
d'une opration COPY donne utiliseront le mme format mais la conception du message ne le suppose pas.)

46.2.6. Oprations asynchrones


Il existe plusieurs cas pour lesquels le serveur enverra des messages qui ne sont pas spcifiquement demands par le flux de commande du client. Les clients doivent tre prpars grer ces messages tout moment mme si aucune requte n'est en cours. Vrifier ces cas avant de commencer lire la rponse d'une requte est un minimum.
Il est possible que des messages NoticeResponse soient engendrs en dehors de toute activit ; par exemple, si l'administrateur de
la base de donnes commande un arrt rapide de la base de donnes, le serveur enverra un NoticeResponse l'indiquant avant de
1281

Protocole client/serveur

fermer la connexion. Les clients devraient toujours tre prts accepter et afficher les messages NoticeResponse, mme si la
connexion est inactive.
Des messages ParameterStatus seront engendrs chaque fois que la valeur active d'un paramtre est modifie, et cela pour tout
paramtre que le serveur pense utile au client. Cela survient plus gnralement en rponse une commande SQL set excute par
le client. ce cas est en fait synchrone -- mais il est possible aussi que le changement de statut d'un paramtre survienne la suite
d'une modification par l'administrateur des fichiers de configuration ; changements suivis de l'envoi du signal sighup au postmaster. de plus, si une commande set est annule, un message ParameterStatus appropri sera engendr pour rapporter la valeur
effective.
ce jour, il existe un certain nombre de paramtres cods en dur pour lesquels des messages ParameterStatus seront engendrs :
on trouve server_version, server_encoding, client_encoding, application_name, is_superuser, session_authorization et session_authorization, DateStyle, IntervalStyle, TimeZone et integer_datetimes (server_encoding, timezone et integer_datetimes n'ont pas t reports par les sorties avant la
8.0 ; standard_conforming_strings n'a pas t report par les sorties avant la 8.1 ; IntervalStyle n'a pas t report
par les sorties avant la 8.4; application_name n'a pas t report par les sorties avant la 9.0.). Notez que server_version, server_encoding et integer_datetimes sont des pseudo-paramtres qui ne peuvent pas changer aprs
le lancement. Cet ensemble pourrait changer dans le futur, voire devenir configurable. De toute faon, un client peut ignorer un
message ParameterStatus pour les paramtres qu'il ne comprend pas ou qui ne le concernent pas.
Si un client lance une commande listen, alors le serveur enverra un message NotificationResponse ( ne pas confondre avec NoticeResponse !) chaque fois qu'une commande notify est excute pour le canal de mme nom.

Note
Actuellement, NotificationResponse ne peut tre envoy qu' l'extrieur d'une transaction. Il ne surviendra donc pas
au milieu d'une rponse une commande, mais il peut survenir juste avant ReadyForQuery. Il est toutefois dconseill de concevoir un client en partant de ce principe. La bonne pratique est d'tre capable d'accepter NotificationResponse tout moment du protocole.

46.2.7. Annulation de requtes en cours


Pendant le traitement d'une requte, le client peut demander l'annulation de la requte. La demande d'annulation n'est pas envoye
directement au serveur par la connexion ouverte pour des raisons d'efficacit de l'implmentation : il n'est pas admissible que le
serveur vrifie constamment les messages manant du client lors du traitement des requtes. Les demandes d'annulation sont relativement inhabituelles ; c'est pourquoi elles sont traites de manire relativement simple afin d'viter que ce traitement ne pnalise
le fonctionnement normal.
Pour effectuer une demande d'annulation, le client ouvre une nouvelle connexion au serveur et envoie un message CancelRequest
la place du message StartupMessage envoy habituellement l'ouverture d'une connexion. Le serveur traitera cette requte et
fermera la connexion. Pour des raisons de scurit, aucune rponse directe n'est faite au message de requte d'annulation.
Un message CancelRequest sera ignor sauf s'il contient la mme donne cl (PID et cl secrte) que celle passe au client lors du
dmarrage de la connexion. Si la donne cl correspond, le traitement de la requte en cours est annul (dans l'implantation existante, ceci est obtenu en envoyant un signal spcial au processus serveur qui traite la requte).
Le signal d'annulation peut ou non tre suivi d'effet -- par exemple, s'il arrive aprs la fin du traitement de la requte par le serveur,
il n'aura alors aucun effet. Si l'annulation est effective, il en rsulte la fin prcoce de la commande accompagne d'un message
d'erreur.
De tout ceci, il ressort que, pour des raisons de scurit et d'efficacit, le client n'a aucun moyen de savoir si la demande
d'annulation a abouti. Il continuera d'attendre que le serveur rponde la requte. Effectuer une annulation permet simplement
d'augmenter la probabilit de voir la requte en cours finir rapidement et chouer accompagne d'un message d'erreur plutt que
russir.
Comme la requte d'annulation est envoye via une nouvelle connexion au serveur et non pas au travers du lien de communication
client/serveur tabli, il est possible que la requte d'annulation soit lance par un processus quelconque, pas forcment celui du
client pour lequel la requte doit tre annule. Cela peut fournir une flexibilit supplmentaire dans la construction d'applications
multi-processus ; mais galement une faille de scurit puisque des personnes non autorises pourraient tenter d'annuler des requtes. La faille de scurit est comble par l'exigence d'une cl secrte, engendre dynamiquement, pour toute requte
d'annulation.

46.2.8. Fin
Lors de la procdure normale de fin le client envoie un message Terminate et ferme immdiatement la connexion. la rception
de ce message, le serveur ferme la connexion et s'arrte.
1282

Protocole client/serveur

Dans de rares cas (tel un arrt de la base de donnes par l'administrateur), le serveur peut se dconnecter sans demande du client.
Dans de tels cas, le serveur tentera d'envoyer un message d'erreur ou d'avertissement en donnant la raison de la dconnexion avant
de fermer la connexion.
D'autres scnarios de fin peuvent tre dus diffrents cas d'checs, tels qu'un core dump ct client ou serveur, la perte du lien
de communications, la perte de synchronisation des limites du message, etc. Que le client ou le serveur s'aperoive d'une fermeture de la connexion, le buffer sera vid et le processus termin. Le client a la possibilit de lancer un nouveau processus serveur
en recontactant le serveur s'il ne souhaite pas se finir. Il peut galement envisager de clore la connexion si un type de message non
reconnu est reu ; en effet, ceci est probablement le rsultat de la perte de synchronisation des limite de messages.
Que la fin soit normale ou non, toute transaction ouverte est annule, non pas valide. Si un client se dconnecte alors qu'une requte autre que select est en cours de traitement, le serveur terminera probablement la requte avant de prendre connaissance de la
dconnexion. Si la requte est en dehors d'un bloc de transaction (squence begin ... commit), il se peut que les rsultats soient valids avant que la connexion ne soit reconnue.

46.2.9. Chiffrement ssl de session


Si postgresql a t construit avec le support de ssl, les communications client/serveur peuvent tre chiffres en l'utilisant. Ce
chiffrement assure la scurit de la communication dans les environnements o des agresseurs pourraient capturer le trafic de la
session. Pour plus d'informations sur le cryptage des sessions postgresql avec ssl, voir Section 17.9, Connexions tcp/ip scurises avec ssl .
Pour initier une connexion chiffre par ssl, le client envoie initialement un message SSLRequest la place d'un StartupMessage.
Le serveur rpond avec un seul octet contenant s ou n indiquant respectivement s'il souhaite ou non utiliser le ssl. Le client peut
alors clore la connexion s'il n'est pas satisfait de la rponse. Pour continuer aprs un s, il faut changer une poigne de main ssl
(handshake) (non dcrite ici car faisant partie de la spcification ssl) avec le serveur. en cas de succs, le StartupMessage habituel
est envoy. Dans ce cas, StartupMessage et toutes les donnes suivantes seront chiffres avec ssl. pour continuer aprs un n, il suffit d'envoyer le startupmessage habituel et de continuer sans chiffrage.
Le client doit tre prpar grer une rponse ErrorMessage un SSLRequest manant du serveur. Ceci ne peut survenir que si le
serveur ne dispose pas du support de ssl. dans ce cas, la connexion doit tre ferme, mais le client peut choisir d'ouvrir une nouvelle connexion et procder sans ssl.
Un SSLRequest initial peut galement tre utilis dans une connexion en cours d'ouverture pour envoyer un message CancelRequest.
Alors que le protocole lui-mme ne fournit pas au serveur de moyen de forcer le chiffrage ssl, l'administrateur peut configurer le
serveur pour rejeter les sessions non chiffres, ce qui est une autre faon de vrifier l'authentification.

46.3. Types de donnes des message


Cette section dcrit les types de donnes basiques utiliss dans les messages.
Intn(i)
Un entier sur n bits dans l'ordre des octets rseau (octet le plus significatif en premier). Si i est spcifi, c'est exactement la
valeur qui apparatra, sinon la valeur est variable, par exemple Int16, Int32(42).
Intn[k]
Un tableau de k entiers sur n bits, tous dans l'ordre des octets rseau. La longueur k du tableau est toujours dtermine par un
champ prcdent du message, par exemple, Int16[M].
String(s)
Une chane termine par un octet nul (chane style C). Il n'y a pas de limitation sur la longueur des chanes. Si s est spcifi,
c'est la valeur exacte qui apparatra, sinon la valeur est variable. Par exemple, String("utilisateur").

Note
il n'y a aucune limite prdfinie la longueur d'une chane retourne par le serveur. Une bonne stratgie de codage de client consiste utiliser un tampon dont la taille peut crotre pour que tout ce qui tient en mmoire
puisse tre accept. Si cela n'est pas faisable, il faudra lire la chane complte et supprimer les caractres qui ne
tiennent pas dans le tampon de taille fixe.
Byten(c)
Exactement n octets. si la largeur n du champ n'est pas une constante, elle peut toujours tre dtermine partir d'un champ
prcdent du message. Si c est spcifi, c'est la valeur exacte. Par exemple, Byte2, Byte1('\n').
1283

Protocole client/serveur

46.4. Protocole de rplication en continu


Pour initier la rplication en flux continu, le client envoi le paramtre replication dans son message d'ouverture. Il indique au
serveur de se placer en mode walsender dans lequel en petit ensemble de commandes de rplication peuvent tre utilises la
place d'ordres SQL. Dans le mode walsender, seul le protocole de requte simple est disponible. Les commandes acceptes en
mode walsender sont:
IDENTIFY_SYSTEM
Demande au serveur de s'identifier. Le serveur rpond avec un set de rsultat d'une seule ligne contenant trois champs:
systemid
L'identifiant systme unique du cluster. Il peut tre utilis pour vrifier que la base de sauvegarde utilise pour initialiser le
serveur en attente provient du mme cluster.
timeline
TimelineID courant. Tout aussi utile pour vrifier que le serveur en attente est consistant avec le matre.
xlogpos
Emmplacement d'criture courant des journaux de transactions. Utile pour connatre un emplacement dans les journaux de
transactions partir duquel le mode de rplication en flux peut commencer.
START_REPLICATION XXX/XXX
Demande au serveur de dbuter l'envoi de WAL en continu, en commenant la position XXX/XXX dans le WAL. Le serveur
peu rpondre avec une erreur, par exemple si la section de WAL demande a dj t recycle. En cas de succs, le serveur
rpond avec un message CopyBothResponse et dbute l'envoi en continu de WAL au client. Les WAL seront envoy en
continu jusqu' ce que la connexion soit interrompue ; aucune autre commande ne sera accepte.
Les donnes des WAL sont envoyes en une srie de messages CopyData (ce qui permet d'envoyer d'autre informations dans
les intervalles ; en particulier un serveur peut envoyer un message ErrorResponse s'il rencontre une erreur aprs la dbut de
l'envoi en continu des donnes). Le contenu de chaque message CopyData suit le format suivant:
XLogData (B)
Byte1('w')
Identifie le message comme une donne de WAL.
Byte8
Le point de dpart de la donne du WAL dans ce message, donn au format XLogRecPtr.
Byte8
Le fin courante du WAL sur le serveur, donn au format XLogRecPtr
Byte8
L'horloge systme du serveur l'heure de la transmission, donn au format TimestampTz.
Byten
Une section de donne du flux de WAL.
Une entre de WAL n'est jamais dcoupe dans deux messages CopyData. Cependant, lorsqu'une entre bute sur la fin d'une
page de WAL, et est par consquent divise en utilisant des enregistrements de suite, elle peut tre divise sur la fin de la
page. En d'autre terme, le premier enregistrement principal et les autres de suite peuvent tres envoys dans diffrents messages CopyData.
noter que tous les champs l'intrieur d'une donne de WAL et les enttes dcrites prcdemment seront envoys au format
natif du serveur. L'endianisme et le format de timestamp ne sont pas prvsible moins que le receveur ait vrifi que
l'identifiant systme de l'meteur corresponde au contenu de son propre pg_control.
Si le processus d'mission de WAL se termine correctement (pendant l'arrt du postmaster), il enverra un message CommandComplete avant de s'arrter. Ce message pourrait videment ne pas tre envoy en cas d'arrt brutal.
Le processus de rception peut envoyer ses rponses l'metteur tout moment, en utilisant un des formats de message suivants (ainsi que dans la charge d'un message CopyData) :
Mise jour du statut du serveur en standby (F)
Byte1('r')
Identifie le message comme une mise jour du statut du rceptionneur.
1284

Protocole client/serveur

Byte8
L'emplacement du dernier octet des journaux de transactions + 1 reu et crit sur le disque du serveur en standby, dans le format XLogRecPtr.
Byte8
L'emplacement du dernier octet des journaux de transactions + 1 pouss sur le disque du serveur en standby, dans le format
XLogRecPtr.
Byte8
L'emplacement du dernier octet des journaux de transactions + 1 appliqu sur le disque du serveur en standby, dans le format
XLogRecPtr.
Byte8
L'horloge systme du serveur au moment de la transmission, au format TimestampTz.
Message de rponse Hot Standby (F)
Byte1('h')
Identifie le message comme un message de rponse Hot Standby.
Byte8
L'horloge systme du serveur au moment de la transmission, au format TimestampTz.
Byte4
Le xmin courant du serveur en standby. Cela peut valoir 0 si le standby envoit des notifications que le retour du Hot Standby
ne va pas renvoyer sur cette connexion. Les messages suivants diffrents de 0 pourraient rinitier le mcanisme de retour
d'informations.
Byte4
Le epoch courant du serveur en standby.
BASE_BACKUP [LABEL 'label'] [PROGRESS] [FAST] [WAL] [NOWAIT]
Demande au serveur de commencer l'envoi d'une sauvegarde de base. Le systme sera mis automatiquement en mode sauvegarde avant que celle-ci ne commence et en sera sorti une fois la sauvegarde termine. Les options suivantes sont acceptes :
LABEL 'label'
Prcise le label de la sauvegarde. Si aucun label n'est indiqu, le label utilis est base backup. Les rgles de mise entre
guillemets du label sont les mmes que pour une chane SQL standard avec standard_conforming_strings activ.
PROGRESS
Demande la gnration d'un rapport de progression. Cela enverra la taille approximative dans l'en-tte de chaque tablespace,
qui peut tre utilis pour calculer ce qu'il reste rcuprer. La taille est calcule en numrant la taille de tous les fichiers
avant de commencer le transfert. Du coup, il est possible que cela ait un impact ngatif sur les performances. En particulier, la
premire donne peut mettre du temps tre envoye. De plus, comme les fichiers de la base de donnes peuvent tre modifis pendant la sauvegarde, la taille est seulement approximative et peut soit grandir, soit diminuer entre le moment de son
calcul initial et le moment o les fichiers sont envoys.
FAST
Demande un checkpoint rapide.
WAL
Inclut les journaux de transactions ncessaires dans la sauvegarde. Cela inclue tous les fichiers entre le dbut et la fin de la
sauvegarde de base dans le rpertoire pg_xlog dans l'archive tar.
NOWAIT
Par dfaut, la sauvegarde attendra que le dernier journal de transactions requis soit archiv ou mettra un message
d'avertissement si l'archivage des journaux de transactions n'est pas activ. Indiquer NOWAIT dsactive les deux (l'attente et le
message), laissant le client responsable de la disponibilit des journaux de transactions requis.
Quand la sauvegarde est lance, le serveur enverra tout d'abord deux ensembles de rsultats standards, suivis par un ou plusieurs rsultats de CopyResponse.
Le premier ensemble de rsultats standard contient la position de dmarrage de la sauvegarde, dans un format XLogRecPtr en
tant que colonne seule sur une seule ligne.
Le deuxime ensemble de rsultats standard contient une ligne pour chaque tablespace. Voici la liste des champs d'une telle
ligne :
spcoid
L'OID du tablespace, ou NULL s'il s'agit du rpertoire de donnes.
1285

Protocole client/serveur

spclocation
Le chemin complet du rpertoire du tablespace, ou NULL s'il s'agit du rpertoire de donnes.
size
La taille approximative du tablespace, si le rapport de progression a t demand. NULL sinon.
Aprs l'envoi du deuxime ensemble standard de rsultats, un ou plusieurs rsultats de type CopyResponse seront envoys, un
pour PGDATA et un pour chaque tablespace supplmentaire, autre que pg_default et pg_global. Les donnes dans les
rsultats de type CopyResponse seront un format tar (en suivant le format d'change ustar spcifi dans le standard POSIX
1003.1-2008) du contenu du tablespace, sauf que les deux blocs de zros la fin indiqus dans le standard sont omis. Aprs
que l'envoi des donnes du tar est termin, un ensemble final de rsultats sera envoy.
L'archive tar du rpertoire des donnes et de chaque tablespace contiendra tous les fichiers du rpertoire, que ce soit des fichiers PostgreSQL ou des fichiers ajouts dans le mme rpertoire. Les seuls fichiers exclus sont :

postmaster.pid
postmaster.opts
pg_xlog, ainsi que les sous-rpertoires. Si la sauvegarde est lance avec ajout des journaux de transactions, une version
synththise de pg_xlog sera inclus mais elle ne contiendra que les fichiers ncessaires au bon fonctionnement de la sauvegarde, et pas le reste de son contenu.

Le propritaire, le groupe et les droits du fichier sont conservs si le systme de fichiers du serveur le permet.
Une fois que tous les tablespaces ont t envoys, un ensemble de rsultats final est envoy. Cet ensemble contient la position
finale de la sauvegarde, dans un format XLogRecPtr sur une seule colonne et une seule ligne.

46.5. Formats de message


Cette section dcrit le format dtaill de chaque message. Chaque message est marqu pour indiquer s'il peut tre envoy par un
client (F pour frontend), un serveur (B pour backend) ou les deux (F & B). bien que chaque message commence par son nombre
d'octets, le format du message est dfini de telle sorte que la fin du message puisse tre trouve sans ce nombre. Cela contribue
la vrification de la validit. Le message CopyData est une exception car il constitue une partie du flux de donnes ; le contenu
d'un message CopyData individuel n'est, en soi, pas interprtable.
AuthenticationOk (B)
Byte1('R')
Marqueur de demande d'authentification.
Int32(8)
Taille du message en octets, y compris la taille elle-mme.
Int32(0)
L'authentification a russi.
AuthenticationKerberosV5 (B)
Byte1('R')
Marqueur de demande d'authentification.
Int32(8)
Taille du message en octets, y compris la taille elle-mme.
Int32(2)
Une authentification Kerberos V5 est requise.
AuthenticationCleartextPassword (B)
Byte1('R')
Marqueur de demande d'authentification.
Int32(8)
Taille du message en octets, y compris la taille elle-mme.
Int32(3)
Un mot de passe en clair est requis.
AuthenticationMD5Password (B)
Byte1('R')
1286

Protocole client/serveur

Marqueur de demande d'authentification.


Int32(12)
Taille du message en octets, y compris la taille elle-mme.
Int32(5)
Un mot de passe chiffr par MD5 est requis.
Byte4
Composant (salt) utiliser lors du chiffrement du mot de passe.
AuthenticationSCMCredential (B)
Byte1('R')
Marqueur de demande d'authentification.
Int32(8)
Taille du message en octets, y compris la taille elle-mme.
Int32(6)
Un message d'accrditation SCM est requis.
AuthenticationGSS (B)
Byte1('R')
Identifie le message en tant que requte d'authentification.
Int32(8)
Longueur du contenu du message en octets, lui-mme inclus.
Int32(7)
Spcifie qu'une authentification GSSAPI est requise.
AuthenticationSSPI (B)
Byte1('R')
Identifie le message en tant que requte d'authentification.
Int32(8)
Longueur du message en octet, incluant la longueur.
Int32(9)
Specifie que l'authentification SSPI est requise.
AuthenticationGSSContinue (B)
Byte1('R')
Identifie le message comme une requte d'authentification.
Int32
Longueur du message en octet, incluant la longueur.
Int32(8)
Spcifie que ce message contient des donnes GSSAPI ou SSPI.
Byten
Donnes d'authentification GSSAPI ou SSPI.
BackendKeyData (B)
Byte1('K')
Marqueur de cl d'annulation. Le client doit sauvegarder ces valeurs s'il souhaite initier des messages CancelRequest par la
suite.
Int32(12)
Taille du message en octets, y compris la taille elle-mme.
Int32
ID du processus du serveur concern.
Int32
Cl secrte du serveur concern.
Bind (F)
1287

Protocole client/serveur

Byte1('B')
Marqueur de commande Bind.
Int32
Taille du message en octets, y compris la taille elle-mme.
String
Nom du portail de destination (une chane vide slectionne le portail non-nomm).
String
Nom de l'instruction source prpare (une chane vide slectionne l'instruction prpare non-nomme).
Int16
Nombre de codes de format de paramtres qui suivent (nots c ci-dessous). peut valoir zro pour indiquer qu'il n'y a aucun
paramtre ou que tous les paramtres utilisent le format par dfaut (texte) ; ou un, auquel cas le code de format spcifi est appliqu tous les paramtres ; il peut aussi tre gal au nombre courant de paramtres.
Int16[c]
Codes de format des paramtres. Tous doivent valoir zro (texte) ou un (binaire).
Int16
Nombre de valeurs de paramtres qui suivent (peut valoir zro). Cela doit correspondre au nombre de paramtres ncessaires
la requte.
Puis, le couple de champs suivant apparat pour chaque paramtre : paramtre :
Int32
Taille de la valeur du paramtre, en octets (ce nombre n'inclut pas la longueur elle-mme). Peut valoir zro. Trait comme un
cas spcial, -1 indique une valeur de paramtre NULL. Aucun octet de valeur ne suit le cas NULL.
Byten
Valeur du paramtre, dans le format indiqu par le code de format associ. n est la longueur ci-dessus.
Aprs le dernier paramtre, les champs suivants apparaissent :
Int16
Nombre de codes de format des colonnes de rsultat qui suivent (not r ci-dessous). peut valoir zro pour indiquer qu'il n'y a
pas de colonnes de rsultat ou que les colonnes de rsultat utilisent le format par dfaut (texte) ; ou une, auquel cas le code de
format spcifi est appliqu toutes les colonnes de rsultat (s'il y en a) ; il peut aussi tre gal au nombre de colonnes de rsultat de la requte.
Int16[r]
Codes de format des colonnes de rsultat. Tous doivent valoir zro (texte) ou un (binaire).
BindComplete (B)
Byte1('2')
Indicateur de Bind complet.
Int32(4)
Taille du message en octets, y compris la taille elle-mme.
CancelRequest (F)
Int32(16)
Taille du message en octets, y compris la taille elle-mme.
Int32(80877102)
Code d'annulation de la requte. La valeur est choisie pour contenir 1234 dans les 16 bits les plus significatifs et 5678 dans
les 16 bits les moins significatifs (pour viter toute confusion, ce code ne doit pas tre le mme qu'un numro de version de
protocole).
Int32
ID du processus du serveur cible.
Int32
Cl secrte du serveur cible.
Close (F)
Byte1('C')
Marqueur de commande Close.
Int32
1288

Protocole client/serveur

Taille du message en octets, y compris la taille elle-mme.


Byte1
's' pour fermer une instruction prpare ; ou 'p' pour fermer un portail.
String
Nom de l'instruction prpare ou du portail fermer (une chane vide slectionne l'instruction prpare ou le portail nonnomm(e)).
CloseComplete (B)
Byte1('3')
Indicateur de compltude de Close.
Int32(4)
Taille du message en octets, y compris la taille elle-mme.
CommandComplete (B)
Byte1('C')
Marqueur de rponse de compltude de commande.
Int32
Taille du message en octets, y compris la taille elle-mme.
String
Balise de la commande. Mot simple identifiant la commande SQL termine.
Pour une commande insert, la balise est insert oid lignes o lignes est le nombre de lignes insres. oid est l'id
de l'objet de la ligne insre si lignes vaut 1 et que la table cible a des OID ; sinon oid vaut 0.
Pour une commande delete, la balise est delete lignes o lignes est le nombre de lignes supprimes.
Pour une commande update, la balise est update lignes o lignes est le nombre de lignes mises jour.
Pour les commandes SELECT ou CREATE TABLE AS, la balise est SELECT lignes o lignes est le nombre de
ligne rcupres.
Pour une commande move, la balise est move lignes o lignes est le nombre de lignes de dplacement du curseur.
Pour une commande fetch, la balise est fetch lignes o lignes est le nombre de lignes rcupres partir du curseur.
CopyData (F & B)
Byte1('d')
Marqueur de donnes de COPY.
Int32
Taille du message en octets, y compris la taille elle-mme.
Byten
Donnes formant une partie d'un flux de donnes copy. les messages envoys depuis le serveur correspondront toujours des
lignes uniques de donnes, mais les messages envoys par les clients peuvent diviser le flux de donnes de faon arbitraire.
CopyDone (F & B)
Byte1('c')
Indicateur de fin de COPY.
Int32(4)
Taille du message en octets, y compris la taille elle-mme.
CopyFail (F)
Byte1('f')
Indicateur d'chec de COPY.
Int32
Taille du message en octets, y compris la taille elle-mme.
String
Message d'erreur rapportant la cause d'un chec.
CopyInResponse (B)
Byte1('G')
1289

Protocole client/serveur

Marqueur de rponse de Start Copy In. Le client doit alors envoyer des donnes de copie (s'il n'est pas cela, il enverra un
message CopyFail).
Int32
Taille du message en octets, y compris la taille elle-mme.
Int8
0 indique que le format de copie complet est textuel (lignes spares par des retours chariot, colonnes spares par des caractres de sparation, etc). 1 indique que le format de copie complet est binaire (similaire au format DataRow). Voir COPY(7)
pour plus d'informations.
Int16
Nombre de colonnes dans les donnes copier (not n ci-dessous).
Int16[n]
Codes de format utiliser pour chaque colonne. Chacun doit valoir zro (texte) ou un (binaire). Tous doivent valoir zro si le
format de copie complet est de type texte.
CopyOutResponse (B)
Byte1('H')
Marqueur de rponse Start Copy Out. Ce message sera suivi de donnes copy-out.
Int32
Taille du message en octets, y compris la taille elle-mme.
Int8
0 indique que le format de copie complet est textuel (lignes spares par des retours chariots, colonnes spares par des caractres sparateur, etc). 1 indique que le format de copie complet est binaire (similaire au format DataRow). Voir COPY(7)
pour plus d'informations.
Int16
Nombre de colonnes de donnes copier (not n ci-dessous).
Int16[n]
Codes de format utiliser pour chaque colonne. Chaque code doit valoir zro (texte) ou un (binaire). Tous doivent valoir zro
si le format de copie complet est de type texte.
CopyBothResponse (B)
Byte1('W')
Identifie le message comme une rponse Start Copy Both. Ce message est seulement utilis pour la rplication en flux.
Int32
Longueur du contenu du message en octets, incluant lui-mme.
Int8
0 indique que le format COPY global est textuel (lignes spares par des retours la ligne, colonnes spars par des caractres sparateurs, etc). 1 indique que le format de copie global est binaire (similaire au format DataRow). Voir COPY(7) pour
plus d'informations.
Int16
Le nombre de colonnes dans les donnes copier (dnot N ci-dessous).
Int16[N]
Les codes de format utiliss pour chaque colonne. Chacune doit actuellement valoir 0 (texte) ou 1 (binaire). Tous doivent valoir 0 si le format de copy global est texte.
DataRow (B)
Byte1('D')
Marqueur de ligne de donnes.
Int32
Taille du message en octets, y compris la taille elle-mme.
Int16
Nombre de valeurs de colonnes qui suivent (peut valoir zro).
Apparat ensuite le couple de champs suivant, pour chaque colonne :
Int32
Longueur de la valeur de la colonne, en octets (ce nombre n'inclut pas la longueur elle-mme). Peut valoir zro. Trait comme
1290

Protocole client/serveur

un cas spcial, -1 indique une valeur NULL de colonne. Aucun octet de valeur ne suit le cas NULL.
Byten
Valeur de la colonne dans le format indiqu par le code de format associ. n est la longueur ci-dessus.
Describe (F)
Byte1('D')
Marqueur de commande Describe.
Int32
Taille du message en octets, y compris la taille elle-mme.
Byte1
's' pour dcrire une instruction prpare ; ou 'p' pour dcrire un portail.
String
Nom de l'instruction prpare ou du portail dcrire (une chane vide slectionne l'instruction prpare ou le portail nonnomm(e)).
EmptyQueryResponse (B)
Byte1('I')
Marqueur de rponse une chane de requte vide (c'est un substitut de CommandComplete).
Int32(4)
Taille du message en octets, y compris la taille elle-mme.
ErrorResponse (B)
Byte1('E')
Marqueur d'erreur.
Int32
Taille du message en octets, y compris la taille elle-mme.
Le corps du message est constitu d'un ou plusieurs champs identifi(s), suivi(s) d'un octet nul comme dlimiteur de fin.
L'ordre des champs n'est pas fix. Pour chaque champ, on trouve les informations suivantes :
Byte1
Code identifiant le type de champ ; s'il vaut zro, c'est la fin du message et aucune chane ne suit. Les types de champs dfinis
sont lists dans Section 46.6, Champs des messages d'erreur et d'avertissement . de nouveaux types de champs pourraient
tre ajouts dans le futur, les clients doivent donc ignorer silencieusement les types non reconnus.
String
Valeur du champ.
Execute (F)
Byte1('E')
Marqueur de commande Execute.
Int32
Taille du message en octets, y compris la taille elle-mme.
String
Nom du portail excuter (une chane vide slectionne le portail non-nomm).
Int32
Nombre maximum de lignes retourner si le portail contient une requte retournant des lignes (ignor sinon). Zro signifie
aucune limite .
Flush (F)
Byte1('H')
Marqueur de commande Flush.
Int32(4)
Taille du message en octets, y compris la taille elle-mme.
FunctionCall (F)
Byte1('F')
Marqueur d'appel de fonction.
1291

Protocole client/serveur

Int32
Taille du message en octets, y compris la taille elle-mme.
Int32
Spcifie l'ID de l'objet reprsentant la fonction appeler.
Int16
Nombre de codes de format de l'argument qui suivent (not c ci-dessous). cela peut tre zro pour indiquer qu'il n'y a pas
d'arguments ou que tous les arguments utilisent le format par dfaut (texte) ; un, auquel cas le code de format est appliqu
tous les arguments ; il peut aussi tre gal au nombre rel d'arguments.
Int16[c]
Les codes de format d'argument. Chacun doit valoir zro (texte) ou un (binaire).
Int16
Nombre d'arguments fournis la fonction.
Apparat ensuite, pour chaque argument, le couple de champs suivant :
Int32
Longueur de la valeur de l'argument, en octets (ce nombre n'inclut pas la longueur elle-mme). Peut valoir zro. Trait comme
un cas spcial, -1 indique une valeur NULL de l'argument. Aucun octet de valeur ne suit le cas NULL.
Byten
Valeur de l'argument dans le format indiqu par le code de format associ. n est la longueur ci-dessus.
Aprs le dernier argument, le champ suivant apparat :
Int16
Code du format du rsultat de la fonction. Doit valoir zro (texte) ou un (binaire).
FunctionCallResponse (B)
Byte1('V')
Marqueur de rsultat d'un appel de fonction.
Int32
Taille du message en octets, y compris la taille elle-mme.
Int32
Longueur de la valeur du rsultat de la fonction, en octets (ce nombre n'inclut pas la longueur elle-mme). Peut valoir zro.
Trait comme un cas spcial, -1 indique un rsultat de fonction NULL. Aucun octet de valeur ne suit le cas NULL.
Byten
Valeur du rsultat de la fonction, dans le format indiqu par le code de format associ. n est la longueur ci-dessus.
NoData (B)
Byte1('n')
Indicateur d'absence de donnes.
Int32(4)
Taille du message en octets, y compris la taille elle-mme.
NoticeResponse (B)
Byte1('N')
Marqueur d'avertissement.
Int32
Taille du message en octets, y compris la taille elle-mme.
Le corps du message est constitu d'un ou plusieurs champs identifi(s), suivi(s) d'un octet zro comme dlimiteur de fin.
L'ordre des champs n'est pas fix. Pour chaque champ, on trouve les informations suivantes :
Byte1
Code identifiant le type de champ ; s'il vaut zro, c'est la fin du message et aucune chane ne suit. Les types de champs dj
dfinis sont lists dans Section 46.6, Champs des messages d'erreur et d'avertissement . de nouveaux types de champs
pourraient tre ajouts dans le futur, les clients doivent donc ignorer silencieusement les champs de type non reconnu.
String
Valeur du champ.
NotificationResponse (B)

1292

Protocole client/serveur

Byte1('A')
Marqueur de rponse de notification.
Int32
Taille du message en octets, y compris la taille elle-mme.
Int32
ID du processus serveur ayant procd la notification.
String
Nom du canal l'origine de la notification.
String
La chane embarque passe lors de la notification
ParameterDescription (B)
Byte1('t')
Marqueur de description de paramtre.
Int32
Taille du message en octets, y compris la taille elle-mme.
Int16
Nombre de paramtres utilis par l'instruction (peut valoir zro).
Pour chaque paramtre, suivent :
Int32
ID de l'objet du type de donnes du paramtre.
ParameterStatus (B)
Byte1('S')
Marqueur de rapport d'tat de paramtre d'excution.
Int32
Taille du message en octets, y compris la taille elle-mme.
String
Nom du paramtre d'excution dont le rapport est en cours.
String
Valeur actuelle du paramtre.
Parse (F)
Byte1('P')
Marqueur de commande Parse.
Int32
Taille du message en octets, y compris la taille elle-mme.
String
Nom de l'instruction prpare de destination (une chane vide slectionne l'instruction prpare non-nomme).
String
Chane de requte analyser.
Int16
Nombre de types de donnes de paramtre spcifis (peut valoir zro). Ce n'est pas une indication du nombre de paramtres
pouvant apparatre dans la chane de requte, mais simplement le nombre de paramtres pour lesquels le client veut prspcifier les types.
Pour chaque paramtre, on trouve ensuite :
Int32
ID de l'objet du type de donnes du paramtre. la valeur zro quivaut ne pas spcifier le type.
ParseComplete (B)
Byte1('1')
Indicateur de fin de Parse.
Int32(4)
1293

Protocole client/serveur

Taille du message en octets, y compris la taille elle-mme.


PasswordMessage (F)
Byte1('p')
Identifie le message comme une rponse un mot de passe. Notez que c'est aussi utilis par les messages de rponse GSSAPI
et SSPI (qui est vraiment une erreur de conception car les donnes contenues ne sont pas une chane termine par un octet nul
dans ce cas, mais peut tre une donne binaire arbitraire).
Int32
Taille du message en octets, y compris la taille elle-mme.
String
Mot de passe (chiffr la demande).
PortalSuspended (B)
Byte1('s')
Indicateur de suspension du portail. Apparat seulement si la limite du nombre de lignes d'un message Execute a t atteint.
Int32(4)
Taille du message en octets, y compris la taille elle-mme.
Query (F)
Byte1('Q')
Marqueur de requte simple.
Int32
Taille du message en octets, y compris la taille elle-mme.
String
La chane de requte elle-mme.
ReadyForQuery (B)
Byte1('Z')
Identifie le type du message. ReadyForQuery est envoy chaque fois que le serveur est prt pour un nouveau cycle de requtes.
Int32(5)
Taille du message en octets, y compris la taille elle-mme.
Byte1
Indicateur de l'tat transactionnel du serveur. Les valeurs possibles sont 'i' s'il est en pause (en dehors d'un bloc de transaction) ; 't' s'il est dans un bloc de transaction ; ou 'e' s'il est dans un bloc de transaction choue (les requtes seront rejetes
jusqu' la fin du bloc).
RowDescription (B)
Byte1('T')
Marqueur de description de ligne.
Int32
Taille du message en octets, y compris la taille elle-mme.
Int16
Nombre de champs dans une ligne (peut valoir zro).
On trouve, ensuite, pour chaque champ :
String
Nom du champ.
Int32
Si le champ peut tre identifi comme colonne d'une table spcifique, l'ID de l'objet de la table ; sinon zro.
Int16
Si le champ peut tre identifi comme colonne d'une table spcifique, le numro d'attribut de la colonne ; sinon zro.
Int32
ID de l'objet du type de donnes du champ.
Int16
Taille du type de donnes (voir pg_type.typlen). Les valeurs ngatives indiquent des types de largeur variable.
1294

Protocole client/serveur

Int32
Modificateur de type (voir pg_attribute.atttypmod). La signification du modificateur est spcifique au type.
Int16
Code de format utilis pour le champ. Zro (texte) ou un (binaire), l'heure actuelle. Dans un RowDescription retourn par la
variante de l'instruction de Describe, le code du format n'est pas encore connu et vaudra toujours zro.
SSLRequest (F)
Int32(8)
Taille du message en octets, y compris la taille elle-mme.
Int32(80877103)
Code de requte ssl. la valeur est choisie pour contenir 1234 dans les 16 bits les plus significatifs, et 5679 dans les 16 bits
les moins significatifs (pour viter toute confusion, ce code ne doit pas tre le mme que celui d'un numro de version de protocole).
StartupMessage (F)
Int32
Taille du message en octets, y compris la taille elle-mme.
Int32(196608)
Numro de version du protocole. Les 16 bits les plus significatifs reprsentent le numro de version majeure (3 pour le protocole dcrit ici). Les 16 bits les moins significatifs reprsentent le numro de version mineure (0 pour le protocole dcrit ici).
Le numro de version du protocole est suivi par un ou plusieurs couple(s) nom de paramtre et chane de valeur. Un octet zro
est requis comme dlimiteur de fin aprs le dernier couple nom/valeur. L'ordre des paramtres n'est pas fix. Le paramtre
user est requis, les autres sont optionnels. Chaque paramtre est spcifi de la faon suivante :
String
Nom du paramtre. Les noms actuellement reconnus sont :
user
Nom de l'utilisateur de base de donnes sous lequel se connecter. Requis ; il n'y a pas de valeur par dfaut.
database
Base de donnes laquelle se connecter. Par dfaut le nom de l'utilisateur.
options
Arguments en ligne de commande pour le serveur (rendu obsolte par l'utilisation de paramtres individuels d'excution).
En plus de ce qui prcde, tout paramtre d'excution pouvant tre initialis au dmarrage du serveur peut tre list. Ces paramtres seront appliqus au dmarrage du serveur (aprs analyse des options en ligne de commande, s'il y en a). Leurs valeurs
agiront comme valeurs de session par dfaut.
String
Valeur du paramtre.
Sync (F)
Byte1('S')
Marqueur de commande Sync.
Int32(4)
Taille du message en octets, y compris la taille elle-mme.
Terminate (F)
Byte1('X')
Marqueur de fin.
Int32(4)
Taille du message en octets, y compris la taille elle-mme.

46.6. Champs des messages d'erreur et d'avertissement


Cette section dcrit les champs qui peuvent apparatre dans les messages ErrorResponse et NoticeResponse. Chaque type de
champ a un motif d'identification cod sur un octet. Tout type de champ donn doit apparatre au plus une fois par message.
s
Gravit (Severity) : le contenu du champ peut tre error, fatal ou panic dans un message d'erreur, warning,
1295

Protocole client/serveur

, debug, info ou log dans un message d'avertissement, ou la traduction rgionale de l'un d'eux. Toujours prsent.
c
Code : code SQLSTATE de l'erreur (voir Annexe A, Codes d'erreurs de PostgreSQL). non internationalisable. Toujours
prsent.
m
Message : premier message d'erreur, en clair. Doit tre court et prcis (typiquement une ligne). Toujours prsent.
d
Dtail : deuxime message d'erreur, optionnel, apportant des informations supplmentaires sur le problme. Peut tre sur plusieurs lignes.
h
Astuce (Hint) : suggestion optionnelle de rsolution du problme. Diffrent de Dtail parce qu'il offre un conseil
(potentiellement inappropri) plutt que des faits rels. Peut tre sur plusieurs lignes.
p
Position : valeur du champ, entier dcimal ASCII indiquant un curseur sur la position de l'erreur dans la chane de requte originale. Le premier caractre a l'index 1. Les positions sont mesures en caractres, non pas en octets.
p
Position interne : ceci est dfini de la mme faon que le champ p mais c'est utilis quand la position du curseur se rfre
une commande gnre en interne plutt qu'une soumise par le client. Le champ q apparatra toujours quand ce champ apparat.
q
Requte interne : le texte d'une commande gnre en interne et qui a chou. Ceci pourrait tre, par exemple, une requte
SQL lance par une fonction PL/pgSQL.
w
O (Where) : indication du contexte dans lequel l'erreur est survenue. Inclut, actuellement, une trace de la pile des appels des
fonctions PL actives. Cette trace comprend une entre par ligne, la plus rcente en premier.
f
Fichier (File) : nom du fichier de code source comportant l'erreur.
l
Ligne (Line) : numro de ligne dans le fichier de code source comportant l'erreur.
r
Routine : nom de la routine dans le code source comportant l'erreur.
Le client est responsable du formatage adapt ses besoins des informations affiches ; en particulier par l'ajout de retours chariots sur les lignes longues, si cela s'avrait ncessaire. Les caractres de retour chariot apparaissant dans les champs de messages
d'erreur devraient tre traits comme des changements de paragraphes, non comme des changements de lignes.

46.7. Rsum des modifications depuis le protocole 2.0


Cette section fournit une liste rapide des modifications l'attention des dveloppeurs essayant d'adapter au protocole 3.0 des bibliothques clientes existantes.
Le paquet de dmarrage initial utilise un format flexible de liste de chanes au lieu d'un format fixe. Les valeurs de session par dfaut des paramtres d'excution peuvent mme tre spcifies directement dans le paquet de dmarrage (en fait, cela tait dj possible en utilisant le champ options ; mais tant donn la largeur limite d'options et l'impossibilit de mettre entre guillemets
les espaces fines dans les valeurs, ce n'tait pas une technique trs sre).
Tous les messages possdent dsormais une indication de longueur qui suit immdiatement l'octet du type de message (sauf pour
les paquets de dmarrage qui n'ont pas d'octet de type). PasswordMessage possde prsent un octet de type.
Les messages ErrorResponse et NoticeResponse ('e' et 'n') contiennent maintenant plusieurs champs, partir desquels le code
client peut assembler un message d'erreur fonction du niveau de verbiage dsir. Des champs individuels ne se termineront plus
par un retour chariot alors que la chane seule envoye dans l'ancien protocole le faisait systmatiquement.
Le message ReadyForQuery ('z') inclut un indicateur d'tat de la transaction.
La distinction entre les types de messages BinaryRow et DataRow est supprime ; le type de message DataRow seul sert retourner les donnes dans tous les formats. La disposition de DataRow a chang pour faciliter son analyse. La reprsentation des valeurs binaires a galement t modifie : elle n'est plus lie directement la reprsentation interne du serveur.

1296

Protocole client/serveur

Il existe un nouveau sous-protocole pour les requtes tendues qui ajoute les types de messages client Parse, Bind, Execute,
Describe, Close, Flush et Sync et les types de messages serveur ParseComplete, BindComplete, PortalSuspended, ParameterDescription, NoData et CloseComplete. Les clients existants ne sont pas directement concerns par ce sous-protocole, mais son utilisation apportera des amliorations en terme de performances et de fonctionnalits.
Les donnes de copy sont dsormais encapsules dans des messages CopyData et CopyDone. Il y a une faon bien dfinie de rparer les erreurs lors du copy. la dernire ligne spciale \. n'est plus ncessaire et n'est pas envoye lors de copy out (elle est
toujours reconnue comme un indicateur de fin lors du copy in mais son utilisation est obsolte. Elle sera ventuellement supprime). Le copy binaire est support. les messages copyinresponse et CopyOutResponse incluent les champs indiquant le nombre de
colonnes et le format de chaque colonne.
La disposition des messages FunctionCall et FunctionCallResponse a chang. FunctionCall supporte prsent le passage aux
fonctions d'arguments NULL. Il peut aussi grer le passage de paramtres et la rcupration de rsultats aux formats texte et binaire. Il n'y a plus aucune raison de considrer FunctionCall comme une faille potentielle de scurit car il n'offre plus d'accs direct aux reprsentations internes des donnes du serveur.
Le serveur envoie des messages ParameterStatus ('s') lors de l'initialisation de la connexion pour tous les paramtres qu'il considre intressants pour la bibliothque client. En consquence, un message ParameterStatus est envoy chaque fois que la valeur
active d'un de ces paramtres change.
Le message RowDescription ('t') contient les nouveaux champs oid de table et de numro de colonne pour chaque colonne de la
ligne dcrite. Il affiche aussi le code de format pour chaque colonne.
Le message CursorResponse ('p') n'est plus engendr par le serveur.
Le message NotificationResponse ('a') a un champ de type chane supplmentaire qui peu embarquer une chane passe par
l'metteur de l'vnement notify.
Le message EmptyQueryResponse ('i') ncessitait un paramtre chane vide ; ce n'est plus le cas.

1297

Chapitre 47. Conventions de codage pour


PostgreSQL
47.1. Formatage
Le formatage du code source utilise un espacement de quatre colonnes pour les tabulations, avec prservation de celles-ci
(c'est--dire que les tabulations ne sont pas converties en espaces). Chaque niveau logique d'indentation est une tabulation supplmentaire.
Les rgles de disposition (positionnement des parenthses, etc) suivent les conventions BSD. En particulier, les accolades pour
les blocs de contrle if, while, switch, etc ont leur propre ligne.
Limiter la longueur des lignes pour que le code soit lisible avec une fentre de 80 colonnes. (Cela ne signifie pas que vous ne
devez jamais dpasser 80 colonnes. Par exemple, diviser un long message d'erreur en plusieurs morceaux arbitraires pour respecter la consigne des 80 colonnes ne sera probablement pas un grand gain en lisibilit.)
Ne pas utiliser les commentaires style C++ (//). Les compilateurs C ANSI stricts ne les acceptent pas. Pour la mme raison, ne
pas utiliser les extensions C++ comme la dclaration de nouvelles variables l'intrieur d'un bloc.
Le style prfr pour les blocs multilignes de commentaires est :
/*
* le commentaire commence ici
* et continue ici
*/
Notez que les blocs de commentaire commenant en colonne 1 seront prservs par pgindent, mais qu'il dplacera (au niveau de
la colonne) les blocs de commentaires indents comme tout autre texte. Si vous voulez prserver les retours la ligne dans un
bloc indent, ajoutez des tirets comme ceci :
/*---------* le commentaire commence ici
* et continue ici
*---------*/
Bien que les correctifs (patchs) soumis ne soient absolument pas tenus de suivre ces rgles de formatage, il est recommand de
le faire. Le code est pass dans pgindent avant la sortie de la prochaine version, donc il n'y a pas de raison de l'crire avec une
autre convention de formatage. Une bonne rgle pour les correctifs est de faire en sorte que le nouveau code ressemble au
code existant qui l'entoure .
Le rpertoire src/tools contient des fichiers d'exemples de configuration qui peuvent tre employs avec les diteurs
emacs, xemacs ou vim pour valider que le format du code crit respecte ces conventions.
Les outils de parcours de texte more et less peuvent tre appels de la manire suivante :
more -x4
less -x4
pour qu'ils affichent correctement les tabulations.

47.2. Reporter les erreurs dans le serveur


Les messages d'erreurs, d'alertes et de traces produites dans le code du serveur doivent tre crs avec ereport ou son ancien
cousin elog. L'utilisation de cette fonction est suffisamment complexe pour ncessiter quelques explications.
Il y a deux lments requis pour chaque message : un niveau de svrit (allant de DEBUG PANIC) et un message texte primaire. De plus, il y a des lments optionnels, le plus commun d'entre eux est le code identifiant de l'erreur qui suit les conventions SQLSTATE des spcifications SQL. ereport en elle-mme n'est qu'une fonction shell qui existe principalement pour
des convenances syntaxiques faisant ressembler la gnration de messages l'appel d'une fonction dans un code source C. Le
seul paramtre directement accept par ereport est le niveau de svrit. Le message texte primaire et les autres lments de
messages optionnels sont produits par appel de fonctions auxiliaires, comme errmsg, dans l'appel ereport.
Un appel typique ereport peut ressembler :
1298

Conventions de codage pour PostgreSQL

ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
Le niveau de svrit de l'erreur est ainsi positionn ERROR (une erreur banale). L'appel errcode prcise l'erreur SQLSTATE en utilisant une macro dfinie dans src/include/utils/errcodes.h. L'appel errmsg fournit le message texte
primaire. L'ensemble supplmentaire de parenthses entourant les appels aux fonctions auxiliaires est ennuyeux mais syntaxiquement ncessaire.
Exemple plus complexe :
ereport(ERROR,
(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
errmsg("function %s is not unique",
func_signature_string(funcname, nargs,
NIL, actual_arg_types)),
errhint("Unable to choose a best candidate function. "
"You might need to add explicit typecasts.")));
Cela illustre l'utilisation des codes de formatage pour intgrer des valeurs d'excution dans un message texte. Un message
conseil , optionnel, est galement fourni.
Les routines auxiliaires disponibles pour ereport sont :

errcode(sqlerrcode) prcise le code SQLSTATE de l'identifiant erreur pour la condition. Si cette routine n'est pas appele, l'identifiant l'erreur est, par dfaut, ERRCODE_INTERNAL_ERROR quand le niveau de svrit de l'erreur est ERROR
ou plus haut, ERRCODE_WARNING quand le niveau d'erreur est WARNING et ERRCODE_SUCCESSFUL_COMPLETION pour
NOTICE et infrieur. Bien que ces valeurs par dfaut soient souvent commodes, il faut se demander si elles sont appropries
avant d'omettre l'appel errcode().

errmsg(const char *msg, ...) indique le message texte primaire de l'erreur et les possibles valeurs d'excutions y
insrer. Les insertions sont prcises par les codes de formatage dans le style sprintf. En plus des codes de formatage standard accepts par sprintf, le code %m peut tre utilis pour insrer le message d'erreur retourn par strerror pour la valeur courante de errno. 1 %m ne ncessite aucune entre correspondante dans la liste de paramtres pour errmsg. Notez que
la chane de caractres du message sera passe travers gettext pour une possible adaptation linguistique avant que les
codes de formatage ne soient excuts.

errmsg_internal(const char *msg, ...) fait la mme chose que errmsg l'exception que la chane de caractres du message ne sera ni traduite ni incluse dans le dictionnaire de messages d'internationalisation. Cela devrait tre utilis
pour les cas qui ne peuvent pas arriver et pour lesquels il n'est probablement pas intressant de dployer un effort de traduction.

errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,


...) est identique errmsg mais avec le support pour plusieurs formes de pluriel du message. fmt_singular est le format singulier de l'anglais, fmt_plural est le format pluriel en anglais, n est la valeur entire qui dtermine la forme utilise.
Les arguments restants sont formats suivant le chane de format slectionne. Pour plus d'informations, voir Section 48.2.2,
Guide d'criture des messages .

errdetail(const char *msg, ...) fournit un message dtail optionnel ; cela est utilis quand il y a des informations supplmentaires qu'il semble inadquat de mettre dans le message primaire. La chane de caractres du message est
traite de la mme manire que celle de errmsg.

errdetail_internal(const char *msg, ...) est identique errdetail, sauf que le message ne sera ni traduit ni inclut dans le dictionnaire des messages traduire. Elle doit tre utilise pour les messages de niveau dtail pour lequel
un effort de traduction est inutile, par exemple parce qu'ils sont trop techniques pour que cela soit utile la majorit des utilisateurs.

errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,


...) est identique errdetail mais avec le support de plusieurs formes de pluriel pour le message. Pour plus
d'information, voir Section 48.2.2, Guide d'criture des messages .

errdetail_log(const char *msg, ...) est identique errdetail sauf que cette chane ne va que dans les
traces du serveur. Elle n'est jamais envoye au client. Si errdetail (ou un de ses quivalents ci-dessus) et errdetail_log sont utilises ensemble, alors une chane est envoys au client et l'autre dans les traces du serveur. C'est utile pour
les dtails d'erreur qui concernent la scurit ou qui sont trop techniques pour tre inclus dans le rapport envoy au client.

errhint(const char *msg, ...) fournit un message conseil optionnel ; cela est utilis pour offrir des suggestions sur la faon de rgler un problme, par opposition aux dtails effectifs au sujet de ce qui a mal tourn. La chane de ca1
ractres
du qui
message
estquand
traite
la mme
que celled'errno
de errmsg.
C'est--dire
la valeur
tait courante
l'appelde
ereport
a t manire
atteinte ; les changements
dans les routines auxiliaires de rapports ne l'affecteront pas. Cela ne sera pas vrai si vous devez
crire explicitement strerror(errno) dans la liste de paramtres de errmsg ; en consquence ne faites pas comme a.

1299

Conventions de codage pour PostgreSQL

errcontext(const char *msg, ...) n'est normalement pas appele directement depuis un site de message de
ereport mais plutt elle est utilise dans les fonctions de rappels error_context_stack pour fournir des informations
propos du contexte dans lequel une erreur s'est produite, comme les endroits courants dans la fonction PL. La chane de caractres du message est traite de la mme manire que celle de errmsg. l'inverse des autres fonctions auxiliaires, celle-ci
peut tre appele plus d'une fois dans un appel de ereport ; les chanes successives ainsi fournies sont concatnes et spares pas des caractres d'interlignes (NL).

errposition(int cursorpos) spcifie l'endroit textuel d'une erreur dans la chane de caractres de la requte. Actuellement, c'est seulement utile pour les erreurs dtectes dans les phases d'analyses lexicales et syntaxiques du traitement de la
requte.

errcode_for_file_access() est une fonction commode qui slectionne l'identifiant d'erreur SQLSTATE appropri
pour une dfaillance dans l'appel systme relatif l'accs d'un fichier. Elle utilise le errno sauvegard pour dterminer quel
code d'erreur gnrer. Habituellement cela devrait tre utilis en combinaison avec %m dans le texte du message d'erreur primaire.

errcode_for_socket_access() est une fonction commode qui slectionne l'identifiant d'erreur SQLSTATE appropri
pour une dfaillance dans l'appel systme relatif une socket.

errhidestmt(bool hide_stmt) peut tre appel pour indiquer la suppression de la portion STATEMENT: d'un message dans le journal applicatif de postmaster. Habituellement, c'est appropri si le texte du message contient dj l'instruction
en cours.

Il y a une plus ancienne fonction nomme elog, qui est toujours largement utilise. Un appel elog :
elog(niveau, "chaine format", ...);
est strictement quivalent :
ereport(level, (errmsg_internal("chaine format", ...)));
Le code d'erreur SQLSTATE est toujours celui par dfaut, la chane de caractres du message n'est pas sujette traduction. Par
consquent, elog ne devrait tre utilis que pour les erreurs internes et l'enregistrement de trace de dbogage de bas niveau.
N'importe quel message susceptible d'intresser les utilisateurs ordinaires devrait passer par ereport. Nanmoins, il y a suffisamment de contrles des erreurs internes qui ne peuvent pas arriver dans le systme, pour que elog soit toujours largement
utilise ; elle est prfre pour ces messages du fait de sa simplicit d'criture.
Des conseils sur l'criture de bons messages d'erreurs peuvent tre trouvs dans la Section 47.3, Guide de style des messages
d'erreurs .

47.3. Guide de style des messages d'erreurs


Ce guide de style est fournit dans l'espoir de maintenir une cohrence et un style facile comprendre dans tous les messages gnrs par PostgreSQL.

Ce qui va o
Le message primaire devrait tre court, factuel et viter les rfrences aux dtails d'excution comme le nom de fonction spcifique. Court veut dire devrait tenir sur une ligne dans des conditions normales . Utilisez un message dtail si ncessaire
pour garder le message primaire court ou si vous sentez le besoin de mentionner les dtails de l'implmentation comme un appel
systme particulier qui choue. Les messages primaires et dtails doivent tre factuels. Utilisez un message conseil pour les suggestions propos de quoi faire pour fixer le problme, spcialement si la suggestion ne pourrait pas toujours tre applicable.
Par exemple, au lieu de :
IpcMemoryCreate: shmget(cl=%d, taille=%u, 0%o) a chou : %m
(plus un long supplment qui est basiquement un conseil)
crivez :
Primaire:
Dtail:
Astuce:

Ne peut pas crer un sgment en mmoire partage : %m


L'appel systme qui a chou tait shmget(key=%d, size=%u, 0%o).
Le supplment

Raisonnement : garder le message primaire court aide le garder au point et laisse les clients prsenter un espace l'cran sur la
supposition qu'une ligne est suffisante pour les messages d'erreurs. Les messages dtails et conseils peuvent tre relgus un
mode verbeux ou peut-tre dans une fentre pop-up dtaillant l'erreur. De plus, les dtails et les conseils devront normalement tre
supprims des traces du serveur pour gagner de l'espace. La rfrence aux dtails d'implmentation est viter puisque les utilisateurs n'en connaissent de toute faon pas les dtails.
1300

Conventions de codage pour PostgreSQL

Formatage
N'mettez pas d'hypothses spcifiques propos du formatage dans les messages textes. Attendez-vous ce que les clients et les
traces du serveur enveloppent les lignes pour correspondre leurs propres besoins. Dans les messages longs, les caractres
d'interlignes (\n) peuvent tre utiliss pour indiquer les coupures suggres d'un paragraphe. Ne terminez pas un message avec un
caractre d'interlignes. N'utilisez pas des tabulations ou d'autres caractres de formatage (dans les affichages des contextes
d'erreurs, les caractres d'interlignes sont automatiquement ajouts pour sparer les niveaux d'un contexte comme dans les appels
aux fonctions).
Raisonnement : les messages ne sont pas ncessairement affichs dans un affichage de type terminal. Dans les interfaces graphiques ou les navigateurs, ces instructions de formatage sont, au mieux, ignores.

Guillemets
Les textes en anglais devraient utiliser des guillemets doubles quand la mise entre guillemets est approprie. Les textes dans les
autres langues devraient uniformment employer un genre de guillemets qui est conforme aux coutumes de publication et la sortie visuelle des autres programmes.
Raisonnement : le choix des guillemets doubles sur celui des guillemets simples est quelque peu arbitraire mais tend tre
l'utilisation prfre. Certains ont suggr de choisir le type de guillemets en fonction du type d'objets des conventions SQL
(notamment, les chanes de caractres entre guillemets simples, les identifiants entre guillemets doubles). Mais ceci est un point
technique l'intrieur du langage avec lequel beaucoup d'utilisateurs ne sont pas familiers ; les conventions SQL ne prennent pas
en compte les autres genres de termes entre guillemets, ne sont pas traduites dans d'autres langues et manquent un peu de sens aussi.

Utilisation des guillemets


Utilisez toujours les guillemets pour dlimiter les noms de fichiers, les identifiants fournis par les utilisateurs et les autres variables
qui peuvent contenir des mots. Ne les utilisez pas pour marquer des variables qui ne contiennent pas de mots (par exemple, les
noms d'oprateurs).
Il y a des fonctions au niveau du serveur qui vont, au besoin, mettre entre guillemets leur propre flux de sortie (par exemple, format_type_be()). Ne mettez pas de guillemets supplmentaires autour du flux de sortie de ce genre de fonctions.
Raisonnement : les objets peuvent avoir un nom qui cre une ambigut une fois incorpor dans un message. Soyez prudent en indiquant o un nom commence et fini. Mais n'encombrez pas les messages avec des guillemets qui ne sont pas ncessaires ou qui
sont dupliqus.

Grammaire et ponctuation
Les rgles sont diffrentes pour les messages d'erreurs primaires et pour les messages dtails/conseils :
Messages d'erreurs primaires : ne mettez pas en majuscule la premire lettre. Ne terminez pas un message avec un point. Ne pensez mme pas finir un message avec un point d'exclamation.
Messages dtails et conseils : utilisez des phrases compltes et toutes termines par des points. Mettez en majuscule le premier
mot des phrases. Placez deux espaces aprs le point si une autre phrase suit (pour un texte en anglais... cela pourrait tre diffrent
dans une autre langue).
Chanes de contexte d'erreur: Ne mettez pas en majuscule la premire lettre et ne terminer pas la chane avec un point. Les chanes
de contexte ne sont normalement pas des phrases compltes.
Raisonnement : viter la ponctuation rend plus facile, pour les applications clientes, l'intgration du message dans des contextes
grammaticaux varis. Souvent, les messages primaires ne sont de toute faon pas des phrases compltes (et s'ils sont assez longs
pour tre sur plusieurs phrases, ils devraient tre diviss en une partie primaire et une partie dtail). Cependant, les messages dtails et conseils sont longs et peuvent avoir besoin d'inclure de nombreuses phrases. Pour la cohrence, ils devraient suivre le style
des phrases compltes mme s'il y a seulement une phrase.

Majuscule contre minuscule


Utilisez les minuscules pour les mots d'un message, inclus la premire lettre d'un message d'erreur primaire. Utilisez les majuscules pour les commandes et les mots-cl SQL s'ils apparaissent dans le message.
Raisonnement : il est plus facile de rendre toutes les choses plus cohrentes au regard de cette faon, puisque certains messages
sont des phrases compltes et d'autres non.

viter la voix passive


1301

Conventions de codage pour PostgreSQL

Utilisez la voix active. Utilisez des phrases compltes quand il y a un sujet ( A ne peut pas faire B ). Utilisez le style tlgramme, sans sujet, si le sujet est le programme lui-mme ; n'utilisez pas Je pour le programme.
Raisonnement : le programme n'est pas humain. Ne prtendez pas autre chose.

Prsent contre pass


Utilisez le pass si une tentative de faire quelque chose chouait, mais pourrait peut-tre russir la prochaine fois (peut-tre aprs
avoir corriger certains problmes). Utilisez le prsent si l'chec est sans doute permanent.
Il y a une diffrence smantique non triviale entre les phrases de la forme :
n'a pas pu ouvrir le fichier "%s": %m
et :
ne peut pas ouvrir le dossier "%s"
La premire forme signifie que la tentative d'ouverture du fichier a chou. Le message devrait donner une raison comme disque
plein ou le fichier n'existe pas . Le pass est appropri parce que la prochaine fois le disque peut ne plus tre plein ou le fichier en question peut exister.
La seconde forme indique que la fonctionnalit d'ouvrir le fichier nomm n'existe pas du tout dans le programme ou que c'est
conceptuellement impossible. Le prsent est appropri car la condition persistera indfiniment.
Raisonnement : d'accord, l'utilisateur moyen ne sera pas capable de tirer de grandes conclusions simplement partir du temps du
message mais, puisque la langue nous fournit une grammaire, nous devons l'utiliser correctement.

Type de l'objet
En citant le nom d'un objet, spcifiez quel genre d'objet c'est.
Raisonnement : sinon personne ne saura ce qu'est foo.bar.baz .

Crochets
Les crochets sont uniquement utiliss (1) dans les synopsis des commandes pour indiquer des arguments optionnels ou (2) pour indiquer l'indice infrieur d'un tableau.
Raisonnement : rien de ce qui ne correspond pas l'utilisation habituelle, largement connue troublera les gens.

Assembler les messages d'erreurs


Quand un message inclut du texte produit ailleurs, il est intgr dans ce style :
n'a pas pu ouvrir le fichier %s: %m
Raisonnement : il serait difficile d'expliquer tous les codes d'erreurs possibles pour coller ceci dans une unique phrase douce, ainsi
une certaine forme de ponctuation est ncessaire. Mettre le texte inclus entre parenthses a t galement suggr, mais ce n'est
pas naturel si le texte inclus est susceptible d'tre la partie la plus importante du message, comme c'est souvent le cas.

Raisons pour les erreurs


Les messages devraient toujours indiquer la raison pour laquelle une erreur s'est produite. Par exemple :
MAUVAIS : n'a pas pu ouvrir le fichier %s
MEILLEUR : n'a pas pu ouvrir le fichier %s (chec E/S)
Si aucune raison n'est connue, vous feriez mieux de corriger le code.

Nom des fonctions


N'incluez pas le nom de la routine de rapport dans le texte de l'erreur. Nous avons d'autres mcanismes pour trouver cela quand
c'est ncessaire et, pour la plupart des utilisateurs, ce n'est pas une information utile. Si le texte de l'erreur n'a plus beaucoup de
sens sans le nom de la fonction, reformulez-le.
MAUVAIS : pg_atoi: erreur dans "z": ne peut pas analyser "z"
MEILLEUR : syntaxe en entre invalide pour l'entier : "z"
vitez de mentionner le nom des fonctions appeles, au lieu de cela dites ce que le code essayait de faire :
1302

Conventions de codage pour PostgreSQL

MAUVAIS : ouvrir() a chou : %m


MEILLEUR : n'a pas pu ouvrir le fichier %s: %m
Si cela semble vraiment ncessaire, mentionnez l'appel systme dans le message dtail (dans certains cas, fournir les valeurs
relles passes l'appel systme pourrait tre une information approprie pour le message dtail).
Raisonnement : les utilisateurs ne savent pas tout ce que ces fonctions font.

Mots dlicats viter


Incapable. Incapable est presque la voix passive. Une meilleure utilisation est ne pouvait pas ou ne pourrait pas selon
les cas.
Mauvais. Les messages d'erreurs comme mauvais rsultat sont vraiment difficile interprter intelligemment. Cela est mieux
d'crire pourquoi le rsultat est mauvais , par exemple, format invalide .
Illgal. Illgal reprsente une violation de la loi, le reste est invalide . Meilleur encore, dites pourquoi cela est invalide.
Inconnu. Essayez d'viter inconnu . Considrez erreur : rponse inconnue . Si vous ne savez pas qu'elle est la rponse,
comment savez-vous que cela est incorrect ? Non reconnu est souvent un meilleur choix. En outre, assurez-vous d'inclure la
valeur pour laquelle il y a un problme.
MAUVAIS : type de nud inconnu
MEILLEUR : type de nud non reconnu : 42
Trouver contre Exister. Si le programme emploie un algorithme non trivial pour localiser une ressource (par exemple, une recherche de chemin) et que l'algorithme choue, il est juste de dire que le programme n'a pas p trouver la ressource. D'un autre
ct, si l'endroit prvu pour la ressource est connu mais que le programme ne peut pas accder celle-ci, alors dites que la ressource n' existe pas. Utilisez trouvez dans ce cas l semble faible et embrouille le problme.
May vs. Can vs. Might. May suggre un droit (par exemple You may borrow my rake.) et a peu d'utilit dans la documentation et dans les messages d'erreur. Can suggre une capacit (par exemple I can lift that log.), et might suggre une possibilit (par exemple It might rain today.). Utiliser le bon mot clarifie la signification et aide les traducteurs.
Contractions. viter les contractions comme can't ; utilisez cannot la place.

Orthographe approprie
Orthographiez les mots en entier. Par exemple, vitez :

spec (NdT : spcification)

stats (NdT : statistiques)

params (NdT : paramtres)

auth (NdT : authentification)

xact (NdT : transaction)

Raisonnement : cela amliore la cohrence.

Adaptation linguistique
Gardez l'esprit que les textes des messages d'erreurs ont besoin d'tre traduit en d'autres langues. Suivez les directives dans la
Section 48.2.2, Guide d'criture des messages pour viter de rendre la vie difficile aux traducteurs.

1303

Chapitre 48. Support natif des langues


Peter Eisentraut

48.1. Pour le traducteur


Les programmes PostgreSQL (serveur et client) peuvent afficher leur message dans la langue prfre de l'utilisateur -- si les
messages ont t traduits. Crer et maintenir les ensembles de messages traduits ncessite l'aide de personnes parlant leur propre
langue et souhaitant contribuer PostgreSQL. Il n'est nul besoin d'tre un dveloppeur pour cela. Cette section explique comment apporter son aide.

48.1.1. Prrequis
Les comptences dans sa langue d'un traducteur ne seront pas juges -- cette section concerne uniquement les outils logiciels.
Thoriquement, seul un diteur de texte est ncessaire. Mais ceci n'est vrai que dans le cas trs improbable o un traducteur ne
souhaiterait pas tester ses traductions des messages. Lors de la configuration des sources, il faudra s'assurer d'utiliser l'option -enable-nls. Ceci assurera galement la prsence de la bibliothque libintl et du programme msgfmt dont tous les utilisateurs finaux ont indniablement besoin. Pour tester son travail, il sera utile de suivre les parties pertinentes des instructions
d'installation.
Pour commencer un nouvel effort de traduction ou pour faire un assemblage de catalogues de messages (dcrit ci-aprs), il faudra installer respectivement les programmes xgettext et msgmerge dans une implmentation compatible GNU. Il est prvu
dans le futur que xgettext ne soit plus ncessaire lorsqu'une distribution empaquete des sources est utilise (en travaillant
partir du Git, il sera toujours utile). GNU Gettext 0.10.36 ou ultrieure est actuellement recommand.
Toute implmentation locale de gettext devrait tre disponible avec sa propre documentation. Une partie en est certainement duplique dans ce qui suit mais des dtails complmentaires y sont certainement disponibles.

48.1.2. Concepts
Les couples de messages originaux (anglais) et de leurs (possibles) traductions sont conservs dans les catalogues de messages,
un pour chaque programme (bien que des programmes lis puissent partager un catalogue de messages) et pour chaque langue
cible. Il existe deux formats de fichiers pour les catalogues de messages : le premier est le fichier PO (pour "Portable Object"
ou Objet Portable), qui est un fichier texte muni d'une syntaxe spciale et que les traducteurs ditent. Le second est un fichier
MO (pour "Machine Object" ou Objet Machine), qui est un fichier binaire engendr partir du fichier PO respectif et qui est
utilis lorsque le programme internationalis est excut. Les traducteurs ne s'occupent pas des fichiers MO ; en fait, quasiment
personne ne s'en occupe.
L'extension du fichier de catalogue de messages est, sans surprise, soit .po, soit .mo. Le nom de base est soit le nom du programme qu'il accompagne soit la langue utilise dans le fichier, suivant la situation. Ceci peut s'avrer tre une source de confusion. Des exemples sont psql.po (fichier PO pour psql) ou fr.mo (fichier MO en franais).
Le format du fichier PO est illustr ici :
# commentaire
msgid "chane originale"
msgstr "chane traduite"
msgid "encore une originale"
msgstr "encore une de traduite"
"les chanes peuvent tre sur plusieurs lignes, comme ceci"
...
Les chanes msgid sont extraites des sources du programme. (Elles n'ont pas besoin de l'tre mais c'est le moyen le plus commun). Les lignes msgstr sont initialement vides puis compltes avec les chanes traduites. Les chanes peuvent contenir des caractres d'chappement de style C et peuvent tre sur plusieurs lignes comme le montre l'exemple ci-dessus (la ligne suivante
doit dmarrer au dbut de la ligne).
Le caractre # introduit un commentaire. Si une espace fine suit immdiatement le caractre #, c'est qu'il s'agit l d'un commentaire maintenu par le traducteur. On trouve aussi des commentaires automatiques qui n'ont pas d'espace fine suivant immdiatement le caractre #. Ils sont maintenus par les diffrents outils qui oprent sur les fichiers PO et ont pour but d'aider le traducteur.
1304

Support natif des langues

#. commentaire automatique
#: fichier.c:1023
#, drapeau, drapeau
Les commentaires du style #. sont extraits du fichier source o le message est utilis. Il est possible que le dveloppeur ait ajout
des informations pour le traducteur, telles que l'alignement attendu. Le commentaire #: indique l'emplacement exact o le message
est utilis dans le source. Le traducteur n'a pas besoin de regarder le source du programme, mais il peut le faire s'il subsiste un
doute sur l'exactitude d'une traduction. Le commentaire #, contient des drapeaux dcrivant le message d'une certaine faon. Il
existe actuellement deux drapeaux : fuzzy est positionn si le message risque d'tre rendu obsolte par des changements dans les
sources. Le traducteur peut alors vrifier ceci et supprimer ce drapeau. Notez que les messages fuzzy ne sont pas accessibles
l'utilisateur final. L'autre drapeau est c-format indiquant que le message utilise le format de la fonction C printf. Ceci signifie que la traduction devrait aussi tre de ce format avec le mme nombre et le mme type de paramtres fictifs. Il existe des outils
qui vrifient que le message est une chane au format printf et valident le drapeau c-format en consquence.

48.1.3. Crer et maintenir des catalogues de messages


OK, alors comment faire pour crer un catalogue de messages vide ? Tout d'abord, se placer dans le rpertoire contenant le
programme dont on souhaite traduire les messages. S'il existe un fichier nls.mk, alors ce programme est prpar pour la traduction.
S'il y a dj des fichiers .po, alors quelqu'un a dj ralis des travaux de traduction. Les fichiers sont nomms langue.po, o
langue est le code de langue sur deux caractres (en minuscules) tel que dfini par l' ISO 639-1, le code du pays compos de
deux lettres en minuscule, c'est--dire fr.po pour le franais. S'il existe rellement un besoin pour plus d'une traduction par
langue, alors les fichiers peuvent tre renomms langue_region.po o region est le code de langue sur deux caractres (en
majuscules), tel que dfini par l'ISO 3166-1, le code du payes sur deux lettres en majuscule, c'est--dire pt_BR.po pour le portugais du Brsil. Si vous trouvez la langue que vous souhaitez, vous pouvez commencer travailler sur ce fichier.
Pour commencer une nouvelle traduction, il faudra pralablement excuter la commande :
gmake init-po
Ceci crera un fichier nomprog.pot. (.pot pour le distinguer des fichiers PO qui sont en production . Le T signifie
template (NdT : modle en anglais). On copiera ce fichier sous le nom langue.po. On peut alors l'diter. Pour faire savoir
qu'une nouvelle langue est disponible, il faut galement diter le fichier nls.mk et y ajouter le code de la langue (ou de la langue
et du pays) avec une ligne ressemblant ceci :
AVAIL_LANGUAGES := de fr
(d'autres langues peuvent apparatre, bien entendu).
mesure que le programme ou la bibliothque change, des messages peuvent tre modifis ou ajouts par les dveloppeurs. Dans
ce cas, il n'est pas ncessaire de tout recommencer depuis le dbut. la place, on lancera la commande :
gmake update-po
qui crera un nouveau catalogue de messages vides (le fichier pot avec lequel la traduction a t initie) et le fusionnera avec les
fichiers PO existants. Si l'algorithme de fusion a une incertitude sur un message particulier, il le marquera fuzzy comme expliqu ci-dessus. Le nouveau fichier PO est sauvegard avec l'extension .po.new.

48.1.4. diter les fichiers PO


Les fichiers PO sont ditables avec un diteur de texte standard. Le traducteur doit seulement modifier l'emplacement entre les
guillemets aprs la directive msgstr, peut ajouter des commentaires et modifier le drapeau fuzzy (NdA : Il existe, ce qui n'est pas
surprenant, un mode PO pour Emacs, que je trouve assez utile).
Les fichiers PO n'ont pas besoin d'tre entirement remplis. Le logiciel retournera automatiquement la chane originale si une
traduction n'est pas disponible ou est laisse vide. Soumettre des traductions incompltes pour les inclure dans l'arborescence des
sources n'est pas un problme ; cela permet d'autres personnes de rcuprer le travail commenc pour le continuer. Nanmoins,
les traducteurs sont encourags donner une haute priorit la suppression des entres fuzzy aprs avoir fait une fusion. Les entres fuzzy ne seront pas installes ; elles servent seulement de rfrence ce qui pourrait tre une bonne traduction.
Certaines choses sont garder l'esprit lors de l'dition des traductions :

S'assurer que si la chane originale se termine par un retour chariot, la traduction le fasse bien aussi. De mme pour les tabulations, etc.

Si la chane originale est une chane au format printf, la traduction doit l'tre aussi. La traduction doit galement avoir les
mme spcificateurs de format et dans le mme ordre. Quelques fois, les rgles naturelles de la langue rendent cela impossible
ou tout au moins difficile. Dans ce cas, il est possible de modifier les spcificateurs de format de la faon suivante :
1305

Support natif des langues

msgstr "Die Datei %2$s hat %1$u Zeichen."


Le premier paramtre fictif sera alors utilis par le deuxime argument de la liste. Le chiffre$ a besoin de suivre immdiatement le %, avant tout autre manipulateur de format (cette fonctionnalit existe rellement dans la famille des fonctions
printf, mais elle est peu connue, n'ayant que peu d'utilit en dehors de l'internationalisation des messages).

Si la chane originale contient une erreur linguistique, on pourra la rapporter (ou la corriger soi-mme dans le source du programme) et la traduire normalement. La chane corrige peut tre fusionne lorsque les programmes sources auront t mis
jour. Si la chane originale contient une erreur factuelle, on la rapportera (ou la corrigera soi-mme) mais on ne la traduira pas.
la place, on marquera la chane avec un commentaire dans le fichier PO.

Maintenir le style et le ton de la chane originale. En particulier, les messages qui ne sont pas des phrases (cannot open
file %s, soit ne peut pas ouvrir le fichier %s) ne devraient probablement pas commencer avec une lettre
capitale (si votre langue distingue la casse des lettres) ou finir avec un point (si votre langue utilise des marques de ponctuation). Lire Section 47.3, Guide de style des messages d'erreurs peut aider.

Lorsque la signification d'un message n'est pas connue ou s'il est ambig, on pourra demander sa signification sur la liste de
diffusion des dveloppeurs. Il est possible qu'un anglophone puisse aussi ne pas le comprendre ou le trouver ambig. Il est
alors prfrable d'amliorer le message.

48.2. Pour le dveloppeur


48.2.1. Mcaniques
Cette section explique comment implmenter le support natif d'une langue dans un programme ou dans une bibliothque qui fait
partie de la distribution PostgreSQL. Actuellement, cela s'applique uniquement aux programmes C.
Procdure 48.1. Ajouter le support NLS un programme

1.

Le code suivant est insr dans la squence initiale du programme :


#ifdef ENABLE_NLS
#include <locale.h>
#endif
...
#ifdef ENABLE_NLS
setlocale(LC_ALL, "");
bindtextdomain("nomprog", LOCALEDIR);
textdomain("nomprog");
#endif
(nomprog peut tre choisi tout fait librement).

2.

Partout o un message candidat la traduction est trouv, un appel gettext() doit tre insr. Par exemple :
fprintf(stderr, "panic level %d\n", lvl);
devra tre chang avec :
fprintf(stderr, gettext("panic level %d\n"), lvl);
(gettext est dfini comme une opration nulle si NLS n'est pas configur).
Cela peut engendrer du fouillis. Un raccourci habituel consiste utiliser :
#define _(x) gettext(x)
Une autre solution est envisageable si le programme effectue la plupart de ses communications via une fonction ou un
nombre restreint de fonctions, telle ereport() pour le moteur. Le fonctionnement interne de cette fonction peut alors tre
modifie pour qu'elle appelle gettext pour toutes les chanes en entre.

3.

Un fichier nls.mk est ajout dans le rpertoire des sources du programme. Ce fichier sera lu comme un makefile. Les affectations des variables suivantes doivent tre ralises ici :
CATALOG_NAME
Le nom du programme tel que fourni lors de l'appel textdomain().
1306

Support natif des langues

AVAIL_LANGUAGES
Liste des traductions fournies -- initialement vide.
GETTEXT_FILES
Liste des fichiers contenant les chanes traduisibles, c'est--dire celles marques avec gettext ou avec une solution alternative. Il se peut que cette liste inclut pratiquement tous les fichiers sources du programme. Si cette liste est trop longue, le premier fichier peut tre remplac par un + et le deuxime mot reprsenter un fichier contenant un nom de fichier par ligne.
GETTEXT_TRIGGERS
Les outils qui engendrent des catalogues de messages pour les traducteurs ont besoin de connatre les appels de fonction
contenant des chanes traduire. Par dfaut, seuls les appels gettext() sont reconnus. Si _ ou d'autres identifiants sont
utiliss, il est ncessaire de les lister ici. Si la chane traduisible n'est pas le premier argument, l'lment a besoin d'tre de la
forme func:2 (pour le second argument). Si vous avez une fonction qui supporte les messages au format pluriel, l'lment
ressemblera func:1,2 (identifiant les arguments singulier et pluriel du message).

Le systme de construction s'occupera automatiquement de construire et installer les catalogues de messages.

48.2.2. Guide d'criture des messages


Voici quelques lignes de conduite pour l'criture de messages facilement traduisibles.

Ne pas construire de phrases l'excution, telles que :


printf("Files were %s.\n", flag ? "copied" : "removed");
L'ordre des mots d'une phrase peut tre diffrent dans d'autres langues. De plus, mme si gettext() est correctement appel
sur chaque fragment, il pourrait tre difficile de traduire sparment les fragments. Il est prfrable de dupliquer un peu de
code de faon ce que chaque message traduire forme un tout cohrent. Seuls les nombres, noms de fichiers et autres variables d'excution devraient tre insrs au moment de l'excution dans le texte d'un message.

Pour des raisons similaires, ceci ne fonctionnera pas :


printf("copied %d file%s", n, n!=1 ? "s" : "");
parce que cette forme prsume de la faon dont la forme plurielle est obtenue. L'ide de rsoudre ce cas de la faon suivante :
if (n==1)
printf("copied 1 file");
else
printf("copied %d files", n):
sera source de dception. Certaines langues ont plus de deux formes avec des rgles particulires. Il est souvent prfrable de
concevoir le message de faon viter le problme, par exemple ainsi :
printf("number of copied files: %d", n);
Si vous voulez vraiment construire un message correctement pluralis, il existe un support pour cela, mais il est un peu
trange. Quand vous gnrez un message d'erreur primaire ou dtaill dans ereport(), vous pouvez crire quelque-chose
comme ceci :
errmsg_plural("copied %d file",
"copied %d files",
n,
n)
Le premier argument est le chane dans le format appropri pour la forme au singulier en anglais, le second est le format de
chane appropri pour la forme plurielle en anglais, et le troisime est la valeur entire dterminant la forme utiliser. Des arguments additionnels sont formats suivant la chane de formatage comme d'habitude. (Habituellement, la valeur de contrle
de la pluralisation sera aussi une des valeurs formater, donc elle sera crite deux fois.) En anglais, cela n'importe que si n est
gale 1 ou est diffrent de 1, mais dans d'autres langues, il pourrait y avoir plusieurs formes de pluriel. Le traducteur voit les
deux formes anglaises comme un groupe et a l'opportunit de fournir des chanes de substitution supplmentaires, la bonne
tant slectionne suivant la valeur l'excution de n.
Si vous avez besoin de pluraliser un message qui ne va pas directement errmsg ou errdetail, vous devez utiliser la
fonction sous-jacente ngettext. Voir la documentation gettext.

Lorsque quelque chose doit tre communiqu au traducteur, telle que la faon dont un message doit tre align avec quelque
1307

Support natif des langues

autre sortie, on pourra faire prcder l'occurrence de la chane d'un commentaire commenant par translator, par
exemple :
/* translator: This message is not what it seems to be. */
Ces commentaires sont copis dans les catalogues de messages de faon ce que les traducteurs les voient.

1308

Chapitre 49. crire un gestionnaire de langage


procdural
Tous les appels de fonctions crites dans un langage autre que celui de l'interface version 1 pour les langages compils (ce
qui inclut les fonctions dans les langages procduraux utilisateur, les fonctions SQL et les fonctions utilisant l'interface de langage compil version 0), passent par une fonction spcifique au langage du gestionnaire d'appels. Le gestionnaire d'appels excute la fonction de manire approprie, par exemple en interprtant le code source fourni. Ce chapitre dcrit l'criture du gestionnaire d'appels d'un nouveau langage procdural.
Le gestionnaire d'appel d'un langage procdural est une fonction normale qui doit tre crite dans un langage compil tel que
le C, en utilisant l'interface version-1, et enregistre sous PostgreSQL comme une fonction sans argument et retournant le type
language_handler. Ce pseudo-type spcial identifie la fonction comme gestionnaire d'appel et empche son appel partir des
commandes SQL. Pour plus de dtails sur les conventions d'appels et le chargement dynamique en langage C, voir Section 35.9,
Fonctions en langage C .
L'appel du gestionnaire d'appels est identique celui de toute autre fonction : il reoit un pointeur de structure FunctionCallInfoData qui contient les valeurs des arguments et d'autres informations de la fonction appele. Il retourne un rsultat Datum (et, initialise le champ isnull de la structure FunctionCallInfoData si un rsultat SQL NULL doit tre retourn). La diffrence entre
un gestionnaire d'appels et une fonction ordinaire se situe au niveau du champ flinfo->fn_oid de la structure FunctionCallInfoData. Dans le cas du gestionnaire d'appels, il contiendra l'OID de la fonction appeler, et non pas celui du gestionnaire
d'appels lui-mme. Le gestionnaire d'appels utilise ce champ pour dterminer la fonction excuter. De plus, la liste
d'arguments passe a t dresse partir de la dclaration de la fonction cible, et non pas en fonction du gestionnaire d'appels.
C'est le gestionnaire d'appels qui rcupre l'entre de la fonction dans la table systme pg_proc et analyse les types des arguments et de la valeur de retour de la fonction appele. La clause AS de la commande CREATE FUNCTION se situe dans la colonne prosrc de pg_proc. Il s'agit gnralement du texte source du langage procdural lui-mme (comme pour PL/Tcl)
mais, en thorie, cela peut tre un chemin vers un fichier ou tout ce qui indique au gestionnaire d'appels les dtails des actions
effectuer.
Souvent, la mme fonction est appele plusieurs fois dans la mme instruction SQL. L'utilisation du champ flinfo>fn_extra vite au gestionnaire d'appels de rpter la recherche des informations concernant la fonction appele. Ce champ,
initialement NULL, peut tre configur par le gestionnaire d'appels pour pointer sur l'information concernant la fonction appele. Lors des appels suivants, si flinfo->fn_extra est diffrent de NULL, alors il peut tre utilis et l'tape de recherche
d'information vite. Le gestionnaire d'appels doit s'assurer que flinfo->fn_extra pointe sur une zone mmoire qui restera
alloue au moins jusqu' la fin de la requte en cours, car une structure de donnes FmgrInfo peut tre conserve aussi longtemps. Cela peut-tre obtenu par l'allocation des donnes supplmentaires dans le contexte mmoire spcifi par flinfo>fn_mcxt ; de telles donnes ont la mme esprance de vie que FmgrInfo. Le gestionnaire peut galement choisir d'utiliser un
contexte mmoire de plus longue esprance de vie de faon mettre en cache sur plusieurs requtes les informations concernant
les dfinitions des fonctions.
Lorsqu'une fonction en langage procdural est appele via un dclencheur, aucun argument ne lui est pass de faon traditionnelle mais le champ context de FunctionCallInfoData pointe sur une structure TriggerData. Il n'est pas NULL comme c'est le
cas dans les appels de fonctions standard. Un gestionnaire de langage doit fournir les mcanismes pour que les fonctions de langages procduraux obtiennent les informations du dclencheur.
Voici un modle de gestionnaire de langage procdural crit en C :
#include
#include
#include
#include
#include
#include
#include
#include

"postgres.h"
"executor/spi.h"
"commands/trigger.h"
"fmgr.h"
"access/heapam.h"
"utils/syscache.h"
"catalog/pg_proc.h"
"catalog/pg_type.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(plsample_call_handler);
Datum
plsample_call_handler(PG_FUNCTION_ARGS)
{
1309

crire un gestionnaire de langage procdural

Datum

retval;

if (CALLED_AS_TRIGGER(fcinfo))
{
/*
* Appel comme procdure de dclencheur
*/
TriggerData
*trigdata = (TriggerData *) fcinfo->context;
retval = ...
}
else
{
/*
* Appel en tant que fonction
*/
retval = ...
}
return retval;
}
Il suffit de remplacer les points de suspension par quelques milliers de lignes de codes pour complter ce modle.
Lorsque la fonction du gestionnaire est compile dans un module chargeable (voir Section 35.9.6, Compiler et lier des fonctions
charges dynamiquement ), les commandes suivantes enregistrent le langage procdural dfini dans l'exemple :
CREATE FUNCTION plsample_call_handler() RETURNS language_handler
AS 'nomfichier'
LANGUAGE C;
CREATE LANGUAGE plsample
HANDLER plsample_call_handler;
Bien que fournir un gestionnaire d'appels est suffisant pour crer un langage de procdures minimal, il existe deux autres fonctions
qui peuvent tre fournies pour faciliter l'utilisation du langage. Ce sont les fonctions de validation (validator) et de traitement en
ligne (inline handler). Une fonction de validation peut tre fournie pour activer une vrification spcifique au langage lors du
CREATE FUNCTION(7). Une fonction de traitement en ligne sera utilis pour supporter les blocs de code anonymes excuts via
la commande DO(7).
Si une fonction de validation est fournie par un langage de procdures, elle doit tre dclare comme une fonction prenant un seul
paramtre, de type oid. Le rsultat de la validation est ignor, donc elle peut renvoyer le type void. La fonction de validation sera
appele la fin de la commande CREATE FUNCTION qui a cr ou mis jour une fonction crite dans ce langage. L'OID pass
en argument est l'OID de la fonction, disponible dans le catalogue pg_proc. La fonction de validation doit rcuprer cette ligne
de la faon habituelle et raliser les vrifications appropries. Tout d'abord, elle appelle CheckFunctionValidatorAccess() pour diagnostiquer les appels explicites au validateur que l'utilisateur ne peut pas raliser via CREATE FUNCTION.
Les vrifications typiques incluent la vrification du support des types en arguments et en sortie, ainsi que la vrification syntaxique du corps de la requte pour ce langage. Si la fonction de validation est satisfait par la fonction, elle quitte sans erreur. Si,
par contre, elle trouve une erreur, elle doit rapporter cette erreur au travers du mcanisme ereport() standard. Renvoyer une
erreur forcera une annulation de la transaction et empchera du mme coup l'enregistrement de la fonction dont la dfinition est
errone.
Les fonctions de validation devraient typiquement accepter le paramtre check_function_bodies : s'il est dsactiv, alors tout vrification coteuse ou spcifique au contexte devrait tre abandonne. Si le langage permet l'excution de code la compilation, le
validateur doit supprimer les vrifications qui impliquerait une telle excution. En particulier, ce paramtre est dsactiv par
pg_dump, pour qu'il puisse charger le langage de procdures sans avoir s'inquiter des effets de bord et des dpendances possibles dans le corps des procdures stockes avec d'autres objets de la base de donnes. ( cause de cela, le gestionnaire d'appels
doit viter de supposer que la fonction de validation a vrifi compltement la fonction. Le but d'avoir une fonction de validation
n'est pas d'viter au gestionnaire d'appels de faire des vrifications, mais plutt de notifier immdiatement l'utilisateur si des erreurs videntes apparaissent dans la commande CREATE FUNCTION.) Bien que le choix de ce qui est vrifier est laiss la
discrtion de la fonction de validation, il faut noter que le code de CREATE FUNCTION excute seulement les clauses SET attaches la fonction quand le paramtre check_function_bodies est activ. Du coup, les vrifications dont les rsultats
pourraient tre affects par les paramtres en question doivent tre ignores quand check_function_bodies est dsactiv
pour viter de checs errons lors du chargement d'une sauvegarde.
Si une fonction de traitement en ligne est fournie au langage de procdures, elle doit tre dclare comme une fonction acceptant
un seul paramtre de type internal. Le rsultat de la fonction de traitement en ligne est ignor, donc elle peut renvoyer le type void.
Elle sera appele quand une instruction DO est excute pour ce langage. Le paramtre qui lui est fourni est un pointeur vers une
1310

crire un gestionnaire de langage procdural

structure InlineCodeBlock, structure contenant des informations sur les paramtres de l'instruction DO, en particulier le texte du
bloc de code anonyme excuter. La fonction doit excuter ce code.
It est recommand de placer toutes les dclarations de fonctions ainsi que la commande CREATE LANGUAGE dans une extension pour qu'une simple commande CREATE EXTENSION suffise installer le langage. Voir Section 35.15, Empaqueter des
objets dans une extension pour plus d'informations sur l'criture d'extensions.
Les langages procduraux inclus dans la distribution standard sont de bons points de dpart l'criture de son propre gestionnaire
de langage. Les sources se trouvent dans le rpertoire src/pl. La page de rfrence de CREATE LANGUAGE(7) contient aussi
certains dtails utiles.

1311

Chapitre 50. crire un wrapper de donnes


distantes
Toutes les oprations sur une table distante sont gres via un wrapper de donnes distantes. Ce dernier est un ensemble de fonctions que le planificateur et l'excuteur appelle. Le wrapper de donnes distantes est responsable de la rcupration des donnes
partir de le source de donnes distante et de leur renvoi l'excuteur PostgreSQL. Ce chapitre indique comment crire un
nouveau wrapper de donnes distantes.
Les wrappers de donnes distantes incluent dans la distribution standard sont de bons exemples lorsque vous essayez d'crire les
votres. Regardez dans le sous-rpertoire contrib/file_fdw du rpertoire des sources. La page de rfrence CREATE FOREIGN DATA WRAPPER(7) contient aussi des dtails utiles.

Note
Le standard SQL spcifie une interface pour l'criture des wrappers de donnes distantes. Nanmoins, PostgreSQL n'implmente pas cette API car l'effort ncessaire pour cela serait trop important. De toute faon, l'API standard n'est pas encore trs adopte.

50.1. Fonctions d'un wrapper de donnes distantes


Le dveloppeur d'un FDW doit crire une fonction de gestion (handler) et, en option, une fonction de validation. Les deux fonctions doivent tre crites dans un langage compil comme le C en utilisant l'interface version-1. Pour les dtails sur les conventions d'appel et le chargement dynamique en langage C, voir Section 35.9, Fonctions en langage C .
La fonction de gestion renvoie simplement une structure de pointeurs de fonctions callback qui seront appeles par le planificateur et l'excuteur. La plupart du travail dans l'criture d'une FDW se trouve dans l'implmentation de ces fonctions callback. La
fonction de gestion doit tre enregistre dans PostgreSQL comme ne prenant aucun argument et renvoyant le pseudo-type
fdw_handler. Les fonctions callback sont des fonctions en C et ne sont pas visibles ou appelables avec du SQL. Les fonctions
callback sont dcrites dans Section 50.2, Routines callback des wrappers de donnes distantes .
La fonction de validation est responsable de la validation des options donnes dans les commandes CREATE et ALTER pour
son wrapper de donnes distantes, ainsi que pour les serveurs distants, les correspondances d'utilisateurs et les tables distants utilisant le wrapper. La fonction de validation doit tre enregistre comme prenant deux arguments : un tableau de texte contenant
les options valider et un OID reprsentant le type d'objet avec lequel les options sont valides (sous la forme d'un OID du catalogue systme o sera stock l'objet, donc ForeignDataWrapperRelationId, ForeignServerRelationId,
UserMappingRelationId ou ForeignTableRelationId). Si aucune fonction de validation n'est fournie, les options
ne sont pas vrifies au moment de la cration ou de la modification de l'objet.

50.2. Routines callback des wrappers de donnes distantes


La fonction de gestion d'une FDW renvoie une structure FdwRoutine alloue avec palloc. Elle contient des pointeurs vers les
fonctions de callback suivantes :
FdwPlan *
PlanForeignScan (Oid foreigntableid,
PlannerInfo *root,
RelOptInfo *baserel);
Planifie un parcours d'une table distante. Cette fonction est appele lors de la planification d'une requte. foreigntableid
est l'OID pg_class de la table distante. root sont des informations globales du planificateur sur la requte et baserel sont les
informations du planificateur sur cette table. La fonction doit renvoyer une structure alloue par palloc, contenant les estimations de cot, ainsi que toute information prive du FDW, ncessaires l'excution du parcours plus tard. (Notez que les informations prives doivent tre reprsentes sous une forme que copyObject sait copier.)
Les informations comprises dans root et baserel peuvent tre utilises pour rduire les informations rcuprer de la table
distante (et du coup rduire l'estimation de cot). En particulier, baserel->baserestrictinfo est intressant car il
contient les qualificatifs de restriction (clauses WHERE) qui peuvent tre utiliss pour filter les lignes rcuprer. (La FDW n'a
pas besoin de forcer ces qualificatifs car le plan final les vrifiera de toute faon.) baserel->reltargetlist est utilisable
pour dterminer les colonnes rcuprer.
En plus du renvoi des estimations de cots, la fonction doit mettre jour baserel->rows pour qu'elle corresponde au
1312

crire un wrapper de donnes distantes

nombre de lignes que le FDW s'attend renvoyer lors du parcours, aprs avoir pris en compte le filtrage ralis par les qualificatifs
de restriction. La valeur initiale de baserel->rows est simplement une estimation constante par dfaut, devant tre remplace
si c'est possible. La fonction peut aussi choisir de mettre jour baserel->width s'il peut calculer une meilleure estimation de
la largeur moyenne d'une ligne de rsultat.
void
ExplainForeignScan (ForeignScanState *node,
ExplainState *es);
Affiche une sortie EXPLAIN supplmentaire pour un parcours de table distante. Elle peut ne rien renvoyer si ce n'est pas ncessaire. Sinon, elle doit appeler ExplainPropertyText et les fonctions relatives pour ajouter des champs la sortie du EXPLAIN. Les champs drapeaux dans es peuvent tre utiliss pour dterminer ce qui doit tre affich et l'tat du nud ForeignScanState peut tre inspect pour fournir des statistiques l'excution dans le cas d'un EXPLAIN ANALYZE.
void
BeginForeignScan (ForeignScanState *node,
int eflags);
Commence l'excution d'un parcours distant. L'appel se fait lors du dmarrage de l'excuteur. Cette fonction doit raliser toutes les
initialisation ncessaires avant le dmarrage du parcours, mais ne doit pas commencer excuter le vrai parcours (cela se fera lors
du premier appel IterateForeignScan). Le nud ForeignScanState est dj cr mais son champ fdw_state vaut toujours NULL. Les informations sur la table parcourir sont accessibles via le nud ForeignScanState (en particulier partir du
nud sous-jacent ForeignScan qui contient un pointeur vers la structure FdwPlan renvoye par PlanForeignScan).
Notez que quand (eflags & EXEC_FLAG_EXPLAIN_ONLY) est vraie, cette fonction ne doit pas raliser d'actions visibles
en externe. Elle doit seulement faire le minimum requis pour que l'tat du nud soit valide pour ExplainForeignScan et
EndForeignScan.
TupleTableSlot *
IterateForeignScan (ForeignScanState *node);
Rcupre une ligne de la source distante, la renvoyant dans un emplacement de ligne de table (le champ ScanTupleSlot du
nud doit tre utilis dans ce but). Renvoie NULL s'il n'y a plus de lignes disponibles. L'infrastructure d'emplacement de ligne de
table permet qu'une ligne physique ou virtuelle soit renvoye. Dans la plupart des cas, la deuxime possibilit (virtuelle), est prfrable d'un point de vue des performances. Notez que cette fonction est appele dans un contexte mmoire dont la dure de vie est
trs courte et qui sera rinitialis entre chaque appel. Crez un contexte mmoire dans BeginForeignScan si vous avez besoin
d'un stockage qui tient plus longtemps ou utilisez le champ es_query_cxt de EState.
Les lignes renvoyes doivent correspondre la signature de la colonne de la table distante parcourue. Si vous prfrez optimiser la
rcupration des colonnes inutiles, vous devez insrer des NULL dans les positions de ces colonnes
Notez que l'excuteur de PostgreSQL ne se proccupe pas de savoir si les lignes renvoyes violent les contraintes NOT NULL
dfinies sur les colonnes de la table distante. Le planificateur s'en proccupe et pourrait mal optimiser les requtes si des valeurs
NULL sont prsentes dans une colonne dclare ne pas en contenir. Si une valeur NULL est dcouverte alors que l'utilisateur a dclar qu'aucune valeur NULL ne devrait tre prsente, il pourrait tre appropri de lever une erreur (exactement comme vous le feriez en cas d'un type de donnes inappropri).
void
ReScanForeignScan (ForeignScanState *node);
Recommence le parcours depuis le dbut. Notez que les paramtres dont dpent le parcours peuvent avoir changs de valeur, donc
le nouveau parcours ne va pas forcment renvoyer les mmes lignes.
void
EndForeignScan (ForeignScanState *node);
Termine le parcours et relche les ressources. Il n'est habituellement pas ncessaire de relcher la mmoire alloue via palloc. Par
contre, les fichiers ouverts et les connexions aux serveurs distants doivent tre nettoys.
Les types de structure FdwRoutine et FdwPlan sont dclars dans src/include/foreign/fdwapi.h, qui est lire pour des
dtails supplmentaires.

1313

Chapitre 51. Optimiseur gntique de requtes


(Genetic Query Optimizer)
Martin Utesch, University of Mining and Technology
Auteur
crit par Martin Utesch (<utesch@aut.tu-freiberg.de>) de l'Institut de Contrle Automatique
l'Universit des Mines et de Technologie de Freiberg, Allemagne.

51.1. Grer les requtes, un problme d'optimisation complexe


De tous les oprateurs relationnels, le plus difficile excuter et optimiser est la jointure (join). Le nombre de plans de requtes possibles crot exponentiellement avec le nombre de jointures de la requte. Un effort supplmentaire d'optimisation est
ncessit par le support de diffrentes mthodes de jointure (boucles imbriques, jointures de hachage, jointures de fusion...)
pour excuter des jointures individuelles et diffrents index (B-tree, hash, GiST et GIN...) pour accder aux relations.
L'optimiseur standard de requtes pour PostgreSQL ralise une recherche quasi-exhaustive sur l'ensemble des stratgies alternatives. Cet algorithme, introduit l'origine dans la base de donnes System R d'IBM, produit un ordre de jointure quasi-optimal
mais peut occuper beaucoup de temps et de mmoire mesure que le nombre de jointures d'une requte augmente. L'optimiseur
ordinaire de requtes de PostgreSQL devient donc inappropri pour les requtes qui joignent un grand nombre de tables.
L'Institut de Contrle Automatique de l'Universit des Mines et de Technologie bas Freiberg, Allemagne, a rencontr des difficults lorsqu'il s'est agi d'utiliser PostgreSQL comme moteur d'un systme d'aide la dcision reposant sur une base de
connaissance utilis pour la maintenance d'une grille de courant lectrique. Le SGBD devait grer des requtes nombreuses
jointures pour la machine d'infrence de la base de connaissances. Le nombre de jointures de ces requtes empchait l'utilisation
de l'optimiseur de requte standard.
La suite du document dcrit le codage d'un algorithme gntique de rsolution de l'ordonnancement des jointures qui soit efficace pour les requtes jointures nombreuses.

51.2. Algorithmes gntiques


L'algorithme gntique (GA) est une mthode d'optimisation heuristique qui opre par recherches alatoires. L'ensemble des solutions possibles au problme d'optimisation est considr comme une population d'individus. Le degr d'adaptation d'un individu son environnement est indiqu par sa valeur d'adaptation (fitness).
Les coordonnes d'un individu dans l'espace de recherche sont reprsentes par des chromosomes, en fait un ensemble de
chanes de caractres. Un gne est une sous-section de chromosome qui code la valeur d'un paramtre simple en cours
d'optimisation. Les codages habituels d'un gne sont binary ou integer.
La simulation des oprations d'volution (recombinaison, mutation et slection) permet de trouver de nouvelles gnrations de
points de recherche qui prsentent une meilleure adaptation moyenne que leurs anctres.
Selon la FAQ de comp.ai.genetic, on ne peut pas rellement affirmer qu'un GA n'est pas purement une recherche alatoire. Un GA utilise des processus stochastiques, mais le rsultat est assurment non-alatoire (il est mieux qu'alatoire).
Figure 51.1. Diagramme structur d'un algorithme gntique

P(t)

gnration des anctres au temps t

P''(t)

gnration des descendants au temps t

+=========================================+
|>>>>>>>>>>> Algorithme GA <<<<<<<<<<<<<<|
+=========================================+
| INITIALISE t := 0
|
+=========================================+
| INITIALISE P(t)
|
1314

Optimiseur gntique de requtes (Genetic


Query Optimizer)
+=========================================+
| value ADAPTATION de P(t)
|
+=========================================+
| tant que pas CRITERE ARRET faire
|
|
+-------------------------------------+
|
| P'(t) := RECOMBINAISON{P(t)}
|
|
+-------------------------------------+
|
| P''(t) := MUTATION{P'(t)}
|
|
+-------------------------------------+
|
| P(t+1) := SELECTION{P''(t) + P(t)} |
|
+-------------------------------------+
|
| value ADAPTATION de P''(t)
|
|
+-------------------------------------+
|
| t := t + 1
|
+===+=====================================+

51.3. Optimisation gntique des requtes (GEQO) dans PostgreSQL


Le module GEQO utilise une approche du problme d'optimisation des requtes similaire celui du voyageur de commerce (TSP).
Les plans de requtes possibles sont cods comme des chanes d'entiers. Chaque chane reprsente l'ordre de jointure d'une relation de la requte une autre. Par exemple, l'arbre de jointure
/\
/\ 2
/\ 3
4 1
est cod avec la chane d'entiers '4-1-3-2', ce qui signifie : premire jointure entre les relations '4' et '1', puis '3' et enfin '2', avec 1,
2, 3, 4 les identifiants des relations pour l'optimiseur de PostgreSQL.
Les caractristiques spcifiques de l'implantation du GEQO sont :

l'utilisation d'un algorithme gntique monostable (ou tat stable) (remplacement des individus les moins cibls au lieu d'un
remplacement global de gnration) permet une convergence rapide vers des plans de requtes amliors ; c'est indispensable
au traitement des requtes dans un temps raisonnable ;
l'utilisation de croisements (recombinaisons) aux limites est particulirement adapt pour la restriction des pertes aux limites
lors de la rsolution du problme du voyageur de commerce par un algorithme gntique ;
la mutation en tant qu'oprateur gntique est rendue obsolte afin d'viter la ncessit de mcanismes de rparation lors de la
gnration de tournes valides du problme du voyageur de commerce.

Diverses parties du module GEQO sont adaptes de l'algorithme Genitor de D. Whitley.


Le module GEQO permet l'optimiseur de requtes de PostgreSQL de supporter les requtes disposant de jointures importantes
de manire efficace via une recherche non exhaustive.

51.3.1. Gnration par le GEQO des plans envisageables


Le processus de planification du GEQO utilise le code standard du planificateur pour crer les plans de parcours des relations individuelles. Les plans de jointure sont alors dvelopps l'aide de l'approche gntique. Comme dcrit plus bas, chaque plan de
jointure candidat est reprsent par une squence laquelle joindre les relations de base. Lors de l'tape initiale, l'algorithme produit simplement quelques squences de jointure alatoirement. Pour chaque squence considre, le code du planificateur standard
est invoqu pour estimer le cot de la requte l'aide de cette squence. (Pour chaque tape de la squence, les trois stratgies de
jointure sont considres ; et tous les plans de parcours initiaux sont disponibles. Le cot estim est le moins coteux.) Les squences dont le cot est moindre sont considres plus adapte que celle de cot plus lev. L'algorithme gntique limine les
candidats les moins adapts. De nouveaux candidats sont alors engendrs par combinaison de gnes de candidats forte valeur
d'adaptation -- par l'utilisation de portions alatoires de plans peu coteux pour crer de nouvelles squences. Ce processus est rpt jusqu' ce qu'un nombre prdtermin de squences aient t considres ; la meilleure squence rencontre pendant la recherche est utilise pour produire le plan final.
Ce processus est intrinsquement non-dterministe, du fait des choix alatoires effectus lors de la slection initiale de la population et lors des mutations des meilleurs candidats qui s'en suivent. Pour viter des modifications surprenantes du plan slectionn, chaque excution de l'algorithme relance son gnrateur alatoire de numros avec le paramtre geqo_seed. Tant que geqo_seed et les autres paramtres GEQO sont fixes, le mme plan sera gnr pour une mme requte (ainsi que pour certaines
1315

Optimiseur gntique de requtes (Genetic


Query Optimizer)
informations du planificateur comme les statistiques). Pour exprimenter diffrents chemins de recherche, modifiez geqo_seed.

51.3.2. Tches raliser pour la future implantation du GEQO


Un gros travail est toujours ncessaire pour amliorer les paramtres de l'algorithme gntique. Dans le fichier src/backend/optimizer/geqo/geqo_main.c, pour les routines gimme_pool_size et gimme_number_generations, il
faut trouver un compromis pour que les paramtres satisfassent deux besoins concurrents :

l'optimisation du plan de requte ;


le temps de calcul.

Dans l'implantation courante, l'adaptation de chaque squence de jointure candidate est estime par l'excution ab-initio du code
standard de slection de jointure et d'estimation de cot utilis par le planificateur. Avec l'hypothse que diffrents candidats utilisent des sous-squences de jointure similaires, une grande partie du travail est rpte. Ce processus peut tre grandement acclr en retenant les estimations de cot des sous-jointures. Le problme consiste viter d'tendre inutilement la mmoire en mmorisant ces tats.
un niveau plus basique, il n'est pas certain qu'optimiser une requte avec un algorithme gntique conu pour le problme du
voyageur de commerce soit appropri. Dans le cas du voyageur de commerce, le cot associ une sous-chane quelconque (tour
partiel) est indpendant du reste du tour, mais cela n'est certainement plus vrai dans le cas de l'optimisation de requtes. Du coup,
la question reste pose quant au fait que la recombinaison soit la procdure de mutation la plus efficace.

51.4. Lectures supplmentaires


Les ressources suivantes contiennent des informations supplmentaires sur les algorithmes gntiques :

The Hitch-Hiker's Guide to Evolutionary Computation (FAQ de news://comp.ai.genetic) ;

Evolutionary Computation and its application to art and design, par Craig Reynolds ;

elma04

fong

1316

Chapitre 52. Dfinition de l'interface des mthodes


d'accs aux index
Ce chapitre dfinit l'interface entre le systme PostgreSQL et les mthodes d'accs aux index, qui grent les types d'index individuels. Le systme principal ne sait rien des index en dehors de ce qui est spcifi ici. Il est donc possible de dvelopper de
nouveaux types d'index en crivant du code supplmentaire.
Tous les index de PostgreSQL sont connus techniquement en tant qu'index secondaires ; c'est--dire que l'index est spar
physiquement du fichier de table qu'il dcrit. Chaque index est stock dans sa propre relation physique et donc dcrit par une
entre dans le catalogue pg_class. Le contenu d'un index est entirement contrl par la mthode d'accs l'index. En pratique,
toutes les mthodes d'accs aux index les divisent en pages de taille standard de faon utiliser le gestionnaire de stockage et le
gestionnaire de tampon pour accder au contenu de l'index. De plus, toutes les mthodes existantes d'accs aux index utilisent la
disposition de page standard dcrite dans Section 55.6, Emplacement des pages de la base de donnes et le mme format
pour les en-ttes de ligne de l'index ; mais ces dcisions ne sont pas contraintes sur une mthode d'index.
Dans les faits, un index est une correspondance entre les valeurs des cls de donnes et les identifiants de lignes (tuple identifiers, ou TIDs) des versions de lignes dans la table parent de l'index. Un TID consiste en un numro de bloc et un numro
d'lment l'intrieur de ce bloc (voir Section 55.6, Emplacement des pages de la base de donnes ). C'est une information
suffisante pour rcuprer une version de ligne particulire partir de la table. Les index n'ont pas directement la connaissance de
l'existence ventuelle, sous MVCC, de plusieurs versions de la mme ligne logique ; pour un index, chaque ligne est un objet indpendant qui a besoin de sa propre entre dans l'index. Du coup, la mise jour d'une ligne cre toujours toutes les nouvelles entres d'index pour la ligne, mme si les valeurs de la cl ne changent pas. (Les lignes HOT sont une exception ; mais les index
ne sont pas concerns.) Les entres d'index pour les lignes mortes sont rclames (par le VACUUM) lorsque les lignes mortes
elles-mme sont rclames.

52.1. Entres du catalogue pour les index


Chaque mthode d'accs l'index est dcrite par une ligne dans le catalogue systme pg_am (voir Section 45.3, pg_am ). Le
contenu principal d'une ligne de pg_am est constitu de rfrences des entres de pg_proc qui identifient les fonctions d'accs
l'index fournies par la mthode d'accs. Les API de ces fonctions sont dfinies plus loin dans ce chapitre. De plus, la ligne de
pg_am spcifie quelques proprits fixes de la mthode d'accs, comme le support des index multi-colonnes. Il n'existe pas de
support spcial pour la cration ou la suppression d'entres dans pg_am ; toute personne capable d'crire une nouvelle mthode
d'accs est suppose assez comptente pour insrer la ligne approprie.
Pour tre utile, une mthode d'accs l'index doit aussi avoir une ou plusieurs familles d'oprateur et classes d'oprateur dfinies dans pg_opfamily, pg_opclass, pg_amop et pg_amproc. Ces entres permettent au planificateur de dterminer les types de
qualification des requtes qui peuvent tre utiliss avec les index de cette mthode d'accs. Les familles et classes d'oprateurs
sont dcrites dans Section 35.14, Interfacer des extensions d'index , qui est un lment requis pour comprendre ce chapitre.
Un index individuel est dfini par une entre dans pg_class le dfinissant comme une relation physique, et une entre dans
pg_index affichant le contenu logique de l'index -- c'est--dire ses colonnes d'index et la smantique de ces colonnes, telles que
rcupres par les classes d'oprateur associes. Les colonnes de l'index (valeurs cls) peuvent tre des colonnes simples de la
table sous-jacente ou des expressions sur les lignes de la table. Habituellement, la mthode d'accs l'index ne s'intrese pas la
provenance des valeurs cls de l'index (ce sont toujours des valeurs cls pr-traites), mais trouve beaucoup d'intrt aux informations de la classe d'oprateur dans pg_index. Les entres de ces deux catalogues peuvent tre accdes comme partie de la
structure de donnes de Relation passe toute opration sur l'index.
Certaines colonnes d'options de pg_am ont des implications peu videntes. Les besoins de amcanunique sont discuts dans
Section 52.5, Vrification de l'unicit de l'index . L'option amcanmulticol indique que la mthode d'accs supporte les
index multi-colonnes alors que amoptionalkey indique que des parcours sont autoriss lorsqu'aucune clause de restriction
indexable n'est donne pour la premire colonne de l'index. Quand amcanmulticol est faux, amoptionalkey indique essentiellement si la mthode d'accs autorise les parcours complets de l'index sans clause de restriction. Les mthodes d'accs qui
supportent les colonnes d'index multiples doivent supporter les parcours qui omettent des restrictions sur une ou toutes les colonnes aprs la premire ; nanmoins, elles peuvent imposes qu'une restriction apparaisse pour la premire colonne de l'index,
ce qui est signal par l'initialisation de amoptionalkey faux. Une raison pour laquelle une mthode d'accs d'index initialiserait amoptionalkey false est qu'elle n'indexe pas les valeurs NULL. Comme la plupart des oprateurs indexables sont
stricts et, du coup, ne peuvent pas renvoyer TRUE pour des entres NULL, il est premire vue attractif de ne pas stocker les
entres d'index pour les valeurs NULL : un parcours d'index ne peut, de toute faon, pas les retourner. Nanmoins, cet argument
tombe lorsqu'un parcours d'index n'a pas de clause de restriction pour une colonne d'index donne. En pratique, cela signifie que
les index dont amoptionalkey vaut true doivent indexer les valeurs NULL, car le planificateur peut dcider d'utiliser un tel
index sans aucune cl de parcours. Une restriction en dcoule : une mthode d'accs qui supporte des colonnes d'index multiples
doit supporter l'indexage des valeurs NULL dans les colonnes qui suivent la premire, car le planificateur suppose que l'index
1317

Dfinition de l'interface des mthodes d'accs


aux index
peut tre utilis pour les requtes qui ne restreignent pas ces colonnes. Par exemple, si l'on considre un index sur (a,b) et une requte avec WHERE a = 4, le systme suppose que l'index peut tre utilis pour rechercher les lignes pour lesquelles a = 4, ce
qui est faux si l'index omet les lignes o b est null. Nanmoins, il est correct d'omettre les lignes o la premire colonne indexe
est NULL. Du coup, une mthode d'accs d'index qui ne s'occupe pas des valeurs NULL pourrait aussi configurer amsearchnulls, indiquant ainsi qu'elle supporte les clauses IS NULL et IS NOT NULL dans les conditions de recherche.

52.2. Fonctions de la mthode d'accs aux index


Les fonctions de construction et de maintenance d'index que doit fournir une mthode d'accs aux index sont :
IndexBuildResult *
ambuild (Relation heapRelation,
Relation indexRelation,
IndexInfo *indexInfo);
Construire un nouvel index. La relation de l'index a t cre physiquement mais elle est vide. Elle doit tre remplie avec toute
donne fixe ncessaire la mthode d'accs, ainsi que les entres pour toutes les lignes existant dj dans la table. Habituellement,
la fonction ambuild appelle IndexBuildHeapScan() pour parcourir la table la recherche des lignes qui existent dj et
calculer les cls insrer dans l'index. La fonction doit renvoyer une structure alloue par palloc contenant les statistiques du nouvel index.
bool
void
ambuildempty (Relation indexRelation);
Construire un index vide et l'inscrire dans le fichier d'initialisation (INIT_FORKNUM) de la relation. Cette mthode est seulement
appele pour les tables non traces. L'index vide inscrit dans le fichier d'initialisation sera copi sur le fichier de la relation
chaque redmarrage du serveur.
bool
aminsert (Relation indexRelation,
Datum *values,
bool *isnull,
ItemPointer heap_tid,
Relation heapRelation,
IndexUniqueCheck checkUnique);
Insrer une nouvelle ligne dans un index existant. Les tableaux values et isnull donnent les valeurs de cls indexer.
heap_tid est le TID indexer. Si la mthode d'accs supporte les index uniques (son drapeau pg_am.amcanunique vaut
true), alors checkUnique indique le type de vrification unique raliser. Cela varie si la contrainte unique est dferrable ou
non ; voir Section 52.5, Vrification de l'unicit de l'index pour les dtails. Habituellement, la mthode d'accs a seulement besoin du paramtre heapRelation lors de la vrification de l'unicit (car aprs, elle doit regarder la table pour vrifier la visibilit de la ligne).
La valeur rsultat, de type boolen, de la fonction est significative seulement quand checkUnique vaut
UNIQUE_CHECK_PARTIAL. Dans ce cas, un rsultat TRUE signifie que la nouvelle entre est reconnue comme unique alors
que FALSE indique qu'elle pourrait ne pas tre unique (et une vrification d'unicit dferre doit tre planifie). Dans les autres
cas, un rsultat FALSE constant est recommend.
Certains index pourraient ne pas indexer toutes les lignes. Si la ligne ne doit pas tre indexe, aminsert devrait terminer sans
rien faire.
IndexBulkDeleteResult *
ambulkdelete (IndexVacuumInfo *info,
IndexBulkDeleteResult *stats,
IndexBulkDeleteCallback callback,
void *callback_state);
Supprimer un(des) tuple(s) de l'index. Il s'agit d'une opration de suppression massive implanter par le parcours complet de
l'index et la vrification de chaque entre pour dterminer si elle doit tre supprime. La fonction callback en argument doit
tre appele, sous la forme callback(TID, callback_state) returns bool, pour dterminer si une entre d'index
particulire, identifie par son TID, est supprimer. Cette fonction Doit renvoyer NULL ou une structure issue d'un palloc qui
contient des statistiques sur les effets de l'opration de suppression. La fonction peut retourner NULL si aucune information ne
doit tre envoye amvacuumcleanup.
En cas de limitation de maintenance_work_mem, la suppression de nombreux tuples impose d'appeler ambulkdelete
plusieurs reprises. L'argument stats est le rsultat du dernier appel pour cet index (il est NULL au premier appel dans une op1318

Dfinition de l'interface des mthodes d'accs


aux index
ration VACUUM). Ceci permet l'AM d'accumuler des statistiques sur l'opration dans son intgralit. Typiquement, ambulkdelete modifie et renvoie la mme structure si le stats fourni n'est pas NULL.
IndexBulkDeleteResult *
amvacuumcleanup (IndexVacuumInfo *info,
IndexBulkDeleteResult *stats);
Nettoyage aprs une opration VACUUM (zro plusieurs appels ambulkdelete). La fonction n'a pas d'autre but que de retourner des statistiques concernant les index, mais elle peut raliser un nettoyage en masse (rclamer les pages d'index vides, par
exemple). stats est le retour de l'appel ambulkdelete, ou NULL si ambulkdelete n'a pas t appele car aucune ligne
n'avait besoin d'tre supprime. Si le rsultat n'est pas NULL, il s'agit d'une structure alloue par palloc. Les statistiques qu'elle
contient sont utilises pour mettre jour pg_class, et sont rapportes par VACUUM si VERBOSE est indiqu. La fonction peut retourner NULL si l'index n'a pas t modifi lors de l'opration de VACUUM mais, dans le cas contraire, il faut retourner des statistiques correctes.
partir de PostgreSQL 8.4, amvacuumcleanup sera aussi appel la fin d'une opration ANALYZE operation. Dans ce
cas, stats vaut toujours NULL et toute valeur de retour sera ignore. Ce cas peut tre distingu en vrifiant info>analyze_only. Il est recommand que la mthode d'accs ne fasse rien en dehors du nettoyage aprs insertion pour ce type
d'appel, et cel aseulement dans un processus de travail autovacuum.
void
amcostestimate (PlannerInfo *root,
IndexOptInfo *index,
List *indexQuals,
List *indexOrderBys,
RelOptInfo *outer_rel,
Cost *indexStartupCost,
Cost *indexTotalCost,
Selectivity *indexSelectivity,
double *indexCorrelation);
Estimer les cots d'un parcours d'index. Cette fonction est dcrite compltement dans Section 52.6, Fonctions d'estimation des
cots d'index , ci-dessous.
bytea *
amoptions (ArrayType *reloptions,
bool validate);
Analyser et valider le tableau reloptions pour un index. Cette fonction n'est appele que lorsqu'il existe un tableau reloptions non
NULL pour l'index. reloptions est un tableau de type text contenant des entres de la forme nom=valeur. La fonction
construit une valeur de type bytea copier dans le champ rd_options de l'entre relcache de l'index. Les donnes contenues
dans la valeur bytea sont dfinies par la mthode d'accs. La plupart des mthodes d'accs standard utilisent la structure StdRdOptions. Lorsque validate est true, la fonction remonte un message d'erreur clair si une option n'est pas reconnue ou a des valeurs
invalides ; quand validate est false, les entres invalides sont ignores silencieusement. (validate est faux lors du chargement d'options dj stockes dans pg_catalog ; une entre invalide ne peut tre trouve que si la mthode d'accs a modifi ses
rgles pour les options et, dans ce cas, ignorer les entres obsoltes est appropri.) Pour obtenir le comportement par dfaut, il suffit de retourner NULL.
Le but d'un index est de supporter les parcours de lignes qui correspondent une condition WHERE indexable, souvent appele
qualificateur (qualifier) ou cl de parcours (scan key). La smantique du parcours d'index est dcrite plus compltement dans Section 52.3, Parcours d'index , ci-dessous. Une mthode d'accs l'index peut supporter les parcours d'accs standards ( plain ),
les parcours d'index bitmap ou les deux. Les fonctions lies au parcours qu'une mthode d'accs l'index doit ou devrait fournir sont :
IndexScanDesc
ambeginscan (Relation indexRelation,
int nkeys,
int norderbys);
Prpare un parcours d'index. Les paramtres nkeys et norderbys indiquent le nombre de qualificateurs et d'oprateurs de tri
qui seront utiliss dans le parcours. Cela pourrait se rvler utile pour l'allocation d'espace. Notez que les valeurs actuelles des cls
de parcours ne sont pas encore fournies. Le rsultat doit tre une structure alloue avec la fonction palloc. Pour des raisons
d'implmentation, la mthode d'accs l'index doit crer cette structure en appelant RelationGetIndexScan(). Dans la plupart des cas, ambeginscan fait peu en dehors de cet appel et, peut-tre, d'aqurir des verrous ; les parties intressantes de dbut
de parcours d'index sont dans amrescan.
1319

Dfinition de l'interface des mthodes d'accs


aux index

void
amrescan (IndexScanDesc scan,
ScanKey keys,
int nkeys,
ScanKey orderbys,
int norderbys);
Dmarre ou relance un parcours d'index, possiblement avec des nouvelles cls d'index. (Pour relancer en utilisant des cls dj
passes, NULL est pass pour keys et/ou orderbys.) Notez qu'il n'est pas autoris que le nombre de cls ou d'oprateurs de tri
soit plus grande que celui pass la fonction ambeginscan. En pratique, la fonctionnalit de relancement est utilise quand une
nouvelle ligne externe est slectionne par une jointure de boucle imbrique, et donc une nouvelle valeur de comparaison de cl
est requise, mais la structure de cl de parcours reste la mme.
boolean
amgettuple (IndexScanDesc scan,
ScanDirection direction);
Rcuprer la prochaine ligne d'un parcours donn, dans la direction donne (vers l'avant ou l'arrire de l'index). Renvoie TRUE si
une ligne a t obtenue, FALSE s'il ne reste aucune ligne. Dans le cas TRUE, le TID de la ligne est stock dans la structure scan.
success signifie uniquement que l'index contient une entre qui correspond aux cls de parcours, pas que la ligne existe toujours dans la pile ou qu'elle peut russir le test d'instantan de l'appelant. En cas de succs, amgettuple doit aussi configur
scan->xs_recheck TRUE ou FALSE. FALSE signifie qu'il est certain que l'entre de l'index correspond aux cls de parcours. TRUE signifie que ce n'est pas certain et que les conditions reprsentes par les cls de parcours doivent tre de nouveau
vrifies sur la ligne de la table aprs l'avoir rcupr. Cette diffrence permet de supporter les oprateurs d'index perte . Notez que la nouvelle vrification s'tendra seulement aux conditions de parcours ; un prdicat partiel d'index n'est jamais vrifi par
les appelants amgettuple.
La fonction amgettuple a seulement besoin d'exister si la mthode d'accs supporte les parcours d'index standards. Si ce n'est
pas le cas, le champ amgettuple de la ligne de pg_am doit valoir zro.
int64
amgetbitmap (IndexScanDesc scan,
TIDBitmap *tbm);
Rcupre toutes les lignes du parcours slectionn et les ajoute au TIDBitmap fournit par l'appelant (c'est--dire un OU de
l'ensemble des identifiants de ligne dans l'ensemble o se trouve dj le bitmap). Le nombre de lignes rcupres est renvoy (cela
peut n'tre qu'une estimation car certaines mthodes d'accs ne dtectent pas les duplicats). Lors de l'insertion d'identifiants de
ligne dans le bitmap, amgetbitmap peut indiquer que la vrification des conditions du parcours est requis pour des identifiants
prcis de transactions. C'est identique au paramtre de sortie xs_recheck de amgettuple. Note : dans l'implantation actuelle,
le support de cette fonctionnalit peut beaucoup ressembler au support du stockage perte du bitmap lui-mme, et du coup les appelants vrifient les conditions du parcours et le prdicat de l'index partiel (si disponible) pour les lignes vrifiables nouveau. Cela pourrait ne pas toujours tre vrai. amgetbitmap et amgettuple ne peuvent pas tre utiliss dans le mme parcours
d'index ; il existe d'autres restrictions lors de l'utilisation de amgetbitmap, comme expliques dans Section 52.3, Parcours
d'index .
La fonction amgetbitmap doit seulement exister si la mthode d'accs supporte les parcours d'index bitmap . Dans le cas
contraire, le champ amgetbitmap de la ligne correspondante dans pg_am doit tre zro.
void
amendscan (IndexScanDesc scan);
Terminer un parcours et librer les ressources. La structure scan elle-mme ne doit pas tre libre, mais tout verrou pris en interne par la mthode d'accs doit tre libr.
void
ammarkpos (IndexScanDesc scan);
Marquer la position courante du parcours. La mthode d'accs ne mmorise qu'une seule position par parcours.
void
amrestrpos (IndexScanDesc scan);
Restaurer le parcours sa plus rcente position marque.
Par convention, l'entre pg_proc de toute fonction de mthode d'accs aux index affiche le bon nombre d'arguments, mais les
1320

Dfinition de l'interface des mthodes d'accs


aux index
dclare tous du type internal (la plupart des arguments ont des types qui ne sont pas connus en SQL, et il n'est pas souhaitable que
les utilisateurs appelent les fonctions directement). Le type de retour est dclar void, internal ou boolean suivant le cas. La seule
exception est amoptions, qui doit tre correctement dclare prenant text[] et bool et retournant bytea. Cette protection autorise
le code client excuter amoptions pour tester la validit des paramtres.

52.3. Parcours d'index


Dans un parcours d'index, la mthode d'accs l'index retourne les TID de toutes les lignes annonces correspondre aux cls de
parcours. La mthode d'accs n'est implique ni dans la rcupration de ces lignes dans la table parent de l'index, ni dans les tests
de qualification temporelle ou autre.
Une cl de parcours est une reprsentation interne d'une clause WHERE de la forme cl_index oprateur constante, o
la cl d'index est une des colonnes de l'index et l'oprateur est un des membres de la famille d'oprateur associe avec cette colonne d'index. Un parcours d'index contient entre aucune et plusieurs cls de parcours qui sont assembles implicitement avec des
AND -- les lignes renvoyes doivent satisfaire toutes les conditions indiques.
La mthode d'accs peut indiquer que l'index est perte ou ncessite une vrification pour une requte particulire ; ceci implique
que le parcours d'index renvoie toutes les entres qui correspondent la cl de parcours, avec ventuellement des entres supplmentaires qui ne correspondent pas. La machinerie du parcours d'index du systme principal applique alors les conditions de
l'index au tuple pour vrifier s'il doit bien effectivement tre retenu. Si l'option de vrification n'est pas indique, le parcours
d'index doit renvoyer exactement l'ensemble d'entres correspondantes.
La mthode d'accs doit s'assurer qu'elle trouve correctement toutes les entres correspondantes aux cls de parcours donnes, et
seulement celles-ci. De plus, le systme principal transfert toutes les clauses WHERE qui correspondent aux cls d'index et aux familles d'oprateurs, sans analyse smantique permettant de dterminer si elles sont redondantes ou contradictoires. Par exemple,
tant donn WHERE x > 4 AND x > 14 o x est une colonne indexe B-tree, c'est la fonction B-tree amrescan de dterminer que la premire cl de parcours est redondante et peut tre annule. Le supplment de pr-traitement ncessaire lors de amrescan dpend du niveau de rduction des cls de parcours en une forme normalise ncessaire la mthode d'accs
l'index.
Certaines mthodes d'accs renvoient des entres d'index dans un ordre bien dfini, d'autres non. Il existe en fait deux faons diffrentes permettant une mthode d'accs de fournir une sortie trie :

Les mthodes d'accs qui renvoient toujours les entres dans l'ordre naturel (comme les B-tree) doivent configurer pg_am.amcanorder true. Actuellement, ces mthodes d'accs doivent utiliser des nombres de stratgie compatibles avec les B-tree
pour les oprateurs d'galit et de tri.

Les mthodes d'accs qui supportent les oprateurs de tri doivent configurer pg_am.amcanorderbyop true. Ceci indique
que l'index est capable de renvoyer les entres dans un ordre satisfaisant ORDER BY cl_index oprateur
constante. Les modificateurs de parcours de cette forme peuvent tre passs amrescan comme dcrits prcdemment
previously.

La fonction amgettuple dispose d'un argument direction, qui peut tre soit ForwardScanDirection (le cas normal)
soit BackwardScanDirection. Si le premier appel aprs amrescan prcise BackwardScanDirection, alors
l'ensemble des entres d'index correspondantes est parcourir de l'arrire vers l'avant plutt que dans la direction normale (d'avant
en arrire). amgettuple doit donc renvoyer la dernire ligne correspondante dans l'index, plutt que la premire, comme cela se
fait normalement. (Cela ne survient que pour les mthodes d'accs qui initialise amcanorder true.) Aprs le premier appel,
amgettuple doit tre prpar pour continuer le parcours dans la direction adapte partir de l'entre la plus rcemment renvoye. (Mais si pg_am.amcanbackward vaut false, tous les appels suivants auront la mme direction que le premier.)
Les mthodes d'accs qui supportent les parcours ordonns doivent supporter le marquage d'une position dans un parcours
pour retourner plus tard la position marque. La mme position pourrait tre restaure plusieurs fois. Nanmoins, seule une position par parcours a besoin d'tre conserve en mmoire ; un nouvel appel ammarkpos surcharge la position anciennement marque. Une mthode d'accs qui ne supporte pas les parcours ordonns doit quand mme fournir les fonctions de marquage et de
restauration dans pg_am, mais il est suffisant de leur faire renvoyer des erreurs si les fonctions sont appeles.
Les positions du parcours et du marquage doivent tre conserves de faon cohrente dans le cas d'insertions et de suppressions
concurrentes dans l'index. Il est tout fait correct qu'une entre tout juste insre ne soit pas retourne par un parcours, qui si
l'entre avait exist au dmarrage du parcours, aurait t retourne. De mme est-il correct qu'un parcours retourne une telle entre
lors d'un re-parcours ou d'un retour arrire, alors mme qu'il ne l'a pas retourn lors du parcours initial. l'identique, une suppression concurrente peut tre, ou non, visible dans les rsultats d'un parcours. Il est primordial qu'insertions et suppressions ne
conduisent pas le parcours oublier ou dupliquer des entres qui ne sont pas elles-mme insres ou supprimes.
amgetbitmap peut tre utilis la place de amgettuple pour un parcours d'index. Cela permet de rcuprer toutes les lignes
en un appel. Cette mthode peut s'avrer notablement plus efficace que amgettuple parce qu'elle permet d'viter les cycles de
verrouillage/dverrouillage l'intrieur de la mthode d'accs. En principe, amgetbitmap a les mmes effets que des appels r1321

Dfinition de l'interface des mthodes d'accs


aux index
pts amgettuple, mais plusieurs restrictions ont t imposes pour simplifier la procdure. En premier lieu, amgetbitmap
renvoie toutes les lignes en une fois et le marquage ou la restauration des positions de parcours n'est pas support. Ensuite, les
lignes sont renvoyes dans un bitmap qui n'a pas d'ordre spcifique, ce qui explique pourquoi amgetbitmap ne prend pas de
direction en argument. (Les oprateurs de tri ne seront jamais fournis pour un tel parcours.) Enfin, amgetbitmap ne garantit pas le verrouillage des lignes renvoyes, avec les implications prcises dans Section 52.4, Considrations sur le verrouillage
d'index .
Notez qu'il est permis une mthode d'accs d'implanter seulement amgetbitmap et pas amgettuple, ou vice versa, si son
implantation interne ne convient qu' une seule des API.

52.4. Considrations sur le verrouillage d'index


Les mthodes d'accs aux index doivent grer des mises jour concurrentes de l'index par plusieurs processus. Le systme principal PostgreSQL obtient AccessShareLock sur l'index lors d'un parcours d'index et RowExclusiveLock lors de sa mise
jour (ce qui inclut le VACUUM simple). Comme ces types de verrous ne sont pas conflictuels, la mthode d'accs est responsable
de la finesse du verrouillage dont elle a besoin. Un verrou exclusif sur l'intgralit de l'index entier n'est pris qu' la cration de
l'index, sa destruction ou dans une opration REINDEX.
Construire un type d'index qui supporte les mises jour concurrentes requiert une analyse complte et subtile du comportement requis. Pour les types d'index B-tree et hash, on peut lire les implication sur les dcisions de conception dans src/backend/access/nbtree/README et src/backend/access/hash/README.
En plus des besoins de cohrence interne de l'index, les mises jour concurrentes crent des problmes de cohrence entre la table
parent (l'en-tte, ou heap) et l'index. Comme PostgreSQL spare les accs et les mises jour de l'en-tte de ceux de l'index, il
existe des fentres temporelles pendant lesquelles l'index et l'en-tte peuvent tre incohrents. Ce problme est gr avec les rgles
suivantes :

une nouvelle entre dans l'en-tte est effectue avant son entre dans l'index. (Un parcours d'index concurrent peut alors ne pas
voir l'entre dans l'en-tte. Ce n'est pas gnant dans la mesure o un lecteur de l'index ne s'intresse pas une ligne non valide. Voir Section 52.5, Vrification de l'unicit de l'index );

Lorsqu'entre de l'en-tte va tre supprime (par VACUUM), toutes les entres de l'index doivent d'abord tre supprimes ;

un parcours d'index doit maintenir un lien sur la page d'index contenant le dernier lment renvoy par amgettuple, et ambulkdelete ne peut pas supprimer des entres de pages lies d'autres processus. La raison de cette rgle est explique
plus bas.

Sans la troisime rgle, il est possible qu'un lecteur d'index voit une entre dans l'index juste avant qu'elle ne soit supprime par un
VACUUM, et arrive l'entre correspondante de l'en-tte aprs sa suppression par le VACUUM. Cela ne pose aucun problme
srieux si ce numro d'lment est toujours inutilis quand le lecteur l'atteint, car tout emplacement d'lment vide est ignor par
heap_fetch(). Mais que se passe-t-il si un troisime moteur a dj r-utilis l'emplacement de l'lment pour quelque chose
d'autre ? Lors de l'utilisation d'un instantan compatible MVCC, il n'y a pas de problme car le nouvel occupant de l'emplacement
est certain d'tre trop rcent pour russir le test de l'insstantan. En revanche, avec un instantan non-compatible MVCC (tel que
SnapshotNow), une ligne qui ne correspond pas aux cls de parcours peut tre accepte ou retourne. Ce scnario peut tre vit
en imposant que les cls de parcours soient re-confrontes la ligne d'en-tte dans tous les cas, mais cela est trop coteux. la
place, un lien sur une page d'index est utilis comme proxy pour indiquer que le lecteur peut tre en parcours entre l'entre de
l'index et l'entre de l'en-tte correspondante. Bloquer ambulkdelete sur un tel lien assure que VACUUM ne peut pas supprimer l'entre de l'en-tte avant que le lecteur n'en ait termin avec elle. Cette solution est peu coteuse en temps d'excution, et
n'ajoute de surcharge du fait du blocage que dans de rares cas rellement un conflictuels.
Cette solution requiert que les parcours d'index soient synchrones : chaque ligne d'en-tte doit tre rcupre immdiatement
aprs le parcours de l'entre d'index correspondante. C'est coteux pour plusieurs raisons. Un parcours asynchrone dans lequel
de nombreux TID sont rcuprs de l'index, et pour lequel les en-ttes de lignes ne sont visits que plus tard, requiert moins de
surcharge de verrouillage d'index et autorise un modle d'accs l'en-tte plus efficace. D'aprs l'analyse ci-dessus, l'approche
synchronise doit tre utilise pour les instantans non compatibles avec MVCC, mais un parcours asynchrone est possible pour
une requte utilisant une instantan MVCC.
Dans un parcours d'index amgetbitmap, la mthode d'accs ne conserve pas de lien l'index sur quelque ligne renvoye. C'est
pourquoi, il est prfrable d'utiliser de tels parcours avec les instantans compatibles MVCC.
Quand le drapeau ampredlocks n'est pas configur, tout parcours utilisant cette mthode d'accs de l'index dans une transaction
srialisable acqurera un verrou prdicat non bloquant sur l'index complet. Ceci gnrera un conflit en lecture/criture avec
l'insertion d'une ligne dans cet index par une transaction srialisable concurrente. Si certains motifs de conflit en lecture/criture
sont dtects parmi un ensemble de transactions srialisables concurrentes, une de ces transactions pourrait tre annule pour protger l'intgrit des donnes. Quand le drapeau est configur, cela indique que la mthode d'accs de l'index implmente un verrou
prdicat plus fin, qui tend rduire la frquence d'annulations de telles requtes.
1322

Dfinition de l'interface des mthodes d'accs


aux index

52.5. Vrification de l'unicit de l'index


PostgreSQL assure les contraintes d'unicit SQL en utilisant des index d'unicit, qui sont des index qui refusent les entres multiples cls identiques. Une mthode d'accs qui supporte cette fonctionnalit initialise pg_am.amcanunique true. ( ce jour,
seul B-tree le supporte).
Du fait de MVCC, il est toujours ncessaire de permettre des entres dupliques d'exister physiquement dans un index : les entres peuvent faire rfrence des versions successives d'une mme ligne logique. Le comportement qu'il est rellement souhaitable d'assurer est qu'aucune image MVCC n'inclut deux lignes avec les mmes cls d'index. Cela se rsume aux cas suivants, qu'il
est ncessaire de vrifier l'insertion d'une nouvelle ligne dans un index d'unicit :

si une ligne valide conflictuelle a t supprime par la transaction courante, pas de problme. (En particulier, comme un UPDATE supprime toujours l'ancienne version de la ligne avant d'insrer la nouvelle version, cela permet un UPDATE sur une
ligne sans changer la cl) ;

si une ligne conflictuelle a t insre par une transaction non encore valide, l'insreur potentiel doit attendre de voir si la
transaction est valide. Si la transaction est annule, alors il n'y a pas de conflit. Si la transaction est valide sans que la ligne
conflictuelle soit supprime, il y a violation de la contrainte d'unicit. (En pratique, on attend que l'autre transaction finisse et
le contrle de visibilit est effectu nouveau dans son intgralit) ;

de faon similaire, si une ligne valide conflictuelle est supprime par une transaction non encore valide, l'inserant potentiel
doit attendre la validation ou l'annulation de cette transaction et recommencer le test.

De plus, immdiatement avant de lever une violation d'unicit en fonction des rgles ci-dessus, la mthode d'accs doit revrifier
l'tat de la ligne en cours d'insertion. Si elle est valide tout en tant morte, alors aucune erreur ne survient. (Ce cas ne peut pas
survenir lors du scnario ordinaire d'insertion d'une ligne tout juste cre par la transaction en cours. Cela peut nanmoins arriver
lors d'un CREATE UNIQUE INDEX CONCURRENTLY.)
La mthode d'accs l'index doit appliquer elle-mme ces tests, ce qui signifie qu'elle doit accder l'en-tte pour vrifier le statut
de validation de toute ligne prsente avec une cl duplique au regard du contenu de l'index. C'est sans aucun doute moche et non
modulaire, mais cela permet d'viter un travail redondant : si un test spar est effectu, alors la recherche d'une ligne conflictuelle
dans l'index est en grande partie rpte lors de la recherche d'une place pour insrer l'entre d'index de la nouvelle ligne. Qui plus,
est, il n'y a pas de faon triviale d'viter les conflits, sauf si la recherche de conflit est partie intgrante de l'insertion de la nouvelle
entre d'index.
Si la contrainte unique est dferrable, il y a une complication supplmentaire : nous devons tre capable d'insrer une entre
d'index pour une nouvelle ligne mais de dferrer toute erreur de violation de l'unicit jusqu' la fin de l'instruction, voire mme
aprs. Pour viter des recherches rptes et inutiles de l'index, la mthode d'accs de l'index doit faire une vrification prliminaire d'unicit lors de l'insertion initiale. Si cela montre qu'il n'y a pas de conflit avec une ligne visible, nous avons termin. Sinon,
nous devons planifier une nouvelle vrification quand il sera temps de forcer la contrainte. Si, au moment de la nouvelle vrification, la ligne insre et d'autres lignes de la mme cl sont vivantes, alors l'erreur doit tre reporte. (Notez que, dans ce contexte,
vivant signifie rellement toute ligne dans la chaine HOT de l'entre de l'index est vivante .) Pour implanter ceci, la fonction aminsert reoit un paramtre checkUnique qui peut avoir une des valeurs suivantes :

UNIQUE_CHECK_NO indicates that no uniqueness checking should be done (this is not a unique index).

UNIQUE_CHECK_YES indique qu'il s'agit d'un index unique non dferrable et la vrification de l'unicit doit se faire immdiatement, comme dcrit ci-dessus.

UNIQUE_CHECK_PARTIAL indique que la contrainte unique est dferrable. PostgreSQL utilisera ce mode pour insrer
l'entre d'index de chaque ligne. La mthode d'accs doit autoriser les entres dupliques dans l'index et rapporter tout dupliquat potentiel en renvoyant FALSE partir de aminsert. Pour chaque ligne pour laquelle FALSE est renvoy, une revrification dferre sera planifie.
La mthode d'accs doit identifier toute ligne qui pourrait violer la contrainte unique, mais rapporter des faux positifs n'est pas
une erreur. Cela permet de faire la vrification sans attendre la fin des autres transactions ; les conflits rapports ici ne sont pas
traits comme des erreurs, et seront revrifis plus tard, un moment o ils ne seront peut-tre plus en conflit.

UNIQUE_CHECK_EXISTING indique que c'est une revrification dferre d'une ligne qui a t rapporte comme en violation
potentielle d'unicit. Bien que cela soit implant par un appel aminsert, la mthode d'accs ne doit pas insrer une nouvelle entre d'index dans ce cas. L'entre d'index est dj prsente. la place, la mthode d'accs doit vrifier s'il existe une
autre entre d'index vivante. Si c'est le cas et que la ligne cible est toujours vivante, elle doit rapporter une erreur.
Il est recommend que, dans un appel UNIQUE_CHECK_EXISTING, la mthode d'accs vrifie en plus que la ligne cible
ait rellement une entre existante dans l'index et de rapporter une erreur si ce n'est pas le cas. C'est une bonne ide car les valeurs de la ligne d'index passes aminsert auront t recalcules. Si la dfinition de l'index implique des fonctions qui ne
sont pas vraiment immutables, nous pourrions vrifier la mauvaise aire de l'index. Vrifier que la ligne cible est trouve dans
1323

Dfinition de l'interface des mthodes d'accs


aux index
la revrification permet de s'assurer que nous recherchons les mmes valeurs de la ligne comme elles ont t utilises lors de
l'insertion originale.

52.6. Fonctions d'estimation des cots d'index


La fonction amcostestimate se voit donner des informations dcrivant un parcours d'index possible, incluant des listes de
clauses WHERE et ORDER BY qui ont t dtermines pour tre utilisables avec l'index. Elle doit renvoyer une estimation du
cot de l'accs l'index et de la slectivit des clauses WHERE (c'est--dire la fraction des lignes de la table parent qui seront rcupres lors du parcours de l'index). Pour les cas simples, pratiquement tout le travail de l'estimateur de cot peut tre effectu en
appelant des routines standard dans l'optimiseur ; la raison d'avoir une fonction amcostestimate est d'autoriser les mthodes
d'accs aux index fournir une connaissance spcifique au type d'index, au cas o il serait possible d'amliorer les estimations
standard.
Chaque fonction amcostestimate doit avoir la signature :
void
amcostestimate (PlannerInfo *root,
IndexOptInfo *index,
List *indexQuals,
List *indexOrderBys,
RelOptInfo *outer_rel,
Cost *indexStartupCost,
Cost *indexTotalCost,
Selectivity *indexSelectivity,
double *indexCorrelation);
Les cinq premiers paramtres sont des entres :
root
Information du planificateur sur la requte en cours de traitement.
index
Index considr.
indexQuals
Liste des clauses de qualifications (qual clauses) d'index (implicitement assembles avec des AND) ; une liste NIL indique
qu'aucun qualificateur n'est disponible. Notez que la liste contient des arbres d'expression avec des nuds RestrictInfo audessus, et non pas ScanKeys.
indexOrderBys
Liste des oprateurs ORDER BY indexables, ou NIL s'il n'y en a pas. La liste contient des arbres d'expression, pas des ScanKeys.
outer_rel
Si l'utilisation de l'index est considre dans un parcours d'index pour une jointure interne, c'est l'information du planificateur
concernant le ct externe de la jointure. Sinon NULL. Si non NULL, certaines clauses de qualifications sont des clauses de
jointure avec cette relation plutt que de simples clauses de restriction. De plus, le processus d'estimation du cot doit
s'attendre ce que le parcours d'index soit rpt pour chaque ligne de la relation externe.
Les quatre derniers paramtres sont les sorties passes par rfrence :
*indexStartupCost
Initialis au cot du lancement du traitement de l'index.
*indexTotalCost
Initialis au cot du traitement total de l'index.
*indexSelectivity
Initialis la slectivit de l'index.
*indexCorrelation
Initialis au coefficient de corrlation entre l'ordre du parcours de l'index et l'ordre sous-jacent de la table.
Les fonctions d'estimation de cots doivent tre crites en C, pas en SQL ou dans tout autre langage de procdure, parce qu'elles
doivent accder aux structures de donnes internes du planificateur/optimiseur.
Les

cots

d'accs

aux

index

doivent

tre

calculs
1324

en

utilisant

les

paramtres

utiliss

par

src/ba-

Dfinition de l'interface des mthodes d'accs


aux index
ckend/optimizer/path/costsize.c : la rcupration d'un bloc disque squentiel a un cot de seq_page_cost, une
rcupration non squentielle a un cot de random_page_cost, et le cot de traitement d'une ligne d'index doit habituellement
tre considr comme cpu_index_tuple_cost. De plus, un multiple appropri de cpu_operator_cost doit tre charg
pour tous les oprateurs de comparaison impliqus lors du traitement de l'index (spcialement l'valuation des indexQuals).
Les cots d'accs doivent inclure tous les cots ds aux disques et aux CPU associs au parcours d'index lui-mme, mais pas les
cots de rcupration ou de traitement des lignes de la table parent qui sont identifies par l'index.
Le cot de lancement est la partie du cot total de parcours dpenser avant de commencer rcuprer la premire ligne. Pour
la plupart des index, cela s'value zro, mais un type d'index avec un grand cot de lancement peut vouloir le configurer une
autre valeur que zro.
indexSelectivity doit tre initialis la fraction estime des lignes de la table parent qui sera rcupre lors du parcours
d'index. Dans le cas d'une requte perte, c'est typiquement plus lev que la fraction des lignes qui satisfont les conditions de
qualification donnes.
indexCorrelation doit tre initialis la corrlation (valeur entre -1.0 et 1.0) entre l'ordre de l'index et celui de la table. Cela
permet d'ajuster l'estimation du cot de rcupration des lignes de la table parent.
Dans le cas de la jointure, les nombres renvoys doivent tre les moyennes attendues pour tout parcours de l'index.
Procdure 52.1. Estimation du cot

Un estimateur typique de cot excute le traitement ainsi :


1.

Estime et renvoie la fraction des lignes de la table parent visites d'aprs les conditions de qualification donnes. En l'absence
de toute connaissance spcifique sur le type de l'index, on utilise la fonction de l'optimiseur standard clauselist_selectivity():
*indexSelectivity = clauselist_selectivity(root, indexQuals,
index->rel->relid,
JOIN_INNER, NULL);

2.

Estime le nombre de lignes d'index visites lors du parcours. Pour de nombreux types d'index, il s'agit de indexSelectivity multipli par le nombre de lignes dans l'index, mais cela peut valoir plus (la taille de l'index en pages et lignes est disponible partir de la structure IndexOptInfo).

3.

Estime le nombre de pages d'index rcupres pendant le parcours. Ceci peutt tre simplement indexSelectivity multipli par la taille de l'index en pages.

4.

Calcule le cot d'accs l'index. Un estimateur gnrique peut le faire ainsi :


/*
* Our generic assumption is that the index pages will be read
* sequentially, so they have cost seq_page_cost each, not random_page_cost.
* Also, we charge for evaluation of the indexquals at each index row.
* All the costs are assumed to be paid incrementally during the scan.
*/
cost_qual_eval(&index_qual_cost, indexQuals, root);
*indexStartupCost = index_qual_cost.startup;
*indexTotalCost = seq_page_cost * numIndexPages +
(cpu_index_tuple_cost + index_qual_cost.per_tuple) * numIndexTuples;
Nanmoins, le calcul ci-dessus ne prend pas en compte l'amortissement des lectures des index travers les parcours rpts
d'index dans le cas de la jointure.

5.

Estime la corrlation de l'index. Pour un index ordonn sur un seul champ, cela peut s'extraire de pg_statistic. Si la corrlation est inconnue, l'estimation conservative est zro (pas de corrlation).

Des exemples de fonctions d'estimation du cot sont disponibles dans src/backend/utils/adt/selfuncs.c.

1325

Chapitre 53. Index GiST


53.1. Introduction
GiST est un acronyme de Generalized Search Tree, c'est--dire arbre de recherche gnralis. C'est une mthode d'accs balance structure de type arbre, qui agit comme un modle de base dans lequel il est possible d'implanter des schmas d'indexage
arbitraires. B-trees, R-trees et de nombreux autres schmas d'indexage peuvent tre implants en GiST.
GiST a pour avantage d'autoriser le dveloppement de types de donnes personnaliss avec les mthodes d'accs appropries,
par un expert en types de donnes, plutt que par un expert en bases de donnes.
Quelques informations disponibles ici sont drives du site web du projet d'indexage GiST de l'universit de Californie Berkeley et de la thse de Marcel Kornacker, Mthodes d'accs pour les systmes de bases de donnes de la prochaine gnration.
L'implantation GiST de PostgreSQL est principalement maintenu par Teodor Sigaev et Oleg Bartunov. Leur site web fournit
de plus amples informations.

53.2. Extensibilit
L'implantation d'une nouvelle mthode d'accs un index a toujours t un travail complexe. Il est, en effet, ncessaire de comprendre le fonctionnement interne de la base de donnes, tel que le gestionnaire de verrous ou le WAL.
L'interface GiST dispose d'un haut niveau d'abstraction, ce qui autorise le codeur de la mthode d'accs ne coder que la smantique du type de donnes accd. La couche GiST se charge elle-mme de la gestion des accs concurrents, des traces et de la
recherche dans la structure en arbre.
Cette extensibilit n'est pas comparable celle des autres arbres de recherche standard en termes de donnes gres. Par
exemple, PostgreSQL supporte les B-trees et les index de hachage extensibles. Cela signifie qu'il est possible d'utiliser PostgreSQL pour construire un B-tree ou un hachage sur tout type de donnes. Mais, les B-trees ne supportent que les prdicats
d'chelle (<, =, >), les index de hachage que les requtes d'galit.
Donc, lors de l'indexation d'une collection d'images, par exemple, avec un B-tree PostgreSQL, seules peuvent tre lances des
requtes de type est-ce que imagex est gale imagey , est-ce que imagex est plus petite que imagey et est-ce que imagex est plus grande que imagey . En fonction de la dfinition donne gale , infrieure ou suprieure , cela
peut avoir une utilit. Nanmoins, l'utilisation d'un index bas sur GiST permet de crer de nombreuses possibilits de poser des
questions spcifiques au domaine, telles que trouver toutes les images de chevaux ou trouver toutes les images surexposes .
Pour obtenir une mthode d'accs GiST fonctionnelle, il suffit de coder plusieurs mthodes utilisateur dfinissant le comportement des cls dans l'arbre. Ces mthodes doivent tre suffisamment labores pour supporter des requtes avances, mais pour
toutes les requtes standard (B-trees, R-trees, etc.) elles sont relativement simples. En bref, GiST combine extensibilit, gnralit, r-utilisation de code et interface claire.

53.3. Implantation
Une classe d'oprateur d'index GiST doit fournir sept mthodes, et une huitime optionnelle. La prcision de l'index est assure
par l'implantation des mthodes same, consistent et union alors que l'efficacit (taille et rapidit) de l'index dpendra des
mthodes penalty et picksplit. Les deux fonctions restantes sont compress et decompress, qui permettent un index d'avoir des donnes internes de l'arbre d'un type diffrent de ceux des donnes qu'il indexe. Les feuilles doivent tre du type
des donnes indexes alors que les autres nuds peuvent tre de n'importe quelle structure C (mais vous devez toujours suivre
les rgles des types de donnes de PostgreSQL dans ce cas, voir ce qui concerne varlena pour les donnes de taille variable). Si le type de donnes interne de l'arbre existe au niveau SQL, l'option STORAGE de la commande CREATE OPERATOR CLASS peut tre utilise. La huitime mthode, optionnelle, est distance, qui est ncessaire si la classe d'oprateur
souhaite supporter les parcours ordonnes (intressant dans le cadre des recherches du voisin-le-plus-proche, nearest-neighbor).
consistent
tant donn une entre d'index p et une valeur de requte q, cette fonction dtermine si l'entre de l'index est cohrente
( consistent en anglais) avec la requte ; c'est--dire, est-ce que le prdicat colonne_indexe oprateur_indexable q soit vrai pour toute ligne reprsente par l'entre de l'index ? Pour une entre de l'index de type
feuille, c'est l'quivalent pour tester la condition indexable, alors que pour un nud interne de l'arbre, ceci dtermine s'il est
ncessaire de parcourir le sous-arbre de l'index reprsent par le nud. Quand le rsultat est true, un drapeau recheck
doit aussi tre renvoy. Ceci indique si le prdicat est vrai coup sr ou seulement peut-tre vrai. Si recheck = false,
alors l'index a test exactement la condition du prdicat, alors que si recheck = true, la ligne est seulement un correspondance de candidat. Dans ce cas, le systme valuera automatiquement l'oprateur_indexable avec la valeur ac1326

Index GiST

tuelle de la ligne pour voir s'il s'agit rellement d'une correspondance. Cette convention permet GiST de supporter la fois
les structures sans pertes et celles avec perte de l'index.
La dclaration SQL de la fonction doit ressembler ceci :
CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid,
internal)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
Et le code correspondant dans le module C peut alors suivre ce squelette :
Datum
my_consistent(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(my_consistent);
Datum
my_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
data_type *query = PG_GETARG_DATA_TYPE_P(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
bool
*recheck = (bool *) PG_GETARG_POINTER(4);
data_type *key = DatumGetDataType(entry->key);
bool
retval;
/*
* determine return value as a function of strategy, key and query.
*
* Use GIST_LEAF(entry) to know where you're called in the index tree,
* which comes handy when supporting the = operator for example (you could
* check for non empty union() in non-leaf nodes and equality in leaf
* nodes).
*/
*recheck = true;

/* or false if check is exact */

PG_RETURN_BOOL(retval);
}
Ici, key est un lment dans l'index et query la valeur la recherche dans l'index. Le paramtre StrategyNumber indique l'oprateur appliqu de votre classe d'oprateur. Il correspond un des nombres d'oprateurs dans la commande
CREATE OPERATOR CLASS. Suivant les oprateurs que vous avez inclus dans la classe, le type de donnes de query
pourrait varier avec l'oprateur, mais le squelette ci-dessus suppose que ce n'est pas le cas.
union
Cette mthode consolide l'information dans l'arbre. Suivant un ensemble d'entres, cette fonction gnre une nouvelle entre
d'index qui reprsente toutes les entres donnes.
La dclaration SQL de la fonction doit ressembler ceci :
CREATE OR REPLACE FUNCTION my_union(internal, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
Et le code correspondant dans le module C peut alors suivre ce squelette :
Datum
my_union(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(my_union);
Datum
my_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
GISTENTRY *ent = entryvec->vector;
data_type *out,
1327

Index GiST

int

*tmp,
*old;
numranges,
i = 0;

numranges = entryvec->n;
tmp = DatumGetDataType(ent[0].key);
out = tmp;
if (numranges == 1)
{
out = data_type_deep_copy(tmp);
PG_RETURN_DATA_TYPE_P(out);
}
for (i = 1; i < numranges; i++)
{
old = out;
tmp = DatumGetDataType(ent[i].key);
out = my_union_implementation(out, tmp);
}
PG_RETURN_DATA_TYPE_P(out);
}
Comme vous pouvez le voir dans ce quelette, nous grons un type de donnes o union(X, Y, Z) =
union(union(X, Y), Z). C'est assez simple pour supporter les types de donnes o ce n'est pas le cas, en implantant
un autre algorithme d'union dans cette mthode de support GiST.
La fonction d'implantation de union doit renvoyer un pointeur vers la mmoire qui vient d'tre alloue via la fonction palloc(). Vous ne pouvez pas tout simplement renvoyer l'entre.
compress
Convertit l'lment de donnes dans un format compatible avec le stockage physique dans une page d'index.
La dclaration SQL de la fonction doit ressembler ceci :
CREATE OR REPLACE FUNCTION my_compress(internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
Et le code correspondant dans le module C peut alors suivre ce squelette :
Datum
my_compress(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(my_compress);
Datum
my_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval;
if (entry->leafkey)
{
/* replace entry->key with a compressed version */
compressed_data_type *compressed_data =
palloc(sizeof(compressed_data_type));
/* fill *compressed_data from entry->key ... */
retval = palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(compressed_data),
entry->rel, entry->page, entry->offset, FALSE);
}
else
{
/* typically we needn't do anything with non-leaf entries */
1328

Index GiST

retval = entry;
}
PG_RETURN_POINTER(retval);
}
Vous devez adapter compressed_data_type au type spcifique que vous essayez d'obtenir pour compresser les nuds
finaux.
Vous pourriez aussi avoir besoin de faire attention la compression des valeurs NULL, en enregistrant par exemple (Datum)
0 comme le fait gist_circle_compress.
decompress
L'inverse de la fonction compress. Convertit la reprsentation de l'lment de donne en un format manipulable par la base
de donnes.
La dclaration SQL de la fonction doit ressembler ceci :
CREATE OR REPLACE FUNCTION my_decompress(internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
Et le code correspondant dans le module C peut alors suivre ce squelette :
Datum
my_decompress(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(my_decompress);
Datum
my_decompress(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(PG_GETARG_POINTER(0));
}
Le squelette ci-dessus est convenable dans le cas i aucune dcompression n'est ncessaire.
penalty
Renvoie une valeur indiquant le cot d'insertion d'une nouvelle entre dans une branche particulire de l'arbre. Les lments seront insrs dans l'ordre des pnalits moindres (penalty) de l'arbre. Les valeurs renvoyes par penalty doivent
tre positives ou nulles. Si une valeur ngative est renvoye, elle sera traite comme valant zro.
La dclaration SQL de la fonction doit ressembler ceci :
CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT; -- in some cases penalty functions need not be strict
Et le code correspondant dans le module C peut alors suivre ce squelette :
Datum
my_penalty(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(my_penalty);
Datum
my_penalty(PG_FUNCTION_ARGS)
{
GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
float
*penalty = (float *) PG_GETARG_POINTER(2);
data_type *orig = DatumGetDataType(origentry->key);
data_type *new = DatumGetDataType(newentry->key);
*penalty = my_penalty_implementation(orig, new);
PG_RETURN_POINTER(penalty);
}
La fonction penalty est crucial pour de bonnes performances de l'index. Elle sera utilise lors de l'insertion pour dterminer
la branche suivre pour savoir o ajoter la nouvelle entre dans l'arbre. Lors de l'excution de la requte, plus l'arbre sera bien
1329

Index GiST

balanc, plus l'excution sera rapide.


picksplit
Quand une division de page est ncessaire pour un index, cette fonction dcide des entres de la page qui resteront sur
l'ancienne page et de celles qui seront dplaces sur la nouvelle page.
La dclaration SQL de la fonction doit ressembler ceci :
CREATE OR REPLACE FUNCTION my_picksplit(internal, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
Et le code correspondant dans le module C peut alors suivre ce squelette :
Datum
my_picksplit(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(my_picksplit);
Datum
my_picksplit(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
OffsetNumber maxoff = entryvec->n - 1;
GISTENTRY *ent = entryvec->vector;
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
int
i,
nbytes;
OffsetNumber *left,
*right;
data_type *tmp_union;
data_type *unionL;
data_type *unionR;
GISTENTRY **raw_entryvec;
maxoff = entryvec->n - 1;
nbytes = (maxoff + 1) * sizeof(OffsetNumber);
v->spl_left = (OffsetNumber *) palloc(nbytes);
left = v->spl_left;
v->spl_nleft = 0;
v->spl_right = (OffsetNumber *) palloc(nbytes);
right = v->spl_right;
v->spl_nright = 0;
unionL = NULL;
unionR = NULL;
/* Initialize the raw entry vector. */
raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *));
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
raw_entryvec[i] = &(entryvec->vector[i]);
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
int
real_index = raw_entryvec[i] - entryvec->vector;
tmp_union = DatumGetDataType(entryvec->vector[real_index].key);
Assert(tmp_union != NULL);
/*
* Choose where to put the index entries and update unionL and unionR
* accordingly. Append the entries to either v_spl_left or
* v_spl_right, and care about the counters.
*/
if (my_choice_is_left(unionL, curl, unionR, curr))
{
if (unionL == NULL)
1330

Index GiST

unionL = tmp_union;
else
unionL = my_union_implementation(unionL, tmp_union);
*left = real_index;
++left;
++(v->spl_nleft);
}
else
{
/*
* Same on the right
*/
}
}
v->spl_ldatum = DataTypeGetDatum(unionL);
v->spl_rdatum = DataTypeGetDatum(unionR);
PG_RETURN_POINTER(v);
}
Comme penalty, la fonction picksplit est cruciale pour de bonnes performances de l'index. Concevoir des implantations convenables des fonctions penalty et picksplit est le challenge d'un index GiST performant.
same
Renvoit true si les deux entres de l'index sont identiques, faux sinon.
La dclaration SQL de la fonction ressemble ceci :
CREATE OR REPLACE FUNCTION my_same(internal, internal, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
Et le code correspondant dans le module C peut alors suivre ce squelette :
Datum
my_same(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(my_same);
Datum
my_same(PG_FUNCTION_ARGS)
{
prefix_range *v1 = PG_GETARG_PREFIX_RANGE_P(0);
prefix_range *v2 = PG_GETARG_PREFIX_RANGE_P(1);
bool
*result = (bool *) PG_GETARG_POINTER(2);
*result = my_eq(v1, v2);
PG_RETURN_POINTER(result);
}
Pour des raisons historiques, la fonction same ne renvoie pas seulement un rsultat boolen ; la place, il doit enregistrer le
drapeau l'emplacement indiqu par le troisime argument.
distance
partir d'une entre d'index p et une valeur recherche q, cette fonction dtermine la distance entre l'entre de l'index et
la valeur recherche. Cette fonction doit tre fournie si la classe d'oprateur contient des oprateurs de tri. Une requte utilisant l'oprateur de tri sera implmente en renvoyant les entres d'index dont les valeurs de distance sont les plus petites,
donc les rsultats doivent tre cohrents avec la smantique de l'oprateur. Pour une entre d'index de type feuille, le rsultat
reprsente seulement la distance vers l'entre d'index. Pour un nud de l'arbre interne, le rsultat doit tre la plus petite distance que toute entre enfant reprsente.
La dclaration SQL de la fonction doit ressembler ceci :
CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid)
RETURNS float8
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;

1331

Index GiST

Et le code correspondant dans le module C peut correspondre ce squelette :


Datum
my_distance(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(my_distance);
Datum
my_distance(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
data_type *query = PG_GETARG_DATA_TYPE_P(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */
data_type *key = DatumGetDataType(entry->key);
double
retval;
/*
* determine return value as a function of strategy, key and query.
*/
PG_RETURN_FLOAT8(retval);
}
Les arguments de la fonction distance sont identiques aux arguments de la fonction consistent, sauf qu'il n'y a pas de
drapeau recheck . La distance vers une entre d'index de type feuille doit toujours tre dtermine exactement car il
n'existe pas de moyen pour r-ordonner les lignes une fois qu'elles ont t renvoyes. Une approximation est autorise lors de
la dtermination de la distance vers un nud de l'arbre interne, partir du moment o le rsultat n'est jamais plus grand que la
distance relle vers les enfants. Du coup, la distance vers une bote englobante est habituellement suffisante dans les applications de gomtrie. La valeur du rsultat peut tre une valeur float8 finie. (l'infinit et sa valeur ngative sont utilise en interne pour grer des cas comme les valeurs NULL, donc il n'est pas recommand que les fonctions distance renvoient ces
valeurs.)

53.4. Exemples
La distribution source de PostgreSQL inclut plusieurs exemples de mthodes d'indexation implantes selon GiST. Le systme
principal fournit des fonctionnalits de recherche plein texte (indexation des tsvector et tsquery) ainsi que des fonctionnalits quivalentes aux R-Tree pour certains types de donnes gomtriques (voir src/backend/access/gist/gistproc.c). Les
modules contrib suivants contiennent aussi des classes d'oprateur GiST :
btree_gist
Fonctionnalits quivalentes aux B-Tree pour plusieurs types de donnes
cube
Indexation de cubes multi-dimensionnels
hstore
Module pour le stockage des paires (cl, valeur)
intarray
RD-Tree pour tableaux uni-dimensionnels de valeurs int4
ltree
Indexation des structures de type arbre
pg_trgm
Similarit textuelle par correspondance de trigrammes
seg
Indexation pour les nombres flottants

1332

Chapitre 54. Index GIN


54.1. Introduction
GIN est l'acronyme de Generalized Inverted Index (ou index gnrique inverse). GIN est prvu pour traiter les cas o les items
indexer sont des valeurs composites, et o les requtes devant tre acclres par l'index doivent rechercher des valeurs
d'lments apparaissant dans ces items composites. Par exemple, les items pourraient tre des documents, et les requtes pourraient tre des recherches de documents contenant des mots spcifiques.
Nous utilisons le mot item pour dsigner une valeur composite qui doit tre indexe, et le mot cl pour dsigner une valeur
d'lment. GIN stocke et recherche toujours des cls, jamais des items eux mme.
Un index GIN stocke un jeu de paires de (cl, posting list), o posting list est un jeu d'adresse d'enregistrement (row ID) o la
cl existe. Le mme row ID peut apparatre dans plusieurs posting lists, puisqu'un item peut contenir plus d'une cl. Chaque cl
est stocke une seule fois, ce qui fait qu'un index GIN est trs compact dans le cas o une cl apparat de nombreuses fois.
GIN> est gnralis dans le sens o la mthode d'accs GIN n'a pas besoin de connatre l'opration spcifique qu'elle acclre.
la place, elle utilise les stratgies spcifiques dfinies pour les types de donnes. La stratgie dfinit comment extraire les cls
des items indexer et des conditions des requtes, et comment dterminer si un enregistrement qui contient des valeurs de cls
d'une requte rpond rellement la requte.
Un des avantages de GIN est la possibilit qu'il offre que des types de donnes personnaliss et les mthodes d'accs appropries
soient dvelopps par un expert du domaine du type de donnes, plutt que par un expert en bases de donnes. L'utilisation de
GiST offre le mme avantage.
L'implantation de GIN dans PostgreSQL est principalement l'oeuvre de Teodor Sigaev et Oleg Bartunov. Plus d'informations
sur GIN sont disponibles sur leur site web.

54.2. Extensibilit
L'interface GIN a un haut niveau d'abstraction. De ce fait, la personne qui code la mthode d'accs n'a besoin d'implanter que les
smantiques du type de donnes accd. La couche GIN prend en charge la gestion de la concurrence, des traces et des recherches dans la structure de l'arbre.
Pour obtenir une mthode d'accs GIN fonctionnelle, il suffit d'implanter quatre (ou cinq) mthodes utilisateur. Celles-ci dfinissent le comportement des cls dans l'arbre et les relations entre cls, valeurs indexes et requtes indexables. En rsum, GIN
combine extensibilit, gnralisation, r-utilisation du code une interface claire.
Les quatre mthodes qu'une classe d'oprateur GIN doit fournir sont :
int compare(Datum a, Datum b)
Compare deux cls (et non deux valeurs indexes !) et renvoie un entier ngatif, zro ou un entier positif, qui indique si la
premire cl est infrieure, gale ou suprieure la seconde. Null keys are never passed to this function.
Datum *extractValue(Datum inputValue, int32 *nkeys, bool **nullFlags)
Retourne un tableau de cls allou par palloc en fonction d'un item indexer. Le nombre de cls retournes doit tre stoc
dans *nkeys. Si une des cls peut tre nulle, allouez aussi par palloc un tableau de *nkeys boolens, stockez son adresse
dans *nullFlags, et positionnez les drapeaux null o ils doivent l'tre. *nullFlags eut tre lais NULL (sa valeur
initiale) si toutes les cls sont non-nulles. La valeur retourne peut tre NULL si l'item ne contient aucune cl.
Datum *extractQuery(Datum query, int32 *nkeys, StrategyNumber n, bool **pmatch, Pointer **extra_data, bool **nullFlags, int32 *searchMode)
Renvoie un tableau de cls en fonction de la valeur requter ; c'est--dire que query est la valeur du ct droit d'un oprateur indexable dont le ct gauche est la colonne indexe. n est le numro de stratgie de l'oprateur dans la classe
d'oprateur (voir Section 35.14.2, Stratgies des mthode d'indexation ). Souvent, extractQuery doit consulter n
pour dterminer le type de donnes de query et la mthode utiliser pour extraire les valeurs des cls. Le nombre de cls
renvoyes doit tre stock dans *nkeys. Si une des cls peut tre nulle, allouez aussi par palloc un tableau de *nkeys
boolens, stockez son address *nullFlags, et positionnez les drapeaux null o_ils doivent l'tre. *nullFlags peut
tre laiss NULL (sa valeur initiale) si toutes les cls sont non-nulles. La valeur de retour peut tre NULL si query ne
contient aucune cl.
searchMode est un argument de sortie qui permet extractQuery de spcifier des dtails sur comment la recherche
sera effectue. Si *searchMode est positionn GIN_SEARCH_MODE_DEFAULT (qui est la valeur laquelle il est initialis avant l'appel), seuls les items qui correspondent au moins une des cls retournes sont considres comme des candidats correspondance. Si *searchMode est positionn GIN_SEARCH_MODE_INCLUDE_EMPTY, alors en plus des
1333

Index GIN

items qui contiennent au moins une cl correspondant, les items qui ne contiennent aucune cl sont aussi considres comme
des candidats correspondance. (Ce mode est utile pour implmenter un oprateur est sous-ensemble de, par exemple.) Si
*searchMode est positionn GIN_SEARCH_MODE_ALL, alors tous les items non nuls de l'index sont candidats correspondance, qu'ils aient une cl qui corresponde celles retournes ou non. (Ce mode est beaucoup plus lent que les deux
autres, mais il peut tre ncessaire pour implmenter des cas exceptionnels correctement. Un oprateur qui a besoin de ce
mode dans la plupart des cas n'est probablement pas un bon candidat pour une classe d'oprateur GIN.) Les symboles utiliser pour positionner ce mode sont dfinis dans access/gin.h.
pmatch est un paramtre de sortie utiliser quand une correspondance partielle est permise. Pour l'utiliser, extractQuery doit allouer un tableau de boolens *nkeys et stocker son adresse dans *pmatch. Chaque lment du tableau devrait
tre positionn TRUE si la cl correspondante a besoin d'une correspondance partielle, FALSE sinon. Si *pmatch est positionn NULL alors GIN suppose qu'une mise en correspondance partielle n'est pas ncessaire. La variable est initialise
NULL avant l'appel, et peut donc tre simplement ignore par les classes d'oprateurs qui ne supportent pas les correspondances partielles.
extra_data est un paramtre de sortie qui autorise extractQuery passer des donnes supplmentaires aux mthodes
consistent et comparePartial. Pour l'utiliser, extractQuery doit allouer un tableau de pointeurs *nkeys et stocker son adresse *extra_data, puis stocker ce qu'il souhaite dans les pointeurs individuels. La variable est initialise
NULL avant l'appel, afin que ce paramtre soit simplement ignor par une classe d'oprateurs qui n'a pas besoin de donnes
supplmentaires. Si *extra_data est positionn, le tableau dans son ensemble est pass la mthode consistent method, et l'lment appropri la mthode comparePartial.
bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck, Datum queryKeys[], bool nullFlags[])
Retourne TRUE si un item index rpond l'oprateur de requte possdant le numro de stratgie n (ou pourrait le satisfaire,
si l'indication recheck est retourne). Cette fonction n'a pas d'accs direct aux valeurs des items indexs. Au lieu de cela, ce
qui est disponible, c'est la connaissance de quelles valeurs de cls extraites de la requte apparaissent dans un item index
donn. Le tableau check a une longueur de nkeys, qui est la mme que le nombre de cls retourn prcdemment par extractQuery pour ce datum query. Chaque lment du tableau check est TRUE si l'item index contient la cl de requte correspondante, c'est dire, si (check[i] == TRUE) la i-me cl du tableau rsultat de extractQuery est prsente
dans l'item index. Le datum query original est pass au cas o la mthode contains aurait besoin de le consulter, de
mme que les tableaux queryKeys[] et nullFlags[] retourne prcdemment par extractQuery, ou NULL si aucun.
Quand extractQuery retourne une cl nulle dans queryKeys[], l'lment correpondant de check[] est TRUE si
l'item index contient une cl nulle; c'est dire que la smantique de check[] est comme celle de IS NOT DISTINCT
FROM. La fonction consistent peut examiner l'lment correspondant de nullFlags[] si elle a besoin de faire la diffrence entre une correspondance de valeur normale et une correspondance nulle.
En cas de russite, *recheck devrait tre positionn TRUE si les enregistrements de la table doivent tre revrifies par
rapport l'oprateur de la requte, ou FALSE si le test d'index est exact. Autrement dit, une valeur de retour FALSE garantit
que l'enregistrement de la table ne correspond pas; une valeur de retour TRUE avec *recheck FALSE garantit que
l'enregistrement de la table correspond la requte; et une valeur de retour TRUE avec *recheck TRUE signifie que
l'enregistrement de la table pourrait correspondre la requte, et qu'il doit tre rcupr et re-vrifi en valuant l'oprateur de
la requte directement sur l'item initialement index.
En option, une classe d'oprateurs pour GIN peut fournir une cinquime mthode :
int comparePartial(Datum partial_key, Datum key, StrategyNumber n, Pointer extra_data)
Compare une requte de correspondance partielle une cl d'index. Renvoie un entier dont le signe indique le rsultat : infrieur zro signifie que la cl d'index ne correspond pas la requte mais que le parcours d'index va continuer ; zro signifie
que la cl d'index ne correspond pas la requte ; suprieur zro indique que le parcours d'index doit s'arrter car il n'existe
pas d'autres correspondances. Le numro de stratgie n de l'oprateur qui a gnr la requte de correspondance partielle est
fourni au cas o sa smantique est ncessaire pour dterminer la fin du parcours. De plus, extra_data est l'lment correspondant du tableau extra-data fait par extractQuery, ou NULL sinon. Null keys are never passed to this function.
Pour supporter des requtes correspondance partielle , une classe d'oprateur doit fournir la mthode comparePartial, et
sa mthode extractQuery doit positionner le paramtre pmatch quand une requte correspondance partielle est rencontre.
Voir Section 54.3.2, Algorithme de mise en correspondance partielle pour les dtails.
Le type de donnes rel des diffrentes valeurs Datum mentionnes ci-dessus varien en fonction de la classe d'oprateurs. Les valeurs d'item passe extractValue sont toujours du type d'entre de la classe d'oprateur, et toutes les valeurs cl doivent tre
du type de STORAGE de la classe. Le type de l'argument query pass extractQuery et consistent est ce qui est spcifi comme type de droite de l'oprateur du membre de classe identifi par le numro de stratgie. Ce n'est pas ncessairement le
mme que le type de l'item, tant que des valeurs de cls d'un type correct peuvent en tre extraites.
1334

Index GIN

54.3. Implantation
En interne, un index GIN contient un index B-tree construit sur des cls, chaque cl est un lment d'un ou plusieurs items index
(un membre d'un tableau, par exemple) et o chaque enregistrement d'une page feuille contient soit un pointeur vers un B-tree de
pointeurs vers la table (un posting tree ), ou une liste simple de pointeurs vers enregistrement (un posting list ) quand la liste
est suffisamment courte pour tenir dans un seul enregistrement d'index avec la valeur de la cl.
partir de PostgreSQL 9.1, des valeurs de cl NULL peuvent tre incluses dans l'index. Par ailleurs, des NULLs fictifs sont inclus dans l'index pour des objets indexs qui sont NULL ou ne contiennent aucune cl d'aprs extractValue. Cela permet des
recherches retournant des lments vides.
Les index multi-colonnes GIN sont implments en construisant un seul B-tree sur des valeurs composites (numro de colonne,
valeur de cl). Les valeurs de cls pour les diffrentes colonnes peuvent tre de types diffrents.

54.3.1. Technique GIN de mise jour rapide


Mettre jour un index GIN a tendance tre lent en raison de la nature intrinsque des index inverss : insrer ou mettre jour un
enregistrement de la table peut causer de nombreuses insertions dans l'index (une pour chaque cl extraite de l'lment index).
partir de PostgreSQL 8.4, GIN est capable de reporter plus tard la plupart de ce travail en insrant les nouveaux enregistrements dans une liste temporaire et non trie des entres en attente. Quand un vacuum est dclench sur la table, ou si la liste en attente devient trop grosse (plus grande que work_mem), les entres sont dplaces vers la structure de donnes GIN principale en
utilisant la mme technique d'insertion de masse que durant la cration de l'index. Ceci amliore grandement la vitesse de mise
jour de l'index GIN, mme en prenant en compte le surcot engendr au niveau du vacuum. De plus, ce travail supplmentaire
peut tre attribu un processus d'arrire-plan plutt qu' la requte en avant-plan.
Le principal dfaut de cette approche est que les recherches doivent parcourir la liste d'entres en attente en plus de l'index habituel, et que par consquent une grande liste d'entres en attente ralentira les recherches de faon significative. Un autre dfaut est
que, bien que la majorit des mises jour seront rapides, une mise jour qui rend la liste d'attente trop grande dclenchera un
cycle de nettoyage immdiat et sera donc bien plus lente que les autres mises jour. Une utilisation approprie d'autovacuum peut
minimiser ces deux problmes.
Si la cohrence des temps de rponse est plus importante que la vitesse de mise jour, l'utilisation de liste d'entres en attente peut
tre dsactive en dsactivant le paramtre de stockage FASTUPDATE pour un index GIN. Voir CREATE INDEX(7) pour plus de
dtails.

54.3.2. Algorithme de mise en correspondance partielle


GIN peut supporter des requtes de correspondances partielles , dans lesquelles la requte ne dtermine pas une correspondance parfaite pour une ou plusieurs cls, mais que la correspondance tombe une distance suffisamment faible des valeurs de cl
(dans l'ordre de tri des cls dtermin par la mthode de support compare). La mthode extractQuery, au lieu de retourner
une valeur de cl mettre en correspondance de faon exacte, retourne une valeur de cl qui est la limite infrieure de la plage
rechercher, et retourne l'indicateur pmatch positionn true. La plage de cl est alors parcourue en utilisant la mthode comparePartial. comparePartial doit retourner 0 pour une cl d'index correspondante, une valeur ngative pour une noncorrespondance qui est toujours dans la plage de recherche, et une valeur positive si la cl d'index est sortie de la plage qui pourrait correspondre.

54.4. Conseils et astuces GIN


Cration vs insertion
L'insertion dans un index GIN peut tre lente du fait de la probabilit d'insertion de nombreuses cls pour chaque lment.
C'est pourquoi, pour les chargements massifs dans une table, il est conseill de supprimer l'index GIN et de le re-crer aprs le
chargement.
partir de PostgreSQL 8.4, ce conseil est moins important puisqu'une technique de mise jour retarde est utilise (voir
Section 54.3.1, Technique GIN de mise jour rapide pour plus de dtails). Mais pour les trs grosses mises jour, il peut
toujours tre plus efficace de dtruire et recrer l'index.
maintenance_work_mem
Le temps de construction d'un index GIN dpend grandement du paramtre maintenance_work_mem ; il est contreproductif de limiter la mmoire de travail lors de la cration d'un index.
work_mem
Durant une srie d'insertions dans un index GIN existant qui a FASTUPDATE activ, le systme nettoiera la liste d'entres en
attente ds qu'elle deviendra plus grosse que work_mem. Afin d'viter des fluctuations mesurables de temps de rponse, il est
souhaitable d'avoir un nettoyage de la liste d'attente en arrire-plan (c'est--dire via autovacuum). Les oprations de nettoyage
1335

Index GIN

en avant-plan peuvent tre vites en augmentant work_mem ou en rendant autovacuum plus aggressif. Toutefois, augmenter
work_mem implique que si un nettoyage en avant-plan se produit, il prendra encore plus longtemps.
gin_fuzzy_search_limit
La raison principale qui a pouss le dveloppement des index GIN a t la volont de supporter les recherches plein texte dans
PostgreSQL et il arrive frquemment qu'une recherche renvoie un ensemble volumineux de rsultats. Cela arrive d'autant
plus frquemment que la requte contient des mots trs frquents, auquel cas l'ensemble de rsultats n'est mme pas utile.
Puisque la lecture des lignes sur disque et leur tri prend beaucoup de temps, cette situation est inacceptable en production. (La
recherche dans l'index est, elle, trs rapide.)
Pour faciliter l'excution contrle de telles requtes, GIN dispose d'une limite suprieure souple configurable du nombre de
lignes renvoyes, le paramtre de configuration gin_fuzzy_search_limit. Par dfaut, il est positionn 0 (c'est--dire
sans limite). Si une limite diffrente de 0 est choisie, alors l'ensemble renvoy est un sous-ensemble du rsultat complet, choisi alatoirement.
Souple signifie que le nombre rel de rsultats renvoys peut diffrer lgrement de la limite indique, en fonction de la
requte et de la qualit du gnrateur de nombres alatoires du systme.
D'exprience, des valeurs de l'ordre de quelques milliers ( 5000 -- 20000) fonctionnent bien.

54.5. Limitations
GIN part de l'hypothse que les oprateurs indexables sont stricts. Cela signifie que extractValue ne sera pas appel du tout
sur une valeur d'item NULL ( la place, une entre d'enregistrement factice sera cre automatiquement), et extractQuery ne
sera pas appel non plus pour une valeur de query NULL ( la place, la requte est considre comme impossible satisfaire). Notez toutefois qu'une valeur de cl NULL contenue dans un item composite ou une valeur de requte sont supportes.

54.6. Exemples
Les sources de PostgreSQL incluent des classes d'oprateur GIN pour tsvector et pour les tableaux unidimensionnels de tous les
types internes. La recherche de prfixe dans tsvector est implmente en utilisant les correspondances partielles de GIN. Les modules contrib suivants contiennent aussi des classes d'oprateurs GIN :
btree-gin
Fonctionnalit quivalente B-tree pour plusieurs types de donnes
hstore
Module pour le stockage des paires (cl, valeur)
intarray
Support amlior pour le type int[]
pg_trgm
Similarit de texte par correspondance de trigramme

1336

Chapitre 55. Stockage physique de la base de


donnes
Ce chapitre fournit un aperu du format de stockage physique utilis par les bases de donnes PostgreSQL.

55.1. Emplacement des fichiers de la base de donnes


Cette section dcrit le format de stockage au niveau des fichiers et rpertoires.
Toutes les donnes ncessaires un groupe de bases de donnes sont stockes dans le rpertoire data du groupe, habituellement
rfrenc en tant que PGDATA (d'aprs le nom de la variable d'environnement qui peut tre utilis pour le dfinir). Un emplacement courant pour PGDATA est /var/lib/pgsql/data. Plusieurs groupes, grs par diffrentes instances du serveur,
peuvent exister sur la mme machine.
Le rpertoire PGDATA contient plusieurs sous-rpertoires et fichiers de contrle, comme indiqu dans le Tableau 55.1,
Contenu de PGDATA . En plus de ces lments requis, les fichiers de configuration du groupe, postgresql.conf,
pg_hba.conf et pg_ident.conf sont traditionnellement stocks dans PGDATA (bien qu'il soit possible de les conserver
ailleurs partir de la version 8.0 de PostgreSQL).
Tableau 55.1. Contenu de PGDATA

lment

Description

PG_VERSION

Un fichier contenant le numro de version majeur de PostgreSQL

base

Sous-rpertoire contenant les sous-rpertoires par base de donnes

global

Sous-rpertoire contenant les tables communes au groupe, telles que pg_database

pg_clog

Sous-rpertoire contenant les donnes d'tat de validation des transactions

pg_multixact

Sous-rpertoire contenant des donnes sur l'tat des multi-transactions (utilis pour les verrous
de lignes partages)

pg_notify

Sous-rpertoire contenant les donnes de statut de LISTEN/NOTIFY

pg_serial

Sous-rpertoire contenant des informations sur les transactions srialisables valides

pg_stat_tmp

Sous-rpertoire contenant les fichiers temporaires pour le sous-systme des statistiques

pg_subtrans

Sous-rpertoire contenant les donnes d'tats des sous-transaction

pg_tblspc

Sous-rpertoire contenant les liens symboliques vers les espaces logiques

pg_twophase

Sous-rpertoire contenant les fichiers d'tat pour les transactions prpares

pg_xlog

Sous-rpertoire contenant les fichiers WAL (Write Ahead Log)

postmaster.opts

Un fichier enregistrant les options en ligne de commande avec lesquelles le serveur a t lanc
la dernire fois

postmaster.pid

Un fichier verrou contenant l'identifiant du processus postmaster en cours d'excution (PID), le


chemin du rpertoire de donnes, la date et l'heure du lancement de postmaster, le numro de
port, le chemin du rpertoire du socket de domaine Unix (vide sous Windows), la premire
adresse valide dans listen_address (adresse IP ou *, ou vide s'il n'y a pas d'coute TCP) et
l'identifiant du segment de mmoire partag (ce fichier est supprim l'arrt du serveur)

Pour chaque base de donnes dans le groupe, il existe un sous-rpertoire dans PGDATA/base, nomm d'aprs l'OID de la base
de donnes dans pg_database. Ce sous-rpertoire est l'emplacement par dfaut pour les fichiers de la base de donnes; en particulier, ses catalogues systme sont stocks ici.
Chaque table et index est stock dans un fichier spar. Pour les relations ordinaires, ces fichiers sont nomms d'aprs le numro
filenode de la table ou de l'index. Ce numro est stock dans pg_class.relfilenode. Pour les relations temporaires, le nom
du fichier est de la forme tBBB_FFF, o BBB est l'identifiant du processus serveur qui a cr le fichier, et FFF et le numro filenode. Dans tous les cas, en plus du fichier principal (aussi appel main fork), chaque table et index a une carte des espaces
libres (voir Section 55.3, Carte des espaces libres ), qui enregistre des informations sur l'espace libre disponible dans la relation. La carte des espaces libres est stocke dans un fichier dont le nom est le numro filenode suivi du suffixe _fsm. Les tables
ont aussi une carte des visibilits, stocke dans un fichier de suffixe _vm, pour tracer les pages connues comme n'ayant pas de
lignes mortes. La carte des visibilits est dcrite dans Section 55.4, Carte de visibilit . Les tables non traces et les index dis1337

Stockage physique de la base de donnes

posent d'un troisime fichier, connu sous le nom de fichier d'initialisation. Son nom a pour suffixe _init (voir Section 55.5,
The Initialization Fork ).

Attention
Notez que, bien que le filenode de la table correspond souvent son OID, cela n'est pas ncessairement le cas; certaines oprations, comme TRUNCATE, REINDEX, CLUSTER et quelques formes d'ALTER TABLE, peuvent
modifier le filenode tout en prservant l'OID. vitez de supposer que filenode et OID sont identiques. De plus, pour
certains catalogues systme incluant pg_class lui-mme, pg_class.relfilenode contient zro. Le numro filenode en cours est stock dans une structure de donnes de bas niveau, et peut tre obtenu avec la fonction
pg_relation_filenode().
Quand une table ou un index dpasse 1 Go, il est divis en segments d'un Go. Le nom du fichier du premier segment est identique
au filenode ; les segments suivants sont nomms filenode.1, filenode.2, etc. Cette disposition vite des problmes sur les plateformes qui ont des limitations sur les tailles des fichiers. (Actuellement, 1 Go est la taille du segment par dfaut. Cette taille est
ajustable en utilisant l'option --with-segsize pour configure avant de construire PostgreSQL.) En principe, les fichiers de
la carte des espaces libres et de la carte de visibilit pourraient aussi ncessiter plusieurs segments, bien qu'il y a peu de chance
que cela arrive rellement.
Une table contenant des colonnes avec des entres potentiellement volumineuses aura une table TOAST associe, qui est utilise
pour le stockage de valeurs de champs trop importantes pour conserver des lignes adquates. pg_class.reltoastrelid tablit
un lien entre une table et sa table TOAST, si elle existe. Voir Section 55.2, TOAST pour plus d'informations.
Le contenu des tables et des index est discut plus en dtails dans Section 55.6, Emplacement des pages de la base de donnes .
Les tablespaces rendent ce scnario plus compliqus. Chaque espace logique dfini par l'utilisateur contient un lien symbolique
dans le rpertoire PGDATA/pg_tblspc, pointant vers le rpertoire physique du tablespace (celui spcifi dans la commande
CREATE TABLESPACE). Ce lien symbolique est nomm d'aprs l'OID du tablespace. l'intrieur du rpertoire du tablespace,
il existe un sous-rpertoire avec un nom qui dpend de la version du serveur PostgreSQL, comme par exemple
PG_9.0_201008051. (La raison de l'utilisation de ce sous-rpertoire est que des versions successives de la base de donnes
puissent utiliser le mme emplacement indiqu par CREATE TABLESPACE sans que cela provoque des conflits.) l'intrieur
de ce rpertoire spcifique la version, il existe un sous-rpertoire pour chacune des bases de donnes contenant des lments
dans ce tablespace. Ce sous-rpertoire est nomm d'aprs l'OID de la base. Les tables et les index sont enregistrs dans ce rpertoire et suivent le schma de nommage des filenodes. Le tablespace pg_default n'est pas accd via pg_tblspc mais correspond PGDATA/base. De faon similaire, le tablespace pg_global n'est pas accd via pg_tblspc mais correspond PGDATA/global.
La fonction pg_relation_filepath() affiche le chemin entier (relatif PGDATA) de toute relation. Il est souvent utile pour
ne pas avoir se rappeler toutes les diffrentes rgles ci-dessus. Gardez nanmoins en tte que cette fonction donne seulement le
nom du premier segment du fichier principal de la relation -- vous pourriez avoir besoin d'ajouter le numro de segment et/ou les
extensions _fsm ou _vm pour trouver tous les fichiers associs avec la relation.
Les fichiers temporaires (pour des oprations comme le tri de plus de donnes que ce que la mmoire peut contenir) sont crs
l'intrieur de PGDATA/base/pgsql_tmp, ou dans un sous-rpertoire pgsql_tmp du rpertoire du tablespace si un tablespace
autre que pg_default est indiqu pour eux. Le nom du fichier temporaire est de la forme pgsql_tmpPPP.NNN, o PPP est
le PID du serveur propritaire et NNN distingue les diffrents fichiers temporaires de ce serveur.

55.2. TOAST
Cette section fournit un aperu de TOAST (The Oversized-Attribute Storage Technique, la technique de stockage des attributs trop
grands).
Puisque PostgreSQL utilise une taille de page fixe (habituellement 8 Ko) et n'autorise pas qu'une ligne s'tende sur plusieurs
pages. Du coup, il n'est pas possible de stocker de grandes valeurs directement dans les champs. Pour dpasser cette limitation, les
valeurs de champ volumineuses sont compresses et/ou divises en plusieurs lignes physiques. Ceci survient de faon transparente
pour l'utilisateur, avec seulement un petit impact sur le code du serveur. Cette technique est connu sous l'acronyme affectueux de
TOAST (ou the best thing since sliced bread ).
Seuls certains types de donnes supportent TOAST -- il n'est pas ncessaire d'imposer cette surcharge sur les types de donnes qui
ne produisent pas de gros volumes. Pour supporter TOAST, un type de donnes doit avoir une reprsentation (varlena) longueur
variable, dans laquelle les 32 premiers bits contiennent la longueur totale de la valeur en octets (ceci incluant la longueur ellemme). TOAST n'a aucune contrainte supplmentaire sur la reprsentation. Toutes les fonctions niveau C qui grent un type donnes supportant TOAST doivent faire attention grer les valeurs en entre TOASTes. (Ceci se fait normalement en appelant
PG_DETOAST_DATUM avant de faire quoi que ce soit avec une valeur en entre; mais dans certains cas, des approches plus efficaces sont possibles.)
1338

Stockage physique de la base de donnes

TOAST rcupre deux bits du mot contenant la longueur d'un varlena (ceux de poids fort sur les machines big-endian, ceux de
poids faible sur les machines little-endian), limitant du coup la taille logique de toute valeur d'un type de donnes TOAST 1 Go
(230 - 1 octets). Quand les deux bits sont zro, la valeur est une valeur non TOAST du type de donnes et les bits restants dans
le mot contenant la longueur indiquent la taille total du datum (incluant ce mot) en octets. Quand le bit de poids fort (ou de poids
faible) est un, la valeur a un en-tte de seulement un octet alors qu'un en-tte normal en fait quatre. Les bits restants donnent la
taille total du datum (incluant ce mot) en octets. Il reste un cas spcial : si les bits restants sont tous zro (ce qui est impossible
tant donn que le mot indiquant la longueur est inclus dans la taille), la valeur est un pointeur vers une donne stocke dans une
table TOAST spare (la taille d'un pointeur TOAST est indique dans le second octet du datum). Les valeurs dont l'en-tte fait un
seul octet ne sont pas alignes sur une limite particulire. Enfin, quand le bit de poids fort (ou de poids faible) est supprim mais
que le bit adjacent vaut un, le contenu du datum est compress et doit tre dcompress avant utilisation. Dans ce cas, les bits restants du mot contenant la longueur indiquent la taille totale du datum compress, pas celles des donnes au dpart. Notez que la
compression est aussi possible pour les donnes de la table TOAST mais l'en-tte varlena n'indique pas si c'est le cas -- le contenu
du pointeur TOAST le prcise.
Si une des colonnes d'une table est TOAST-able, la table disposera d'une table TOAST associ, dont l'OID est stocke dans
l'entre pg_class.reltoastrelid de la table. Les valeurs TOASTes hors-ligne sont conserves dans la table TOAST comme
dcrit avec plus de dtails ci-dessous.
La technique de compression utilise est un simple et rapide membre de la famille des techniques de compression LZ. Voir src/
backend/utils/adt/pg_lzcompress.c pour les dtails.
Les valeurs hors-ligne sont divises (aprs compression si ncessaire) en morceaux d'au plus TOAST_MAX_CHUNK_SIZE octets
(par dfaut, cette valeur est choisie pour que quatre morceaux de ligne tiennent sur une page, d'o les 2000 octets). Chaque morceau est stock comme une ligne spare dans la table TOAST de la table propritaire. Chaque table TOAST contient les colonnes
chunk_id (un OID identifiant la valeur TOASTe particulire), chunk_seq (un numro de squence pour le morceau de la valeur) et chunk_data (la donne relle du morceau). Un index unique sur chunk_id et chunk_seq offre une rcupration rapide des valeurs. Un pointeur datum reprsentant une valeur TOASTe hors-ligne a par consquent besoin de stocker l'OID de la
table TOAST dans laquelle chercher et l'OID de la valeur spcifique (son chunk_id). Par commodit, les pointeurs datums
stockent aussi la taille logique du datum (taille de la donne originale non compresse) et la taille stocke relle (diffrente si la
compression a t applique). partir des octets d'en-tte varlena, la taille totale d'un pointeur datum TOAST est par consquent
de 18 octets quelque soit la taille relle de la valeur reprsente.
Le code TOAST est dclench seulement quand une valeur de ligne stocker dans une table est plus grande que
TOAST_TUPLE_THRESHOLD octets (habituellement 2 Ko). Le code TOAST compressera et/ou dplacera les valeurs de champ
hors la ligne jusqu' ce que la valeur de la ligne soit plus petite que TOAST_TUPLE_TARGET octets (habituellement l-aussi
2 Ko) ou que plus aucun gain ne puisse tre ralis. Lors d'une opration UPDATE, les valeurs des champs non modifies sont habituellement prserves telles quelles ; donc un UPDATE sur une ligne avec des valeurs hors ligne n'induit pas de cots cause de
TOAST si aucune des valeurs hors-ligne n'est modifie.
Le code TOAST connat quatre stratgies diffrentes pour stocker les colonnes TOAST-ables :

PLAIN empche soit la compression soit le stockage hors-ligne ; de plus, il dsactive l'utilisation d'en-tte sur un octet pour les
types varlena. Ceci est la seule stratgie possible pour les colonnes des types de donnes non TOAST-ables.

EXTENDED permet la fois la compression et le stockage hors-ligne. Ceci est la valeur par dfaut de la plupart des types de
donnes TOAST-ables. La compression sera tente en premier, ensuite le stockage hors-ligne si la ligne est toujours trop
grande.

EXTERNAL autorise le stockage hors-ligne mais pas la compression. L'utilisation d'EXTERNAL rendra plus rapides les oprations sur des sous-chanes d'importantes colonnes de type text et bytea (au dpens d'un espace de stockage accrus) car ces oprations sont optimises pour rcuprer seulement les parties requises de la valeur hors-ligne lorsqu'elle n'est pas compresse.

MAIN autorise la compression mais pas le stockage hors-ligne. (En ralit le stockage hors-ligne sera toujours ralis pour de
telles colonnes mais seulement en dernier ressort s'il n'existe aucune autre solution pour diminuer suffisamment la taille de la
ligne pour qu'elle tienne sur une page.)

Chaque type de donnes TOAST-able spcifie une stratgie par dfaut pour les colonnes de ce type de donne, mais la stratgie
pour une colonne d'une table donne peut tre modifie avec ALTER TABLE SET STORAGE.
Cette combinaison a de nombreux avantages compars une approche plus directe comme autoriser le stockage des valeurs de
lignes sur plusieurs pages. En supposant que les requtes sont habituellement qualifies par comparaison avec des valeurs de cl
relativement petites, la grosse partie du travail de l'excuteur sera ralise en utilisant l'entre principale de la ligne. Les grandes
valeurs des attributs TOASTs seront seulement rcupres (si elles sont slectionnes) au moment o l'ensemble de rsultats est
envoy au client. Ainsi, la table principale est bien plus petite et un plus grand nombre de ses lignes tiennent dans le cache du tampon partag, ce qui ne serait pas le cas sans aucun stockage hors-ligne. Le tri l'utilise aussi, et les tris seront plus souvent raliss
entirement en mmoire. Un petit test a montr qu'une table contenant des pages HTML typiques ainsi que leurs URL taient stockes en peu prs la moiti de la taille des donnes brutes en incluant la table TOAST et que la table principale contenait moins
1339

Stockage physique de la base de donnes

de 10 % de la totalit des donnes (les URL et quelques petites pages HTML). Il n'y avait pas de diffrence l'excution en comparaison avec une table non TOASTe, dans laquelle toutes les pages HTLM avaient t coupes 7 Ko pour tenir.

55.3. Carte des espaces libres


Chaque table et index, en dehors des index hash, a une carte des espaces libres (appele aussi FSM, acronyme de Free Space Map)
pour conserver le trace des emplacements disponibles dans la relation. Elle est stocke dans un fichier spar du fichier des donnes. Le nom de fichier est le numro relfilenode suivi du suffixe _fsm. Par exemple, si le relfilenode d'une relation est 12345, la
FSM est stocke dans un fichier appel 12345_fsm, dans mme rpertoire que celui utilis pour le fichier des donnes.
La carte des espaces libres est organise comme un arbre de pages FSM. Les pages FSM de niveau bas stockent l'espace libre disponible dans chaque page de la relation. Les niveaux supprieurs agrgent l'information des niveaux bas.
l'intrieur de chaque page FSM se trouve un arbre binaire stock dans un tableau avec un octet par nud. Chaque nud final reprsente une page de la relation, ou une page FSM de niveau bas. Dans chaque nud non final, la valeur la plus haute des valeurs
enfants est stocke. Du coup, la valeur maximum de tous les nuds se trouve la racine.
Voir src/backend/storage/freespace/README pour plus de dtails sur la faon dont la FSM est structure, et comment elle est mise jour et recherche. Le module pg_freespacemap peut tre utilis pour examiner l'information stocke dans les
cartes d'espace libre.

55.4. Carte de visibilit


Chaque relation a une carte de visibilit (VM acronyme de Visibility Map) pour garder trace des pages contenant seulement des
lignes connues pour tre visibles par toutes les transactions actives. Elle est stocke en dehors du fichier de donnes dans un fichier spar nomm suivant le numro relfilenode de la relation, auquel est ajout le suffixe _vm. Par exemple, si le relfilenode de
la relation est 12345, la VM est stocke dans un fichier appel 12345_vm, dans le mme rpertoire que celui du fichier de donnes. Notez que les index n'ont pas de VM.
La carte de visibilit enregistre un bit par page. Un bit 1 signifie que toutes les lignes de la page sont visibles par toutes les transactions. Cela signifie que le page ne contient pas de lignes ncessitant un VACUUM ; dans le futur, cela pourra aussi tre utilis
pour viter de visiter la page lors de vrifications de visibilit. Chaque fois qu'un bit est 1, la condition est vraie coup sr. Par
contre, dans le cas contraire, la condition peut tre vraie comme fausse.

55.5. The Initialization Fork


Each unlogged table, and each index on an unlogged table, has an initialization fork. The initialization fork is an empty table or index of the appropriate type. When an unlogged table must be reset to empty due to a crash, the initialization fork is copied over the
main fork, and any other forks are erased (they will be recreated automatically as needed).

55.6. Emplacement des pages de la base de donnes


Cette section fournit un aperu du format des pages utilises par les tables et index de PostgreSQL.1 Les squences et les tables
TOAST tables sont formates comme des tables standards.
Dans l'explication qui suit, un octet contient huit bits. De plus, le terme lment fait rfrence une valeur de donnes individuelle
qui est stocke dans une page. Dans une table, un lment est une ligne ; dans un index, un lment est une entre d'index.
Chaque table et index est stock comme un tableau de pages d'une taille fixe (habituellement 8 Ko, bien qu'une taille de page diffrente peut tre slectionne lors de la compilation du serveur). Dans une table, toutes les pages sont logiquement quivalentes
pour qu'un lment (ligne) particulier puisse tre stock dans n'importe quelle page. Dans les index, la premire page est gnralement rserve comme mtapage contenant des informations de contrle, et il peut exister diffrents types de pages l'intrieur de
l'index, suivant la mthode d'accs l'index. Les tables ont aussi une carte de visibilit dans un fichier de suffixe _vm, pour tracer
les pages dont on sait qu'elles ne contiennent pas de lignes mortes et qui n'ont pas du coup besoin de VACUUM.
Tableau 55.2, Disposition d'une page affiche le contenu complet d'une page. Il existe cinq parties pour chaque page.
Tableau 55.2. Disposition gnrale d'une page

lment

Description

PageHeaderData

Longueur de 24 octets. Contient des informations gnrales sur la page y compris des pointeurs
sur les espaces libres.

En ralit, les mthodes d'accs par index n'ont pas besoin d'utiliser ce format de page. Toutes les mthodes d'indexage existantes utilisent ce format de base mais les donnes conserves dans les mtapages des index ne suivent habituellement pas les rgles d'emplacement des lments.

1340

Stockage physique de la base de donnes

lment

Description

ItemIdData

Tableau de paires (dcalage,longueur) pointant sur les lments rels. Quatre octets par lment.

Free space

L'espace non allou. Les pointeurs de nouveaux lments sont allous partir du dbut de cette
rgion, les nouveaux lments partir de la fin.

Items

Les lments eux-mmes.

Special space

Donnes spcifiques des mthodes d'accs aux index. Diffrentes mthodes stockent diffrentes
donnes. Vide pour les tables ordinaires.

Les 24 premiers octets de chaque page consistent en un en-tte de page (PageHeaderData). Son format est dtaill dans Tableau 55.3, Disposition de PageHeaderData . Les deux premiers champs traquent l'entre WAL la plus rcente relative cette
page. Ensuite se trouve un champ de deux octets contenant des drapeaux. Ils sont suivis par trois champs d'entiers sur deux octets
(pd_lower, pd_upper et pd_special). Ils contiennent des dcalages d'octets partir du dbut de la page jusqu'au dbut de
l'espace non allou, jusqu' la fin de l'espace non allou, et jusqu'au dbut de l'espace spcial. Les deux octets suivants de l'en-tte
de page, pd_pagesize_version, stockent la fois la taille de la page et un indicateur de versoin. partir de la version 8.3 de
PostgreSQL, le numro de version est 4 ; PostgreSQL 8.1 et 8.2 ont utilis le numro de version 3 ; PostgreSQL 8.0 a utilis le numro de version 2 ; PostgreSQL 7.3 et 7.4 ont utilis le numro de version 1 ; les versions prcdentes utilisaient le numro de version 0. (La disposition fondamentale de la page et le format de l'en-tte n'ont pas chang dans la plupart de ces versions mais la disposition de l'en-tte des lignes de tte a chang.) La taille de la page est seulement prsente comme vrification
croise ; il n'existe pas de support pour avoir plus d'une taille de page dans une installation. Le dernier champ est une aide indiquant si traiter la page serait profitable : il garde l'information sur le plus vieux XMAX non trait de la page.
Tableau 55.3. Disposition de PageHeaderData

Champ

Type

Longueur

Description

pd_lsn

XLogRecPtr

8 octets

LSN : octet suivant le dernier octet de l'enregistrement xlog pour la


dernire modification de cette page

pd_tli

uint16

2 octets

TimeLineID de la dernire modification (seulement les 16 bits de


poids faible)

pd_flags

uint16

2 octets

Bits d'tat

pd_lower

LocationIndex 2 octets

Dcalage jusqu'au dbut de l'espace libre

pd_upper

LocationIndex 2 octets

Dcalage jusqu' la fin de l'espace libre

pd_special

LocationIndex 2 octets

Dcalage jusqu'au dbut de l'espace spcial

pd_pagesize_version

uint16

Taille de la page et disposition de l'information du numro de version

pd_prune_xid

TransactionId 4 bytes

2 octets

Plus vieux XMAX non trait sur la page, ou zro si aucun

Tous les dtails se trouvent dans src/include/storage/bufpage.h.


Aprs l'en-tte de la page se trouvent les identificateurs d'lment (ItemIdData), chacun ncessitant quatre octets. Un identificateur
d'lment contient un dcalage d'octet vers le dbut d'un lment, sa longueur en octets, et quelques bits d'attributs qui affectent
son interprtation. Les nouveaux identificateurs d'lments sont allous si ncessaire partir du dbut de l'espace non allou. Le
nombre d'identificateurs d'lments prsents peut tre dtermin en regardant pd_lower, qui est augment pour allouer un nouvel identificateur. Comme un identificateur d'lment n'est jamais dplac tant qu'il n'est pas libr, son index pourrait tre utilis
sur une base long terme pour rfrencer un lment, mme quand l'lment lui-mme est dplac le long de la page pour compresser l'espace libre. En fait, chaque pointeur vers un lment (ItemPointer, aussi connu sous le nom de CTID), cr par PostgreSQL consiste en un numro de page et l'index de l'identificateur d'lment.
Les lments eux-mmes sont stocks dans l'espace allou en marche arrire, partir de la fin de l'espace non allou. La structure
exacte varie suivant le contenu de la table. Les tables et les squences utilisent toutes les deux une structure nomme HeapTupleHeaderData, dcrite ci-dessous.
La section finale est la section spciale qui pourrait contenir tout ce que les mthodes d'accs souhaitent stocker. Par exemple,
les index b-tree stockent des liens vers les enfants gauche et droit de la page ainsi que quelques autres donnes sur la structure de
l'index. Les tables ordinaires n'utilisent pas du tout de section spciale (indique en configurant pd_special la taille de la
page).
Toutes les lignes de la table sont structures de la mme faon. Il existe un en-tte taille fixe (occupant 23 octets sur la plupart
des machines), suivi par un bitmap NULL optionnel, un champ ID de l'objet optionnel et les donnes de l'utilisateur. L'en-tte est
dtaill dans Tableau 55.4, Disposition de HeapTupleHeaderData . Les donnes relles de l'utilisateur (les colonnes de la ligne)
1341

Stockage physique de la base de donnes

commencent u dcalage indiqu par t_hoff, qui doit toujours tre un multiple de la distance MAXALIGN pour la plateforme.
Le bitmap NULL est seulement prsent si le bit HEAP_HASNULL est initialis dans t_infomask. S'il est prsent, il commence
juste aprs l'en-tte fixe et occupe suffisamment d'octets pour avoir un bit par colonne de donnes (c'est--dire t_natts bits ensemble). Dans cette liste de bits, un bit 1 indique une valeur non NULL, un bit 0 une valeur NULL. Quand le bitmap n'est pas prsent, toutes les colonnes sont supposes non NULL. L'ID de l'objet est seulement prsent si le bit HEAP_HASOID est initialis
dans t_infomask. S'il est prsent, il apparat juste avant la limite t_hoff. Tout ajout ncessaire pour faire de t_hoff un
multiple de MAXALIGN apparatra entre le bitmap NULL et l'ID de l'objet. (Ceci nous assure en retour que l'ID de l'objet est
convenablement align.)
Tableau 55.4. Disposition de HeapTupleHeaderData

Champ

Type

Longueur

t_xmin

TransactionId 4 octets

XID d'insertion

t_xmax

TransactionId 4 octets

XID de suppression

t_cid

CommandId

CID d'insertion et de suppression (surcharge avec t_xvac)

t_xvac

TransactionId 4 octets

XID pour l'opration VACUUM dplaant une version de ligne

t_ctid

ItemPointerData

6 octets

TID en cours pour cette version de ligne ou pour une version plus rcente

t_infomask2

int16

2 octets

nombre d'attributs et quelques bits d'tat

t_infomask

uint16

2 octets

diffrents bits d'options (flag bits)

t_hoff

uint8

1 octet

dcalage vers les donnes utilisateur

4 octets

Description

Tous les dtails sont disponibles dans src/include/access/htup.h.


Interprter les donnes relles peut seulement se faire avec des informations obtenues partir d'autres tables, principalement
pg_attribute. Les valeurs cls ncessaires pour identifier les emplacements des champs sont attlen et attalign. Il n'existe aucun moyen pour obtenir directement un attribut particulier, sauf quand il n'y a que des champs de largeur fixe et aucune colonne
NULL. Tout ceci est emball dans les fonctions heap_getattr, fastgetattr et heap_getsysattr.
Pour lire les donnes, vous avez besoin d'examinez chaque attribut son tour. Commencez par vrifier si le champ est NULL en
fonction du bitmap NULL. S'il l'est, allez au suivant. Puis, assurez-vous que vous avez le bon alignement. Si le champ est un
champ taille fixe, alors tous les octets sont placs simplement. S'il s'agit d'un champ taille variable (attlen = -1), alors c'est un
peu plus compliqu. Tous les types de donnes longueur variable partagent la mme structure commune d'en-tte, struct varlena,
qui inclut la longueur totale de la valeur stocke et quelques bits d'option. Suivant les options, les donnes pourraient tre soit dans
la table de base soit dans une table TOAST ; elles pourraient aussi tre compresses (voir Section 55.2, TOAST ).

1342

Chapitre 56. Interface du moteur, BKI


Les fichiers d'interface du moteur (BKI pour Backend Interface) sont des scripts crits dans un langage spcial, compris par le
serveur PostgreSQL lorsqu'il est excut en mode bootstrap . Ce mode autorise la cration et le remplissage des catalogues
systmes ab initio, l o les commandes SQL exigent leur existence pralable. Les fichiers BKI peuvent donc tre utiliss en
premier lieu pour crer le systme de base de donnes. (Ils n'ont probablement pas d'autre utilit.)
initdb utilise un fichier BKI pour raliser une partie de son travail lors de la cration d'un nouveau cluster de bases de donnes.
Le fichier d'entre utilis par initdb est cr, lors de la construction et de l'installation de PostgreSQL, par un programme
nomm genbki.pl qui lit diffrents fichiers d'en-ttes C spcialement formats partir du rpertoire src/include/catalog des sources. Le fichier BKI cr est appel postgres.bki et est normalement install dans le sousrpertoire share du rpertoire d'installation.
D'autres informations sont disponibles dans la documentation d'initdb.

56.1. Format des fichiers BKI


Cette section dcrit l'interprtation des fichiers BKI par le moteur de PostgreSQL. Cette description est plus facile comprendre si le fichier postgres.bki est utilis comme exemple.
L'entre de BKI reprsente une squence de commandes. Les commandes sont constitues de lexmes (tokens) dont le nombre
dpend de la syntaxe de la commande. Les lexmes sont habituellement spars par des espaces fines, mais en l'absence
d'ambigut ce n'est pas ncessaire. Il n'y a pas de sparateur spcial pour les commandes ; le prochain lexme qui ne peut syntaxiquement pas appartenir la commande qui prcde en lance une autre. (En gnral, il est prfrable, pour des raisons de
clart, de placer toute nouvelle commande sur une nouvelle ligne.) Les lexmes peuvent tre des mots cls, des caractres spciaux (parenthses, virgules, etc.), nombres ou chanes de caractres entre guillemets doubles. Tous sont sensibles la casse.
Les lignes qui dbutent par # sont ignores.

56.2. Commandes BKI


create tablename tableoid [bootstrap] [shared_relation] [without_oids] [rowtype_oid oid]
(name1 = type1 [, name2 = type2, ...])
Cre une table nomme nomtable, possdant l'OID tableoid et compose des colonnes donnes entre parenthses.
Les types de colonnes suivants sont supports directement par bootstrap.c: bool, bytea, char (1 byte), name, int2, int4,
regproc, regclass, regtype, text, oid, tid, xid, cid, int2vector, oidvector, _int4 (array), _text (array), _oid (array), _char
(array), _aclitem (array). Bien qu'il soit possible de crer des tables contenant des colonnes d'autres types, cela ne peut pas
tre ralis avant que pg_type ne soit cr et rempli avec les entres appropries. (Ce qui signifie en fait que seuls ces types
de colonnes peuvent tre utiliss dans les tables utilisant le bootstrap mais que les catalogues ne l'utilisant pas peuvent
contenir tout type interne.)
Quand bootstrap est prcis, la table est uniquement construite sur disque ; rien n'est entr dans pg_class, pg_attribute,
etc, pour cette table. Du coup, la table n'est pas accessible par les oprations SQL standard tant que ces entres ne sont pas
ralises en dur ( l'aide de commandes insert). Cette option est utilise pour crer pg_class, etc.
La table est cre partage si shared_relation est indiqu. Elle possde des OID moins que without_oids ne
soit prcis. L'OID du type de ligne de la table (OID de pg_type) peut en option tre indique via la clause
rowtype_oid ; dans le cas contraire, un OID est automatiquement gnr pour lui. (La clause rowtype_oid est inutile
si bootstrap est spcifi, mais il peut nanmoins tre fourni pour documentation.)
open nomtable
Ouvre la table nomme nomtable pour l'ajout de donnes. Toute table alors ouverte est ferme.
close [nomtable]
Ferme la table ouverte. Le nom de la table peut-tre indiqu pour vrification mais ce n'est pas ncessaire.
insert [OID = valeur_oid] (valeur1 valeur2 ...)
Insre une nouvelle ligne dans la table ouverte en utilisant valeur1, valeur2, etc., comme valeurs de colonnes et valeur_oid comme OID. Si valeur_oid vaut zro (0) ou si la clause est omise, et que la table a des OID, alors le prochain OID disponible est utilis.
La valeur NULL peut tre indique en utilisant le mot cl spcial _null_. Les valeurs contenant des espaces doivent tre
places entre guillemets doubles.
declare [unique] index nomindex oidindex on nomtable using nomam ( classeop1 nom1 [, ...] )
1343

Interface du moteur, BKI

Cre un index nomm nomindex, d'OID indexoid, sur la table nomme nomtable en utilisant la mthode d'accs nomme nomam. Les champs indexer sont appels nom1, nom2 etc., et les classes d'oprateur utiliser sont respectivement
classeop1, classeop2 etc. Le fichier index est cr et les entres appropries du catalogue sont ajoutes pour lui, mais
le contenu de l'index n'est pas initialis par cette commande.
declare toast toasttableoid toastindexoid on nomtable
Cre une table TOAST pour la table nomme nomtable. La table TOAST se voit affecter l'OID toasttableoid et son
index l'OID toastindexoid. Comme avec declare index, le remplissage de l'index est report.
build indices
Remplit les index prcdemment dclars.

56.3. Structure du fichier BKI de bootstrap


La commande open ne peut pas tre utilise avant que les tables qu'elle utilise n'existent et n'aient des entres pour la table ouvrir. (Ces tables minimales sont pg_class, pg_attribute, pg_proc et pg_type.) Pour permettre le remplissage de ces tables ellesmmes, create utilis avec l'option bootstrap ouvre implicitement la table cre pour l'insertion de donnes.
De la mme faon, les commandes declare index et declare toast ne peuvent pas tre utilises tant que les catalogues
systmes dont elles ont besoin n'ont pas t crs et remplis.
Du coup, la structure du fichier postgres.bki doit tre :
1. create bootstrap une des tables critiques
2. insert les donnes dcrivant au moins les tables critiques
3. close
4. rpter pour les autres tables critiques.
5. create (sans bootstrap) une table non critique
6. open
7. insert les donnes souhaites
8. close
9. rpter pour les autres tables non critiques.
10 Dfinir les index et les tables TOAST.
.
11 build indices
.
Il existe, sans doute, d'autres dpendances d'ordre non documentes.

56.4. Exemple
La squence de commandes suivante cre la table test_table avec l'OID 420, deux colonnes cola et colb de types respectifs int4 et text et insre deux lignes dans la table :
create test_table 420 (cola = int4, colb = text)
open test_table
insert OID=421 ( 1 "value1" )
insert OID=422 ( 2 _null_ )
close test_table

1344

Chapitre 57. Comment le planificateur utilise les


statistiques
Ce chapitre est construit sur les informations fournies dans Section 14.1, Utiliser EXPLAIN et Section 14.2, Statistiques
utilises par le planificateur pour montrer certains dtails supplmentaires sur la faon dont le planificateur utilise les statistiques systme pour estimer le nombre de lignes que chaque partie d'une requte pourrait renvoyer. C'est une partie importante
du processus de planification, fournissant une bonne partie des informations pour le calcul des cots.
Le but de ce chapitre n'est pas de documenter le code en dtail mais plutt de prsenter un aperu du fonctionnement. Ceci aidera peut-tre la phase d'apprentissage pour quelqu'un souhaitant lire le code.

57.1. Exemples d'estimation des lignes


Les exemples montrs ci-dessous utilisent les tables de la base de tests de rgression de PostgreSQL. Les affichages indiqus
sont pris depuis la version 8.3. Le comportement des versions prcdentes (ou ultrieures) pourraient varier. Notez aussi que,
comme ANALYZE utilise un chantillonage statistique lors de la ralisation des statistiques, les rsultats peuvent changer lgrement aprs toute excution d'ANALYZE.
Commenons avec une requte simple :
EXPLAIN SELECT * FROM tenk1;
QUERY PLAN
------------------------------------------------------------Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
Comment le planificateur dtermine la cardinalit de tenk1 est couvert dans Section 14.2, Statistiques utilises par le planificateur mais est rpt ici pour tre complet. Le nombre de pages et de lignes est trouv dans pg_class :
SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
relpages | reltuples
----------+----------358 |
10000
Ces nombres sont corrects partir du dernier VACUUM ou ANALYZE sur la table. Le planificateur rcupre ensuite le
nombre de pages actuel dans la table (c'est une opration peu coteuse, ne ncessitant pas un parcours de table). Si c'est diffrent
de relpages, alors reltuples est modifi en accord pour arriver une estimation actuelle du nombre de lignes. Dans ce
cas, les valeurs sont correctes donc l'estimation du nombre de lignes est identique reltuples.
Passons un exemple avec une condition dans sa clause WHERE :
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 1000;
QUERY PLAN
-------------------------------------------------------------------------------Bitmap Heap Scan on tenk1 (cost=24.06..394.64 rows=1007 width=244)
Recheck Cond: (unique1 < 1000)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..23.80 rows=1007 width=0)
Index Cond: (unique1 < 1000)
Le planificateur examine la condition de la clause WHERE et cherche la fonction de slectivit partir de l'oprateur < dans
pg_operator. C'est contenu dans la colonne oprrest et le rsultat, dans ce cas, est scalarltsel. La fonction scalarltsel rcupre l'histogramme pour unique1 partir de pg_statistics. Pour les requtes manuelles, il est plus simple de
regarder dans la vue pg_stats :
SELECT histogram_bounds FROM pg_stats
WHERE tablename='tenk1' AND attname='unique1';
histogram_bounds
-----------------------------------------------------{0,993,1997,3050,4040,5036,5957,7057,8029,9016,9995}
Ensuite, la fraction de l'histogramme occupe par < 1000 est traite. C'est la slectivit. L'histogramme divise l'ensemble en
plus petites parties d'gales frquences, donc tout ce que nous devons faire est de localiser la partie o se trouve notre valeur et
compter une partie d'elle et toutes celles qui la prcdent. La valeur 1000 est clairement dans la seconde partie (993-1997), donc
en supposant une distribution linaire des valeurs l'intrieur de chaque partie, nous pouvons calculer la slectivit comme
1345

Comment le planificateur utilise les statistiques


tant :
selectivity = (1 + (1000 - bucket[2].min)/(bucket[2].max - bucket[2].min))/num_buckets
= (1 + (1000 - 993)/(1997 - 993))/10
= 0.100697
c'est--dire une partie complte plus une fraction linaire de la seconde, divise par le nombre de parties. Le nombre de lignes estimes peut maintenant tre calcul comme le produit de la slectivit et de la cardinalit de tenk1 :
rows = rel_cardinality * selectivity
= 10000 * 0.100697
= 1007 (rounding off)
Maintenant, considrons un exemple avec une condition d'galit dans sa clause WHERE :
EXPLAIN SELECT * FROM tenk1 WHERE stringu1 = 'CRAAAA';
QUERY PLAN
---------------------------------------------------------Seq Scan on tenk1 (cost=0.00..483.00 rows=30 width=244)
Filter: (stringu1 = 'CRAAAA'::name)
De nouveau, le planificateur examine la condition de la clause WHERE et cherche la fonction de slectivit pour =, qui est eqsel.
Pour une estimation d'galit, l'histogramme n'est pas utile ; la place, la liste des valeurs les plus communes (most common values, d'o l'acronyme MCV frquemment utilis) est utilis pour dterminer la slectivit. Regardons-les avec quelques colonnes
supplmentaires qui nous serons utiles plus tard :
SELECT null_frac, n_distinct, most_common_vals, most_common_freqs FROM pg_stats
WHERE tablename='tenk1' AND attname='stringu1';
null_frac
| 0
n_distinct
| 676
most_common_vals |
{EJAAAA,BBAAAA,CRAAAA,FCAAAA,FEAAAA,GSAAAA,JOAAAA,MCAAAA,NAAAAA,WGAAAA}
most_common_freqs | {0.00333333,0.003,0.003,0.003,0.003,0.003,0.003,0.003,0.003,0.003}
Comme CRAAAA apparat dans la liste des MCV, la slectivit est tout simplement l'entre correspondante dans la liste des frquences les plus courantes (MCF, acronyme de Most Common Frequencies) :
selectivity = mcf[3]
= 0.003
Comme auparavant, le nombre estim de lignes est seulement le produit de ceci avec la cardinalit de tenk1 comme prcdemment :
rows = 10000 * 0.003
= 30
Maintenant, considrez la mme requte mais avec une constante qui n'est pas dans la liste MCV :
EXPLAIN SELECT * FROM tenk1 WHERE stringu1 = 'xxx';
QUERY PLAN
---------------------------------------------------------Seq Scan on tenk1 (cost=0.00..483.00 rows=15 width=244)
Filter: (stringu1 = 'xxx'::name)
C'est un problme assez diffrent, comment estimer la slectivit quand la valeur n'est pas dans la liste MCV. L'approche est
d'utiliser le fait que la valeur n'est pas dans la liste, combine avec la connaissance des frquences pour tout les MCV :
selectivity = (1 - sum(mvf))/(num_distinct - num_mcv)
= (1 - (0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003 +
0.003 + 0.003 + 0.003 + 0.003))/(676 - 10)
= 0.0014559
C'est--dire ajouter toutes les frquences pour les MCV et les soustraire d'un, puis les diviser par le nombre des autres valeurs distinctes. Notez qu'il n'y a pas de valeurs NULL, donc vous n'avez pas vous en inquiter (sinon nous pourrions soustraire la fraction NULL partir du numrateur). Le nombre estim de lignes est ensuite calcul comme d'habitude :

1346

Comment le planificateur utilise les statistiques


rows = 10000 * 0.0014559
= 15 (rounding off)
L'exemple prcdent avec unique1 < 1000 tait une sur-simplification de ce que scalarltsel faisait rellement ; maintenant que nous avons vu un exemple de l'utilisation des MCV, nous pouvons ajouter quelques dtails supplmentaires. L'exemple
tait correct aussi loin qu'il a t car, comme unique1 est une colonne unique, elle n'a pas de MCV (videmment, n'avoir aucune
valeur n'est pas plus courant que toute autre valeur). Pour une colonne non unique, il y a normalement un histogramme et une liste
MCV, et l'histogramme n'inclut pas la portion de la population de colonne reprsente par les MCV. Nous le faisons ainsi parce
que cela permet une estimation plus prcise. Dans cette situation, scalarltsel s'applique directement la condition
(c'est--dire < 1000 ) pour chaque valeur de la liste MCV, et ajoute les frquence des MCV pour lesquelles la condition est vrifie. Ceci donne une estimation exacte de la slectivit dans la portion de la table qui est MCV. L'histogramme est ensuite utilise de la mme faon que ci-dessus pour estimer la slectivit dans la portion de la table qui n'est pas MCV, et ensuite les deux
nombres sont combines pour estimer la slectivit. Par exemple, considrez
EXPLAIN SELECT * FROM tenk1 WHERE stringu1 < 'IAAAAA';
QUERY PLAN
-----------------------------------------------------------Seq Scan on tenk1 (cost=0.00..483.00 rows=3077 width=244)
Filter: (stringu1 < 'IAAAAA'::name)
Nous voyons dj l'information MCV pour stringu1, et voici son histogramme :
SELECT histogram_bounds FROM pg_stats
WHERE tablename='tenk1' AND attname='stringu1';
histogram_bounds
-------------------------------------------------------------------------------{AAAAAA,CQAAAA,FRAAAA,IBAAAA,KRAAAA,NFAAAA,PSAAAA,SGAAAA,VAAAAA,XLAAAA,ZZAAAA}
En vrifiant la liste MCV, nous trouvons que la condition stringu1 < 'IAAAAA' est satisfaite par les six premires entres et
non pas les quatre dernires, donc la slectivit dans la partie MCV de la population est :
selectivity = sum(relevant mvfs)
= 0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003
= 0.01833333
Additionner toutes les MFC nous indique aussi que la fraction totale de la population reprsente par les MCV est de 0.03033333,
et du coup la fraction reprsente par l'histogramme est de 0.96966667 (encore une fois, il n'y a pas de NULL, sinon nous devrions
les exclure ici). Nous pouvons voir que la valeur IAAAAA tombe prs de la fin du troisime jeton d'histogramme. En utilisant un
peu de suggestions sur la frquence des caractres diffrents, le planificateur arrive l'estimation 0.298387 pour la portion de la
population de l'histogramme qui est moindre que IAAAAA. Ensuite nous combinons les estimations pour les populations MCV et
non MCV :
selectivity = mcv_selectivity + histogram_selectivity * histogram_fraction
= 0.01833333 + 0.298387 * 0.96966667
= 0.307669
rows

= 10000 * 0.307669
= 3077 (rounding off)

Dans cet exemple particulier, la correction partir de la liste MCV est trs petit car la distribution de la colonne est rellement assez plat (les statistiques affichant ces valeurs particulires comme tant plus communes que les autres sont principalement des
une erreur d'chantillonage). Dans un cas plus typique o certaines valeurs sont significativement plus communes que les autres,
ce processus compliqu donne une amlioration utile dans la prcision car la slectivit pour les valeurs les plus communes est
trouve exactement.
Maintenant, considrons un cas avec plus d'une condition dans la clause WHERE :
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 1000 AND stringu1 = 'xxx';
QUERY PLAN
-------------------------------------------------------------------------------Bitmap Heap Scan on tenk1 (cost=23.80..396.91 rows=1 width=244)
Recheck Cond: (unique1 < 1000)
1347

Comment le planificateur utilise les statistiques


Filter: (stringu1 = 'xxx'::name)
-> Bitmap Index Scan on tenk1_unique1
Index Cond: (unique1 < 1000)

(cost=0.00..23.80 rows=1007 width=0)

Le planificateur suppose que les deux conditions sont indpendantes, pour que les slectivits individuelles des clauses puissent
tre multiplies ensemble :
selectivity = selectivity(unique1 < 1000) * selectivity(stringu1 = 'xxx')
= 0.100697 * 0.0014559
= 0.0001466
rows

= 10000 * 0.0001466
= 1 (rounding off)

Notez que le nombre de lignes estim tre renvoyes partir bitmap index scan reflte seulement la condition utilise avec
l'index ; c'est important car cela affecte l'estimation du cot pour les rcuprations suivantes sur la table.
Enfin, nous examinerons une requte qui implique une jointure :
EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 50 AND t1.unique2 = t2.unique2;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------Nested Loop (cost=4.64..456.23 rows=50 width=488)
-> Bitmap Heap Scan on tenk1 t1 (cost=4.64..142.17 rows=50 width=244)
Recheck Cond: (unique1 < 50)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.63 rows=50 width=0)
Index Cond: (unique1 < 50)
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..6.27 rows=1 width=244)
Index Cond: (unique2 = t1.unique2)
La restriction sur tenk1, unique1 < 50, est value avant la jointure de boucle imbrique. Ceci est gr de faon analogue
l'exemple prcdent. Cette fois, la valeur 50 est dans la premire partie de l'histogramme unique1 :
selectivity = (0 + (50 - bucket[1].min)/(bucket[1].max - bucket[1].min))/num_buckets
= (0 + (50 - 0)/(993 - 0))/10
= 0.005035
rows

= 10000 * 0.005035
= 50 (rounding off)

La restriction pour la jointure est t2.unique2 = t1.unique2. L'oprateur est tout simplement le =, nanmoins la fonction
de slectivit est obtenue partir de la colonne oprjoin de pg_operator, et est eqjoinsel. eqjoinsel recherche
l'information statistique de tenk2 et tenk1 :
SELECT tablename, null_frac,n_distinct, most_common_vals FROM pg_stats
WHERE tablename IN ('tenk1', 'tenk2') AND attname='unique2';
tablename | null_frac | n_distinct | most_common_vals
-----------+-----------+------------+-----------------tenk1
|
0 |
-1 |
tenk2
|
0 |
-1 |
Dans ce cas, il n'y a pas d'information MCV pour unique2 parce que toutes les valeurs semblent tre unique, donc nous utilisons
un algorithme qui relie seulement le nombre de valeurs distinctes pour les deux relations ensembles avec leur fractions NULL :
selectivity = (1 - null_frac1) * (1 - null_frac2) * min(1/num_distinct1,
1/num_distinct2)
= (1 - 0) * (1 - 0) / max(10000, 10000)
= 0.0001
C'est--dire, soustraire la fraction NULL pour chacune des relations, et divisez par le maximum of the numbers of distinct values.
Le nombre de lignes que la jointure pourrait mettre est calcul comme la cardinalit du produit cartsien de deux inputs, multipli
par la slectivit :
rows = (outer_cardinality * inner_cardinality) * selectivity
= (50 * 10000) * 0.0001
1348

Comment le planificateur utilise les statistiques


= 50
S'il y avait eu des listes MCV pour les deux colonnes, eqjoinsel aurait utilis une comparaison directe des listes MCV pour
dterminer la slectivit de jointure l'intrieur de la aprtie des populations de colonne reprsentes par les MCV. L'estimation
pour le reste des populations suit la mme approche affiche ici.
Notez que nous montrons inner_cardinality comme 10000, c'est--dire la taille non modifie de tenk2. Il pourrait apparatre en inspectant l'affichage EXPLAIN que l'estimation des lignes jointes vient de 50 * 1, c'est--dire que le nombre de lignes
externes multipli par le nombre estim de lignes obtenu par chaque parcours d'index interne sur tenk2. Mais ce n'est pas le cas : la
taille de la relation jointe est estime avant tout plan de jointure particulier considr. Si tout fonctionne si bien, alors les deux
faons d'estimer la taille de la jointure produiront la mme rponse mais, cause de l'erreur d'arrondi et d'autres facteurs, ils divergent quelque fois significativement.
Pour les personnes intresses par plus de dtails, l'estimation de la taille d'une table (avant toute clause WHERE) se fait dans
src/backend/optimizer/util/plancat.c. La logique gnrique pour les slectivits de clause est dans src/
backend/optimizer/path/clausesel.c. Les fonctions de slectivit spcifiques aux oprateurs se trouvent principalement dans src/backend/utils/adt/selfuncs.c.

1349

Partie VIII. Annexes

Annexe A. Codes d'erreurs de PostgreSQL


Tous les messages mis par le serveur PostgreSQL se voient affects des codes d'erreur sur cinq caractres. Ces codes suivent
les conventions du standard SQL pour les codes SQLSTATE .
Les applications qui souhaitent connatre la condition d'erreur survenue peuvent tester le code d'erreur plutt que rcuprer le message d'erreur textuel. Les codes d'erreurs sont moins sujets changement au fil des versions de PostgreSQL et ne dpendent pas
de la localisation des messages d'erreur. Seuls certains codes d'erreur produits par PostgreSQL sont dfinis par le standard
SQL ; divers codes d'erreur supplmentaires, pour des conditions non dfinies par le standard, ont t invents ou emprunts
d'autres bases de donnes.
Comme le prconise le standard, les deux premiers caractres d'un code d'erreur dfinissent la classe d'erreurs, les trois derniers indiquent la condition spcifique l'intrieur de cette classe. Ainsi, une application qui ne reconnat pas le code d'erreur spcifique
peut toujours agir en fonction de la classe de l'erreur.
Tableau A.1, Codes d'erreur de PostgreSQL liste tous les codes d'erreurs dfinis dans PostgreSQL 9.1.14. (Certains ne
sont pas rellement utiliss mais sont dfinis par le standard SQL.) Les classes d'erreurs sont aussi affiches. Pour chaque classe
d'erreur, il y a un code d'erreur standard dont les trois derniers caractres sont 000. Ce code n'est utilis que pour les conditions d'erreurs de cette classe qui ne possdent pas de code plus spcifique.
Les symboles affiches dans la colonne Nom de condition sont aussi le nom de la condition utiliser dans PL/pgSQL. Les
noms de conditions peuvent tre crits en minuscule ou en majuscule. Notez que PL/pgSQL ne fait pas la distinction entre avertissement et erreur au niveau des noms des conditions ; il s'agit des classes 00, 01 et 02.
Tableau A.1. Codes d'erreur de PostgreSQL

Code erreur

Nom de condition

Class 00 -- Succs de l'opration


00000

successful_completion

Class 01 -- Avertissement
01000

warning

0100C

dynamic_result_sets_returned

01008

implicit_zero_bit_padding

01003

null_value_eliminated_in_set_function

01007

privilege_not_granted

01006

privilege_not_revoked

01004

string_data_right_truncation

01P01

deprecated_feature

Class 02 -- Pas de donnes (galement une classe d'avertissement selon le standard SQL)
02000

no_data

02001

no_additional_dynamic_result_sets_returned

Class 03 -- Instruction SQL pas encore termine


03000

sql_statement_not_yet_complete

Class 08 -- Problme de connexion


08000

connection_exception

08003

connection_does_not_exist

08006

connection_failure

08001

sqlclient_unable_to_establish_sqlconnection

08004

sqlserver_rejected_establishment_of_sqlconnection

08007

transaction_resolution_unknown

08P01

protocol_violation

Class 09 -- Problme d'action dclenche


09000

triggered_action_exception
1351

Codes d'erreurs de PostgreSQL

Code erreur

Nom de condition

Class 0A -- Fonctionnalit non supporte


0A000

feature_not_supported

Class 0B -- Initialisation de transaction invalide


0B000

invalid_transaction_initiation

Class 0F -- Problme de pointeur (Locator)


0F000

locator_exception

0F001

invalid_locator_specification

Class 0L -- Granteur invalide


0L000

invalid_grantor

0LP01

invalid_grant_operation

Class 0P -- Spcification de rle invalide


0P000

invalid_role_specification

Class 20 -- Cas non trouv


20000

case_not_found

Class 21 -- Violation de cardinalit


21000

cardinality_violation

Class 22 -- Problme de donnes


22000

data_exception

2202E

array_subscript_error

22021

character_not_in_repertoire

22008

datetime_field_overflow

22012

division_by_zero

22005

error_in_assignment

2200B

escape_character_conflict

22022

indicator_overflow

22015

interval_field_overflow

2201E

invalid_argument_for_logarithm

22014

invalid_argument_for_ntile_function

22016

invalid_argument_for_nth_value_function

2201F

invalid_argument_for_power_function

2201G

invalid_argument_for_width_bucket_function

22018

invalid_character_value_for_cast

22007

invalid_datetime_format

22019

invalid_escape_character

2200D

invalid_escape_octet

22025

invalid_escape_sequence

22P06

nonstandard_use_of_escape_character

22010

invalid_indicator_parameter_value

22023

invalid_parameter_value

2201B

invalid_regular_expression

2201W

invalid_row_count_in_limit_clause

2201X

invalid_row_count_in_result_offset_clause

22009

invalid_time_zone_displacement_value

2200C

invalid_use_of_escape_character
1352

Codes d'erreurs de PostgreSQL

Code erreur

Nom de condition

2200G

most_specific_type_mismatch

22004

null_value_not_allowed

22002

null_value_no_indicator_parameter

22003

numeric_value_out_of_range

22026

string_data_length_mismatch

22001

string_data_right_truncation

22011

substring_error

22027

trim_error

22024

unterminated_c_string

2200F

zero_length_character_string

22P01

floating_point_exception

22P02

invalid_text_representation

22P03

invalid_binary_representation

22P04

bad_copy_file_format

22P05

untranslatable_character

2200L

not_an_xml_document

2200M

invalid_xml_document

2200N

invalid_xml_content

2200S

invalid_xml_comment

2200T

invalid_xml_processing_instruction

Class 23 -- Violation de contrainte d'intgrit


23000

integrity_constraint_violation

23001

restrict_violation

23502

not_null_violation

23503

foreign_key_violation

23505

unique_violation

23514

check_violation

23P01

exclusion_violation

Class 24 -- tat de curseur invalide


24000

invalid_cursor_state

Class 25 -- tat de transaction invalide


25000

invalid_transaction_state

25001

active_sql_transaction

25002

branch_transaction_already_active

25008

held_cursor_requires_same_isolation_level

25003

inappropriate_access_mode_for_branch_transaction

25004

inappropriate_isolation_level_for_branch_transaction

25005

no_active_sql_transaction_for_branch_transaction

25006

read_only_sql_transaction

25007

schema_and_data_statement_mixing_not_supported

25P01

no_active_sql_transaction

25P02

in_failed_sql_transaction

Class 26 -- Nom d'instruction SQL invalide


26000

invalid_sql_statement_name
1353

Codes d'erreurs de PostgreSQL

Code erreur

Nom de condition

Class 27 -- Violation de modification de donne dclenche


27000

triggered_data_change_violation

Class 28 -- Spcification d'autorisation invalide


28000

invalid_authorization_specification

28P01

invalid_password

Class 2B -- Descripteurs de privilge dpendant toujours existant


2B000

dependent_privilege_descriptors_still_exist

2BP01

dependent_objects_still_exist

Class 2D -- Fin de transaction invalide


2D000

invalid_transaction_termination

Class 2F -- Exception dans une routine SQL


2F000

sql_routine_exception

2F005

function_executed_no_return_statement

2F002

modifying_sql_data_not_permitted

2F003

prohibited_sql_statement_attempted

2F004

reading_sql_data_not_permitted

Class 34 -- Nom de curseur invalide


34000

invalid_cursor_name

Class 38 -- Exception de routine externe


38000

external_routine_exception

38001

containing_sql_not_permitted

38002

modifying_sql_data_not_permitted

38003

prohibited_sql_statement_attempted

38004

reading_sql_data_not_permitted

Class 39 -- Exception dans l'appel d'une routine externe


39000

external_routine_invocation_exception

39001

invalid_sqlstate_returned

39004

null_value_not_allowed

39P01

trigger_protocol_violated

39P02

srf_protocol_violated

Class 3B -- Exception dans un point de retournement


3B000

savepoint_exception

3B001

invalid_savepoint_specification

Class 3D -- Nom de catalogue invalide


3D000

invalid_catalog_name

Class 3F -- Nom de schma invalide


3F000

invalid_schema_name

Class 40 -- Annulation de transaction


40000

transaction_rollback

40002

transaction_integrity_constraint_violation

40001

serialization_failure

40003

statement_completion_unknown

40P01

deadlock_detected

Class 42 -- Erreur de syntaxe ou violation de rgle d'accs


1354

Codes d'erreurs de PostgreSQL

Code erreur

Nom de condition

42000

syntax_error_or_access_rule_violation

42601

syntax_error

42501

insufficient_privilege

42846

cannot_coerce

42803

grouping_error

42P20

windowing_error

42P19

invalid_recursion

42830

invalid_foreign_key

42602

invalid_name

42622

name_too_long

42939

reserved_name

42804

datatype_mismatch

42P18

indeterminate_datatype

42P21

collation_mismatch

42P22

indeterminate_collation

42809

wrong_object_type

42703

undefined_column

42883

undefined_function

42P01

undefined_table

42P02

undefined_parameter

42704

undefined_object

42701

duplicate_column

42P03

duplicate_cursor

42P04

duplicate_database

42723

duplicate_function

42P05

duplicate_prepared_statement

42P06

duplicate_schema

42P07

duplicate_table

42712

duplicate_alias

42710

duplicate_object

42702

ambiguous_column

42725

ambiguous_function

42P08

ambiguous_parameter

42P09

ambiguous_alias

42P10

invalid_column_reference

42611

invalid_column_definition

42P11

invalid_cursor_definition

42P12

invalid_database_definition

42P13

invalid_function_definition

42P14

invalid_prepared_statement_definition

42P15

invalid_schema_definition

42P16

invalid_table_definition

42P17

invalid_object_definition

Class 44 -- Violation de WITH CHECK OPTION


1355

Codes d'erreurs de PostgreSQL

Code erreur

Nom de condition

44000

with_check_option_violation

Class 53 -- Ressources insuffisantes


53000

insufficient_resources

53100

disk_full

53200

out_of_memory

53300

too_many_connections

Class 54 -- Limite du programme dpasse


54000

program_limit_exceeded

54001

statement_too_complex

54011

too_many_columns

54023

too_many_arguments

Class 55 -- L'objet n'est pas l'tat prrequis


55000

object_not_in_prerequisite_state

55006

object_in_use

55P02

cant_change_runtime_param

55P03

lock_not_available

Class 57 -- Intervention d'un oprateur


57000

operator_intervention

57014

query_canceled

57P01

admin_shutdown

57P02

crash_shutdown

57P03

cannot_connect_now

57P04

database_dropped

Class 58 -- Erreur systme (erreurs externes PostgreSQL)


58030

io_error

58P01

undefined_file

58P02

duplicate_file

Class F0 -- Erreur dans le fichier de configuration


F0000

config_file_error

F0001

lock_file_exists

Class HV -- Erreur Foreign Data Wrapper (SQL/MED)


HV000

fdw_error

HV005

fdw_column_name_not_found

HV002

fdw_dynamic_parameter_value_needed

HV010

fdw_function_sequence_error

HV021

fdw_inconsistent_descriptor_information

HV024

fdw_invalid_attribute_value

HV007

fdw_invalid_column_name

HV008

fdw_invalid_column_number

HV004

fdw_invalid_data_type

HV006

fdw_invalid_data_type_descriptors

HV091

fdw_invalid_descriptor_field_identifier

HV00B

fdw_invalid_handle

HV00C

fdw_invalid_option_index
1356

Codes d'erreurs de PostgreSQL

Code erreur

Nom de condition

HV00D

fdw_invalid_option_name

HV090

fdw_invalid_string_length_or_buffer_length

HV00A

fdw_invalid_string_format

HV009

fdw_invalid_use_of_null_pointer

HV014

fdw_too_many_handles

HV001

fdw_out_of_memory

HV00P

fdw_no_schemas

HV00J

fdw_option_name_not_found

HV00K

fdw_reply_handle

HV00Q

fdw_schema_not_found

HV00R

fdw_table_not_found

HV00L

fdw_unable_to_create_execution

HV00M

fdw_unable_to_create_reply

HV00N

fdw_unable_to_establish_connection

Class P0 -- Erreur PL/pgSQL


P0000

plpgsql_error

P0001

raise_exception

P0002

no_data_found

P0003

too_many_rows

Class XX -- Erreur interne


XX000

internal_error

XX001

data_corrupted

XX002

index_corrupted

1357

Annexe B. Support de date/heure


PostgreSQL utilise un analyseur heuristique interne pour le support des dates/heures saisies. Les dates et heures, saisies sous la
forme de chanes de caractres, sont dcoupes en champs distincts aprs dtermination du type d'information contenue dans
chaque champ. Chaque champ est interpret ; une valeur peut lui tre affecte, il peut tre ignor ou encore tre rejet. Le parseur
contient des tables de recherche internes pour tous les champs textuels y compris les mois, les jours de la semaine et les fuseaux
horaires.
Cette annexe dcrit le contenu des tables de correspondance et les mthodes utilises par le parseur pour dcoder les dates et
heures.

B.1. Interprtation des Date/Heure saisies


Les entres de type date/heure sont toutes dcodes en utilisant le processus suivant.
1.

2.

3.

Diviser la chane saisie en lexmes et catgoriser les lexmes en chanes, heures, fuseaux horaires et nombres.
a.

Si le lexme numrique contient un double-point (:), c'est une chane de type heure. On inclut tous les chiffres et
double-points qui suivent.

b.

Si le lexme numrique contient un tiret (-), une barre oblique (/) ou au moins deux points (.), c'est une chane de type
date qui contient peut-tre un mois sous forme textuelle. Si un lexme de date a dj t reconnu, il est alors interprt
comme un nom de fuseau horaire (par exemple America/New_York).

c.

Si le lexme n'est que numrique alors il s'agit soit d'un champ simple soit d'une date concatne ISO 8601 (19990113
pour le 13 janvier 1999, par exemple) ou d'une heure concatne ISO 8601 (141516 pour 14:15:16, par exemple).

d.

Si le lexme dbute par le signe plus (+) ou le signe moins (-), alors il s'agit soit d'un fuseau horaire numrique, soit
d'un champ spcial.

Si le lexme est une chane texte, le comparer avec les diffrentes chanes possibles :
a.

Faire une recherche binaire dans la table pour vrifier si le lexme est une abrviation de fuseau horaire.

b.

S'il n'est pas trouv, une recherche binaire est effectue dans la table pour vrifier si le lexme est une chane spciale
(today, par exemple), un jour (Thursday, par exemple), un mois (January, par exemple), ou du bruit (at, on, par
exemple).

c.

Si le lexme n'est toujours pas trouv, une erreur est leve.

Lorsque le lexme est un nombre ou un champ de nombre :


a.

S'il y a huit ou six chiffres, et qu'aucun autre champ date n'a t lu, alors il est interprt comme une date concatne
(19990118 ou 990118, par exemple). L'interprtation est AAAAMMJJ ou AAMMJJ.

b.

Si le lexme est compos de trois chiffres et qu'une anne est dj lue, alors il est interprt comme un jour de l'anne.

c.

Si quatre ou six chiffres et une anne sont dj lus, alors il est interprt comme une heure (HHMM ou HHMMSS).

d.

Si le lexme est compos de trois chiffres ou plus et qu'aucun champ date n'a t trouv, il est interprt comme une anne (cela impose l'ordre aa-mm-jj des champs dates restants).

e.

Dans tous les autres cas, le champ date est suppos suivre l'ordre impos par le paramtre datestyle : mm-jj-aa, jjmm-aa, ou aa-mm-jj. Si un champ jour ou mois est en dehors des limites, une erreur est leve.

4.

Si BC est indiqu, le signe de l'anne est invers et un est ajout pour le stockage interne. (Il n'y a pas d'anne zro dans le calendrier Grgorien, alors numriquement 1 BC devient l'anne zro.)

5.

Si BC n'est pas indiqu et que le champ anne est compos de deux chiffres, alors l'anne est ajuste quatre chiffres. Si le
champ vaut moins que 70, alors on ajoute 2000, sinon 1900.

Astuce
Les annes du calendrier Grgorien AD 1-99 peuvent tre saisie avec 4 chiffres, deux zros en tte (0099
1358

Support de date/heure

pour AD 99, par exemple).

B.2. Mots cls Date/Heure


Tableau B.1, Noms de mois prsente les lexmes reconnus commme des noms de mois.
Tableau B.1. Noms de mois

Mois

Abrviations

January (Janvier)

Jan

February (Fvrier)

Feb

March (Mars)

Mar

April (Avril)

Apr

May (Mai)
June (Juin)

Jun

July (Juillet)

Jul

August (Aot)

Aug

September (Septembre)

Sep, Sept

October (Octobre)

Oct

November (Novembre)

Nov

December (Dcembre)

Dec

Tableau B.2, Noms des jours de la semaine prsente les lexmes reconnus comme des noms de jours de la semaine.
Tableau B.2. Noms des jours de la semaine

Jour

Abrviation

Sunday (Dimanche)

Sun

Monday (Lundi)

Mon

Tuesday (Mardi)

Tue, Tues

Wednesday (Mercredi)

Wed, Weds

Thursday (Jeudi)

Thu, Thur, Thurs

Friday (Vendredi)

Fri

Saturday (Samedi)

Sat

Tableau B.3, Modificateurs de Champs Date/Heure prsente les lexmes utiliss par divers modificateurs.
Tableau B.3. Modificateurs de Champs Date/Heure

Identifiant

Description

AM

L'heure prcde 12:00

AT

Ignor

JULIAN, JD, J

Le champ suivant est un jour du calendrier Julien

ON

Ignor

PM

L'heure suit 12:00

Le champ suivant est une heure

1359

Support de date/heure

B.3. Fichiers de configuration date/heure


Comme il n'existe pas de rel standard des abrviations de fuseaux horaire, PostgreSQL permet de personnaliser l'ensemble des
abrviations acceptes par le serveur. Le paramtre d'excution timezone_abbreviations dtermine l'ensemble des abrviations actives. Bien que tout utilisateur de la base puisse modifier ce paramtre, les valeurs possibles sont sous le contrle de
l'administrateur de bases de donnes -- ce sont en fait les noms des fichiers de configuration stocks dans
.../share/timezonesets/ du rpertoire d'installation. En ajoutant ou en modifiant les fichiers de ce rpertoire,
l'administrateur peut dfinir les rgles d'abrviation des fuseaux horaires.
timezone_abbreviations peut prendre tout nom de fichier situ dans .../share/timezonesets/, sous rserve que
ce nom soit purement alphabtique. (L'interdiction de caractres non alphabtique dans timezone_abbreviations empche
la lecture de fichiers en dehors du rpertoire prvu et celle de fichiers de sauvegarde ou autre.)
Un fichier d'abrviation de zones horaires peut contenir des lignes blanches et des commentaires (commenant avec un #). Les
autres lignes doivent suivre l'un des formats suivants :
nom_fuseau_horaire dcalage
nom_fuseau_horaire dcalage D
@INCLUDE nom_fichier
@OVERRIDE
Un nom_fuseau_horaire n'est que l'abrviation dfinie. Le dcalage est le dcalage en secondes partir d'UTC, une valeur positive signifiant l'est de Greenwich, une valeur ngative l'ouest. Ainsi, -18000 reprsente cinq heures l'ouest de Greenwich, soit l'heure standard de la cte ouest nord amricaine. D indique que le nom du fuseau reprsente une heure soumise des
rgles de changement d'heure plutt que l'heure standard. Comme tous les dcalages de fuseau horaire ont des limites de 15 minutes, le nombre de secondes doit tre un multiple de 900.
La syntaxe @INCLUDE autorise l'inclusion d'autres fichiers du rpertoire .../share/timezonesets/. Les inclusions
peuvent tre imbriques jusqu' une certaine profondeur.
La syntaxe @OVERRIDE indique que les entres suivantes du fichier peuvent surcharger les entres prcdentes (c'est--dire des
entres obtenues partir de fichiers inclus). Sans cela, les dfinitions en conflit au sein d'une mme abrviation lvent une erreur.
Dans une installation non modifie, le fichier Default contient toutes les abrviations de fuseaux horaire, sans conflit, pour la
quasi-totalit du monde. Les fichiers supplmentaires Australia et India sont fournis pour ces rgions : ces fichiers incluent
le fichier Default puis ajoutent ou modifient les fuseaux horaires si ncessaire.
Pour des raisons de rfrence, une installation standard contient aussi des fichiers Africa.txt, America.txt, etc. qui
contiennent des informations sur les abrviations connues et utilises en accord avec la base de donnes de fuseaux horaires zoneinfo. Les dfinitions des noms de zone trouves dans ces fichiers peuvent tre copies et colles dans un fichier de configuration personnalis si ncessaire. Il ne peut pas tre fait directement rfrence ces fichiers dans le paramtre timezone_abbreviations cause du point dans leur nom.

Note
Si une erreur survient lors de la lecture des jeux de donnes de fuseaux horaires, aucune nouvelle valeur n'est accepte mais les anciennes sont conserves. Si l'erreur survient au dmarrage de la base, celui-ci choue.

Attention
Les abrviations de fuseau horaire dfinies dans le fichier de configuration surchargent les informations sans fuseau
dfinies nativement dans PostgreSQL. Par exemple, le fichier de configuration Australia dfinit SAT (South
Australian Standard Time, soit l'heure standard pour l'Australie du sud). Si ce fichier est actif, SAT n'est plus reconnu comme abrviation de samedi (Saturday).

Attention
Si les fichiers de .../share/timezonesets/ sont modifis, il revient l'utilisateur de procder leur sauvegarde -- une sauvegarde normale de base n'inclut pas ce rpertoire.

B.4. Histoire des units


Le calendrier Julien a t introduit par Julius Caesar en -45. Il tait couramment utilis dans le monde occidental jusqu'en l'an
1360

Support de date/heure

1582, date laquelle des pays ont commenc se convertir au calendrier Grgorien. Dans le calendrier Julien, l'anne tropicale est
arrondie 365 jours 1/4, soit 365,25 jours. Cela conduit une erreur de l'ordre d'un jour tous les 128 ans.
L'erreur grandissante du calendrier poussa le Pape Gregoire XIII a rform le calendrier en accord avec les instructions du Concile
de Trent. Dans le calendrier Grgorien, l'anne tropicale est arrondie 365 + 97/400 jours, soit 365,2425 jours. Il faut donc peu
prs 3300 ans pour que l'anne tropicale subissent un dcalage d'un an dans le calendrier Grgorien.
L'arrondi 365+97/400 est obtenu l'aide de 97 annes bissextiles tous les 400 ans. Les rgles suivantes sont utilises :
toute anne divisible par 4 est bissextile ;
cependant, toute anne divisible par 100 n'est pas bissextile ;
cependant, toute annes divisible par 400 est bissextile.
1700, 1800, 1900, 2100 et 2200 ne sont donc pas des annes bissextiles. 1600, 2000 et 2400 si. Par opposition, dans l'ancien calendrier Julien, toutes les annes divisibles par 4 sont bissextiles.
En fvrier 1582, le pape dcrta que 10 jours devaient tre supprims du mois d'octobre 1582, le 15 octobre devant ainsi arriver
aprs le 4 octobre. Cela a t appliqu en Italie, Pologne, Portugal et Espagne. Les autres pays catholiques ont suivi peu aprs,
mais les pays protestants ont t plus rtifs et les contres orthodoxes grques n'ont pas effctu le changement avant le dbut du
20me sicle. La rforme a t applique par la Grande Bretagne et ses colonies (y compris les actuels Etats-Unis) en 1752. Donc
le 2 septembre 1752 a t suivi du 14 septembre 1752. C'est pour cela que la commande cal produit la sortie suivante :
$ cal 9 1752
septembre 1752
di lu ma me je ve
1 2 14 15
17 18 19 20 21 22
24 25 26 27 28 29

sa
16
23
30

Le standard SQL stipule que dans la dfinition d'un libell date/heure (datetime literal), les valeurs date/heure sont
contraintes par les rgles naturelles des dates et heures imposes par le calendrier Grgorien . Les dates comprises entre le 5 octobre 1582 et le 14 octobre 1582, bien qu'limines dans plusieurs pays par ordre du Pape, sont conformes aux rgles naturelles et sont donc des dates valables. PostgreSQL suit le standard SQL en comptant les dates exclusivement dans le calendrier grgorien, mme pour les annes o ce calendrier n'existait pas encore.
Divers calendriers ont t develops dans diffrentes parties du monde, la plupart prcde le systme Grgorien. Par exemple, les
dbuts du calendrier chinois peuvent tre valus aux alentours du 14me sicle avant J.-C. La lgende veut que l'empereur
Huangdi inventa le calendrier en 2637 avant J-C. La Rpublique de Chine utilise le calendrier Grgorien pour les besoins civils.
Le calendrier chinois est utilis pour dterminer les festivals.
La date Julien n'a pas de relation avec le calendrier Julien . Le systme de date Julien a t invent par le prcepteur
franais Joseph Justus Scaliger (1540-1609) et tient probablement son nom du pre de Scaliger, le prcepteur italien Julius Caesar
Scaliger (1484-1558). Dans le systme de date Julien, chaque jour est un nombre squentiel, commenant partir de JD 0, appel
quelque fois la date Julien. JD 0 correspond au 1er janvier 4713 avant JC dans le calendrier Julien, ou au 24 novembre 4714 avant
JC dans le calendrier grgorien. Le comptage de la date Julien est le plus souvent utilis par les astronomes pour donner un nom
leurs observations, et du coup une date part de midi UTC jusqu'au prochain midi UTC, plutt que de minuit minuit : JD 0 dsigne les 24 heures de midi UTC le 1er janvier 4713 avant JC jusqu'au midi UTC du 2 janvier 4713 avant JC.
Bien que PostgreSQL accepte la saisie et l'affichage des dates en notation de date Julien (et les utilise aussi pour quelques calculs internes de date et heure), il n'utilise pas le coup des dates de midi midi. PostgreSQL traite une date Julien comme allant
de minuit minuit.

1361

Annexe C. Mots-cl SQL


La Tableau C.1, Mots-cl SQL liste tous les lments qui sont des mots-cl dans le standard SQL et dans PostgreSQL
9.1.14. Des informations sous-jacentes peuvent tre trouves dans Section 4.1.1, identificateurs et mots cls .
SQL distingue les mots-cl rservs et non rservs. Selon le standard, les mots-cl rservs sont rellement les seuls mots-cl ; ils
ne sont jamais autoriss comme identifiants. Les mots-cl non rservs ont seulement un sens spcial dans certains contextes et
peuvent tre utiliss comme identifiants dans d'autres contextes. La plupart des mots-cl non rservs sont en fait les noms des
tables et des fonctions prdfinies spcifis par SQL. Le concept de mots-cl non rservs existe seulement pour indiquer que certains sens prdfinis sont attachs un mot dans certains contextes.
Dans l'analyseur de PostgreSQL, la vie est un peu plus complique. Il y a diffrentes classes d'lments allant de ceux que l'on
ne peut jamais utiliser comme identifiants ceux qui n'ont absolument aucun statut spcial dans l'analyseur par rapport un identifiant ordinaire (c'est gnralement le cas pour les fonctions spcifies par SQL). Mme les mots-cl rservs ne sont pas compltement rservs dans PostgreSQL et peuvent tre utiliss comme noms des colonnes (par exemple, SELECT 55 AS CHECK,
mme si CHECK est un mot-cl).
Dans Tableau C.1, Mots-cl SQL , dans la colonne pour PostgreSQL, nous classons comme non rserv les mots-cl qui
sont explicitement connus par l'analyseur mais qui sont autoriss en tant que noms de colonnes ou de tables. Certains mots-cl qui
sont non rservs et qui ne peuvent pas tre utiliss comme un nom de fonction ou un type de donnes sont marqus en consquence. (La plupart des mots reprsentent des fonctions prdfinies ou des types de donnes avec une syntaxe spciale. La fonction ou le type est toujours disponible mais il ne peut pas tre redfini par un utilisateur.) Les rservs sont des lments qui ne
sont pas autoriss en tant que noms de colonne ou de table. Certains mots-cl rservs sont autoriss comme noms pour les fonctions et les types de donnes ; cela est galement montr dans le tableau. Dans le cas contraire, un mot cl rserv est seulement
autoris dans un nom de label AS d'une colonne.
En rgle gnrale, si vous avez des erreurs de la part de l'analyseur pour des commandes qui contiennent un des mots-cls lists
comme identifiants, vous devriez essayer de mettre entre guillemets l'identifiant pour voir si le problme disparait.
Il est important de comprendre avant d'tudier la Tableau C.1, Mots-cl SQL que le fait qu'un mot-cl ne soit pas rserv dans
PostgreSQL ne signifie pas que la fonctionnalit en rapport avec ce mot n'est pas implmente. Rciproquement, la prsence
d'un mot-cl n'indique pas l'existance d'une fonctionnalit.
Tableau C.1. Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

non rserv

non rserv

ABS

rserv

rserv

non rserv

ABSENT

non rserv
non rserv

rserv

rserv

non rserv

non rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv
rserv

A
ABORT

non rserv

ACCESS

non rserv

non rserv

ACCORDING

non rserv
non rserv

ADA
ADD

non rserv

non rserv

non rserv

rserv

ADMIN

non rserv

non rserv

non rserv

rserv

AFTER

non rserv

non rserv

non rserv

rserv

AGGREGATE

non rserv

rserv

ALIAS
ALL

SQL-92

non rserv

ABSOLUTE

ACTION

SQL:1999

rserv
rserv

ALLOCATE

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

ALSO

non rserv

ALTER

non rserv

rserv

rserv

ALWAYS

non rserv

non rserv

non rserv

ANALYSE

rserv
1362

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

SQL-92

ANALYZE

rserv

AND

rserv

rserv

rserv

rserv

rserv

ANY

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

ARE
ARRAY

rserv

ARRAY_AGG

rserv

AS

rserv

rserv

rserv

rserv

rserv

ASC

rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

non rserv

ASENSITIVE
ASSERTION

non rserv

non rserv

non rserv

rserv

ASSIGNMENT

non rserv

non rserv

non rserv

non rserv

ASYMMETRIC

rserv

rserv

rserv

non rserv

AT

non rserv

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv

non rserv

ATOMIC
ATTRIBUTE

non rserv

ATTRIBUTES
AUTHORIZATION

rserv

rserv (peut tre une rserv


fonction ou un type)

rserv

rserv

rserv

rserv

rserv

non rserv

rserv

non rserv

non rserv

AVG
BACKWARD

rserv

non rserv

BASE64
BEFORE

non rserv

non rserv

non rserv

rserv

BEGIN

non rserv

rserv

rserv

rserv

rserv

non rserv

non rserv
non rserv

rserv

BERNOULLI
BETWEEN

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

BIGINT

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

BINARY

rserv (peut tre une rserv


fonction ou un type)

rserv

BIT

non rserv (ne peut


pas tre une fonction
ou un type)

rserv
rserv

BITVAR

rserv

non rserv

BIT_LENGTH

non rserv

BLOB

rserv

rserv

BLOCKED

non rserv

non rserv

BOM

non rserv

rserv

rserv

BOOLEAN

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

BOTH

rserv

rserv

rserv

rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv

BREADTH
BY

non rserv

C
1363

rserv

Mots-cl SQL

Mot-cl

PostgreSQL

CACHE

non rserv

CALL
CALLED

non rserv

CARDINALITY

SQL:2008

SQL:2003

SQL:1999

rserv

rserv

rserv

rserv

rserv

non rserv

rserv

rserv

non rserv

SQL-92

CASCADE

non rserv

non rserv

non rserv

rserv

rserv

CASCADED

non rserv

rserv

rserv

rserv

rserv

CASE

rserv

rserv

rserv

rserv

rserv

CAST

rserv

rserv

rserv

rserv

rserv

CATALOG

non rserv

non rserv

non rserv

rserv

rserv

CATALOG_NAME

non rserv

non rserv

non rserv

non rserv

CEIL

rserv

rserv

CEILING

rserv

rserv

non rserv

CHAIN

non rserv

non rserv

non rserv

CHAR

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

CHARACTER

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

CHARACTERISTICS

non rserv

non rserv

non rserv

CHARACTERS

non rserv

non rserv

CHARACTER_LENGTH

rserv

rserv

non rserv

rserv

CHARACTER_SET_CATALOG

non rserv

non rserv

non rserv

non rserv

CHARACTER_SET_NAME

non rserv

non rserv

non rserv

non rserv

CHARACTER_SET_SCHEMA

non rserv

non rserv

non rserv

non rserv

CHAR_LENGTH

rserv

rserv

non rserv

rserv

rserv

rserv

rserv

rserv

CHECK

rserv

CHECKED

non rserv

CHECKPOINT

non rserv

CLASS

non rserv

rserv

CLASS_ORIGIN

non rserv

non rserv

non rserv

CLOB

rserv

rserv

rserv

non rserv

CLOSE

non rserv

rserv

rserv

rserv

rserv

CLUSTER

non rserv

COALESCE

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

non rserv

rserv

COBOL

non rserv

non rserv

non rserv

non rserv

COLLATE

rserv

rserv

rserv

rserv

rserv

COLLATION

non rserv

non rserv

non rserv

rserv

rserv

COLLATION_CATALOG

non rserv

non rserv

non rserv

non rserv

COLLATION_NAME

non rserv

non rserv

non rserv

non rserv

COLLATION_SCHEMA

non rserv

non rserv

non rserv

non rserv

COLLECT

rserv

rserv

rserv

rserv

rserv

rserv

COLUMN

rserv

COLUMNS

non rserv
1364

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

SQL-92

COLUMN_NAME

non rserv

non rserv

non rserv

non rserv

COMMAND_FUNCTION

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

COMMAND_FUNCTION_CODE
COMMENT

non rserv

COMMENTS

non rserv

COMMIT

non rserv

rserv

rserv

rserv

rserv

COMMITTED

non rserv

non rserv

non rserv

non rserv

non rserv

COMPLETION
CONCURRENTLY

rserv
non rserv (peut tre
une fonction ou un
type)

CONDITION
CONDITION_NUMBER
CONFIGURATION

rserv

non rserv

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv

non rserv

CONNECT
CONNECTION

rserv

non rserv

CONNECTION_NAME
CONSTRAINT

rserv

rserv

rserv

rserv

rserv

CONSTRAINTS

non rserv

non rserv

non rserv

rserv

rserv

CONSTRAINT_CATALOG

non rserv

non rserv

non rserv

non rserv

CONSTRAINT_NAME

non rserv

non rserv

non rserv

non rserv

CONSTRAINT_SCHEMA

non rserv

non rserv

non rserv

non rserv

CONSTRUCTOR

non rserv

non rserv

rserv

CONTAINS

non rserv

non rserv

non rserv

CONTENT

non rserv

non rserv

non rserv

CONTINUE

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

rserv

CORR

rserv

rserv

CORRESPONDING

rserv

COUNT
COVAR_POP
COVAR_SAMP

CONTROL
CONVERSION

COST

rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

non rserv

rserv

rserv

rserv

rserv

rserv

non rserv

CONVERT
COPY

rserv

non rserv

non rserv

CREATE

rserv

rserv

rserv

rserv

rserv

CROSS

rserv (peut tre une rserv


fonction ou un type)

rserv

rserv

rserv

CSV

non rserv
rserv

CUBE

rserv

rserv

CUME_DIST

rserv

rserv
rserv

rserv

rserv

rserv

rserv

rserv

CURRENT

non rserv

rserv

CURRENT_CATALOG

rserv

rserv

CURRENT_DATE

rserv

rserv
1365

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

CURRENT_DEFAULT_TRANSFORM_GROUP

rserv

rserv

CURRENT_PATH

rserv

rserv

rserv

rserv

rserv

rserv

SQL-92

CURRENT_ROLE

rserv

CURRENT_SCHEMA

rserv (peut tre une rserv


fonction ou un type)

CURRENT_TIME

rserv

rserv

rserv

rserv

rserv

CURRENT_TIMESTAMP

rserv

rserv

rserv

rserv

rserv

rserv

rserv

CURRENT_TRANSFORM_GROUP_FOR_TYPE
CURRENT_USER

rserv

rserv

rserv

rserv

rserv

CURSOR

non rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv

CURSOR_NAME
CYCLE

non rserv

rserv

rserv

rserv

DATA

non rserv

non rserv

non rserv

rserv

non rserv

DATABASE

non rserv

DATALINK

rserv

rserv

DATE

rserv

rserv

rserv

rserv

DATETIME_INTERVAL_CODE

non rserv

non rserv

non rserv

non rserv

DATETIME_INTERVAL_PRECISION

non rserv

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

DAY

non rserv

DB
DEALLOCATE

non rserv

rserv

rserv

rserv

rserv

DEC

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

DECIMAL

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

DECLARE

non rserv

rserv

rserv

rserv

rserv

DEFAULT

rserv

rserv

rserv

rserv

rserv

DEFAULTS

non rserv

non rserv

non rserv

DEFERRABLE

rserv

non rserv

non rserv

rserv

rserv

DEFERRED

non rserv

non rserv

non rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

rserv

DENSE_RANK

rserv

rserv

DEPTH

non rserv

non rserv

rserv

DEREF

rserv

rserv

rserv

DERIVED

non rserv

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

DEFINED
DEFINER

non rserv

DEGREE
DELETE

non rserv

DELIMITER

non rserv

DELIMITERS

non rserv

DESC

rserv

DESCRIBE
1366

rserv

rserv

Mots-cl SQL

Mot-cl

PostgreSQL

DESCRIPTOR

SQL:2008

SQL:2003

SQL:1999

SQL-92

non rserv

non rserv

rserv

rserv

DESTROY

rserv

DESTRUCTOR

rserv

DETERMINISTIC

rserv

rserv

rserv

DIAGNOSTICS

non rserv

non rserv

rserv

DICTIONARY

non rserv

DISABLE

non rserv

DISCARD

non rserv

rserv

rserv

DISCONNECT

rserv

rserv

rserv

DISPATCH

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

DLNEWCOPY

rserv

rserv

DLPREVIOUSCOPY

rserv

rserv

DLURLCOMPLETE

rserv

rserv

DLURLCOMPLETEONLY

rserv

rserv

DLURLCOMPLETEWRITE

rserv

rserv

DLURLPATH

rserv

rserv

DLURLPATHONLY

rserv

rserv

DLURLPATHWRITE

rserv

rserv

DLURLSCHEME

rserv

rserv

DLURLSERVER

rserv

rserv

DLVALUE

rserv

rserv

DISTINCT

rserv

rserv

DO

rserv

DOCUMENT

non rserv

non rserv

non rserv

DOMAIN

non rserv

non rserv

non rserv

rserv

rserv

DOUBLE

non rserv

rserv

rserv

rserv

rserv

DROP

non rserv

rserv

rserv

rserv

rserv

DYNAMIC

rserv

rserv

rserv

DYNAMIC_FUNCTION

non rserv

non rserv

non rserv

DYNAMIC_FUNCTION_CODE

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

EACH

non rserv

ELEMENT
ELSE

rserv

EMPTY

non rserv

ENABLE

non rserv

ENCODING

non rserv

ENCRYPTED

non rserv

END

rserv

non rserv

END-EXEC
ENUM

non rserv

EQUALS
ESCAPE

non rserv

EVERY
EXCEPT

non rserv

rserv
1367

rserv
rserv

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

EXCEPTION

SQL:2003

SQL:1999

SQL-92

non rserv

rserv

rserv

EXCLUDE

non rserv

non rserv

non rserv

EXCLUDING

non rserv

non rserv

non rserv

EXCLUSIVE

non rserv
rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

EXEC
EXECUTE

non rserv

EXISTING
EXISTS

non rserv
non rserv (ne peut rserv
pas tre une fonction
ou un type)

rserv

rserv

rserv

EXP

non rserv

rserv

EXPLAIN

non rserv

EXTENSION

non rserv

EXTERNAL

non rserv

rserv

rserv

rserv

rserv

EXTRACT

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

non rserv

rserv

FALSE

rserv

rserv

rserv

rserv

rserv

FAMILY

non rserv

FETCH

rserv

rserv

rserv

rserv

rserv

FILE

non rserv

non rserv

FILTER

rserv

rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

FINAL
FIRST

non rserv

FIRST_VALUE

rserv

FLAG

non rserv

FLOAT

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

FLOOR

rserv

rserv

FOLLOWING

non rserv

non rserv

non rserv

FOR

rserv

rserv

rserv

rserv

rserv

FORCE

non rserv

FOREIGN

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv
rserv

FORTRAN
FORWARD

non rserv

FOUND
FREE
FREEZE

rserv (peut tre une


fonction ou un type)

FROM

rserv

FS
FULL

rserv (peut tre une rserv


fonction ou un type)

rserv

rserv

FUNCTION

non rserv

rserv

rserv

rserv

FUNCTIONS

non rserv
rserv

rserv

FUSION
1368

Mots-cl SQL

Mot-cl

SQL:2008

SQL:2003

SQL:1999

non rserv

non rserv

non rserv

GENERAL

non rserv

non rserv

rserv

GENERATED

non rserv

non rserv

non rserv

GET

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

GO

non rserv

non rserv

rserv

rserv

GOTO

non rserv

non rserv

rserv

rserv
rserv

GLOBAL

PostgreSQL

non rserv

GRANT

rserv

rserv

rserv

rserv

GRANTED

non rserv

non rserv

non rserv

non rserv

GREATEST

non rserv (ne peut


pas tre une fonction
ou un type)

GROUP

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

HEX

non rserv

non rserv

HIERARCHY

non rserv

non rserv

non rserv

rserv

rserv

non rserv

GROUPING
HANDLER

non rserv

HAVING

rserv

HEADER

non rserv

HOLD

non rserv

HOST
HOUR

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

non rserv

IDENTITY

non rserv

IF

non rserv

rserv

IGNORE

non rserv

ILIKE

rserv (peut tre une


fonction ou un type)

IMMEDIATE

non rserv

IMMUTABLE

non rserv

IMPLEMENTATION

rserv

non rserv

non rserv

rserv

non rserv

non rserv

non rserv

rserv

rserv

rserv

non rserv

IMPORT
IN

rserv

rserv

rserv

INCLUDING

non rserv

non rserv

non rserv

INCREMENT

non rserv

non rserv

non rserv

INDENT

rserv

rserv

rserv

rserv

non rserv

INDEX

non rserv

INDEXES

non rserv

INDICATOR

rserv

rserv

INFIX

non rserv

INHERIT

non rserv

INHERITS

non rserv

INITIALIZE
INITIALLY

rserv

rserv

ID

IMPLICIT

SQL-92

rserv
rserv

non rserv
1369

non rserv

rserv

rserv

Mots-cl SQL

Mot-cl

PostgreSQL

INLINE

non rserv

INNER

SQL:2008

SQL:2003

SQL:1999

SQL-92

rserv (peut tre une rserv


fonction ou un type)

rserv

rserv

rserv

INOUT

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

INPUT

non rserv

non rserv

non rserv

rserv

rserv

INSENSITIVE

non rserv

rserv

rserv

non rserv

rserv

INSERT

non rserv

rserv

rserv

rserv

rserv

INSTANCE

non rserv

non rserv

non rserv

INSTANTIABLE

non rserv

non rserv

non rserv

INSTEAD

non rserv

INT

non rserv (ne peut rserv


pas tre une fonction
ou un type)

non rserv
rserv

rserv

rserv

INTEGER

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

rserv

rserv

INTEGRITY

non rserv

non rserv

rserv

rserv

rserv

rserv

INTERVAL

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

INTO

rserv

rserv

rserv

rserv

rserv

INVOKER

non rserv

non rserv

non rserv

non rserv

IS

rserv (peut tre une rserv


fonction ou un type)

rserv

rserv

rserv

ISNULL

rserv (peut tre une


fonction ou un type)

ISOLATION

non rserv

non rserv

rserv

rserv

INTERSECT

rserv

INTERSECTION

non rserv

ITERATE
JOIN

rserv
rserv (peut tre une rserv
fonction ou un type)

K
KEY

rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

KEY_MEMBER

non rserv

non rserv

non rserv

KEY_TYPE

non rserv

non rserv

non rserv

LABEL

non rserv

rserv

rserv

rserv

non rserv

LAG

rserv

LANGUAGE

non rserv

rserv

rserv

rserv

LARGE

non rserv

rserv

rserv

rserv

LAST

non rserv

non rserv

non rserv

rserv

rserv

rserv

LAST_VALUE

rserv

LATERAL

rserv

LC_COLLATE

non rserv

LC_CTYPE

non rserv

LEAD

rserv
1370

rserv
rserv

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

SQL-92

LEADING

rserv

rserv

rserv

rserv

rserv

LEAST

non rserv (ne peut


pas tre une fonction
ou un type)

LEFT

rserv (peut tre une rserv


fonction ou un type)

rserv

rserv

rserv

non rserv

non rserv

non rserv

LENGTH

non rserv

LESS
LEVEL

rserv
non rserv

LIBRARY
LIKE

rserv

rserv

non rserv

non rserv
rserv

rserv

rserv

non rserv

non rserv

rserv

non rserv

non rserv

rserv

rserv

rserv
rserv

LINK
LISTEN

non rserv

rserv (peut tre une rserv


fonction ou un type)

LIKE_REGEX
LIMIT

non rserv

non rserv

LN
LOAD

non rserv

LOCAL

non rserv

rserv

rserv

rserv

LOCALTIME

rserv

rserv

rserv

rserv

LOCALTIMESTAMP

rserv

rserv

rserv

rserv

LOCATION

non rserv

non rserv
non rserv

non rserv

rserv

LOWER

rserv

rserv

non rserv

non rserv

non rserv

non rserv

MAP

non rserv

non rserv

rserv

LOCATOR
LOCK

non rserv

MAPPING

non rserv

non rserv

non rserv

MATCH

non rserv

rserv

rserv

MATCHED

non rserv

non rserv

MAX

rserv

rserv

non rserv

non rserv

MAXVALUE

rserv

non rserv

rserv

rserv

rserv

non rserv

rserv

MAX_CARDINALITY

rserv

MEMBER

rserv

rserv

MERGE

rserv

rserv

MESSAGE_LENGTH

non rserv

non rserv

non rserv

non rserv

MESSAGE_OCTET_LENGTH

non rserv

non rserv

non rserv

non rserv

MESSAGE_TEXT

non rserv

non rserv

non rserv

non rserv

METHOD

rserv

rserv

non rserv

MIN

rserv

rserv

non rserv

rserv

rserv

rserv

MINUTE

non rserv

rserv

rserv

MINVALUE

non rserv

non rserv

non rserv

rserv

rserv

non rserv

rserv

rserv

rserv

MOD
MODE

non rserv

MODIFIES
MODIFY

rserv
1371

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

SQL-92

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv

MULTISET

rserv

rserv

MUMPS

non rserv

non rserv

non rserv

non rserv

MODULE
MONTH

non rserv

MORE
MOVE

non rserv

NAME

non rserv

non rserv

non rserv

non rserv

non rserv

NAMES

non rserv

non rserv

non rserv

rserv

rserv

NAMESPACE

non rserv

NATIONAL

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

NATURAL

rserv (peut tre une rserv


fonction ou un type)

rserv

rserv

rserv

NCHAR

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

NCLOB

rserv

rserv

rserv

NESTING

non rserv

non rserv

NEW

rserv

rserv

rserv

non rserv

non rserv

rserv

rserv

rserv

NEXT

non rserv

NFC

non rserv

NFD

non rserv

NFKC

non rserv

NFKD

non rserv

NIL

non rserv

NO

non rserv

rserv

rserv

rserv

NONE

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

non rserv

non rserv

NORMALIZE
NORMALIZED
NOT

rserv

NOTHING

non rserv

NOTIFY

non rserv

NOTNULL

rserv (peut tre une


fonction ou un type)

NOWAIT

non rserv

NTH_VALUE

rserv

NTILE

rserv

NULL

rserv

NULLABLE
NULLIF

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

NULLS

non rserv

non rserv

non rserv

non rserv

non rserv

NUMBER
1372

Mots-cl SQL

Mot-cl

PostgreSQL

NUMERIC

OBJECT

SQL:2008

SQL:2003

SQL:1999

SQL-92

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

non rserv

non rserv

rserv

non rserv

OCCURRENCES_REGEX

rserv

OCTETS

non rserv

non rserv

OCTET_LENGTH

rserv

rserv

non rserv

rserv

OF

non rserv

rserv

rserv

rserv

rserv

OFF

non rserv

non rserv

non rserv

rserv

OFFSET

rserv

rserv

OIDS

non rserv
rserv

rserv

rserv

OLD
ON

rserv

rserv

rserv

rserv

rserv

ONLY

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

OPEN
OPERATION

rserv

OPERATOR

non rserv

OPTION

non rserv

non rserv

non rserv

rserv

OPTIONS

non rserv

non rserv

non rserv

non rserv

OR

rserv

rserv

rserv

rserv

rserv

ORDER

rserv

rserv

rserv

rserv

rserv

ORDERING

non rserv

non rserv

ORDINALITY

non rserv

non rserv

OTHERS

non rserv

non rserv

rserv

rserv

OUT

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

OUTER

rserv (peut tre une rserv


fonction ou un type)

rserv

rserv

rserv

non rserv

rserv

rserv

rserv

OUTPUT

non rserv

OVER

rserv (peut tre une rserv


fonction ou un type)

rserv

OVERLAPS

rserv (peut tre une rserv


fonction ou un type)

rserv

non rserv

OVERLAY

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

non rserv

non rserv

non rserv

OVERRIDING

non rserv

OWNED

non rserv

OWNER

non rserv

non rserv

PAD

non rserv

non rserv

rserv

PARAMETER

rserv

rserv

rserv

PARAMETERS

rserv

PARAMETER_MODE

non rserv

non rserv

non rserv

PARAMETER_NAME

non rserv

non rserv

non rserv

PARAMETER_ORDINAL_POSITION

non rserv

non rserv

non rserv

1373

rserv

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

PARAMETER_SPECIFIC_CATALOG

non rserv

non rserv

non rserv

PARAMETER_SPECIFIC_NAME

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv
rserv

rserv

non rserv

non rserv

PARAMETER_SPECIFIC_SCHEMA
PARSER

non rserv

PARTIAL

non rserv

non rserv

non rserv

PARTITION

non rserv

rserv

rserv

non rserv

non rserv

PASCAL
PASSING

non rserv

SQL-92

non rserv

PASSTHROUGH

non rserv

non rserv

PATH

non rserv

non rserv

PERCENTILE_CONT

rserv

rserv

PERCENTILE_DISC

rserv

rserv

PERCENT_RANK

rserv

rserv

PERMISSION

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

non rserv

rserv

PASSWORD

non rserv

PLACING

rserv

PLANS

non rserv

PLI
POSITION

non rserv (ne peut rserv


pas tre une fonction
ou un type)

POSITION_REGEX

rserv

rserv

POSTFIX

rserv

POWER

rserv

rserv

non rserv

non rserv

PRECEDING

non rserv

PRECISION

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

PREFIX

rserv

PREORDER

rserv

PREPARE

non rserv

PREPARED

non rserv

PRESERVE
PRIMARY

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

PRIOR

non rserv

non rserv

non rserv

rserv

rserv

PRIVILEGES

non rserv

non rserv

non rserv

rserv

rserv

PROCEDURAL

non rserv

PROCEDURE

non rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

non rserv (ne peut rserv


pas tre une fonction

rserv

rserv

PUBLIC
QUOTE

non rserv

RANGE

non rserv

RANK
READ

non rserv

READS
REAL

1374

rserv

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

non rserv

non rserv

SQL:1999

SQL-92

ou un type)
REASSIGN

non rserv

RECHECK

non rserv

RECOVERY
RECURSIVE

non rserv

rserv

rserv

rserv

REF

non rserv

rserv

rserv

rserv

REFERENCES

rserv

rserv

rserv

rserv

REFERENCING

rserv

rserv

rserv

REGR_AVGX

rserv

rserv

REGR_AVGY

rserv

rserv

REGR_COUNT

rserv

rserv

REGR_INTERCEPT

rserv

rserv

REGR_R2

rserv

rserv

REGR_SLOPE

rserv

rserv

REGR_SXX

rserv

rserv

REGR_SXY

rserv

rserv

REGR_SYY

rserv

rserv

REINDEX

non rserv

RELATIVE

non rserv

non rserv

non rserv

RELEASE

non rserv

rserv

rserv

RENAME

non rserv

REPEATABLE

non rserv

non rserv

non rserv

REPLACE

non rserv

REPLICA

non rserv
non rserv

non rserv

REQUIRING
RESET

rserv

rserv

non rserv

non rserv

rserv

non rserv

RESPECT
RESTART

rserv

non rserv
non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

RESULT

rserv

rserv

rserv

RETURN

rserv

rserv

rserv

RETURNED_CARDINALITY

non rserv

non rserv

RETURNED_LENGTH

non rserv

non rserv

non rserv

non rserv

RETURNED_OCTET_LENGTH

non rserv

non rserv

non rserv

non rserv

RETURNED_SQLSTATE

non rserv

non rserv

non rserv

non rserv

RESTORE
RESTRICT

non rserv

RETURNING

rserv

non rserv

RETURNS

non rserv

rserv

rserv

rserv

REVOKE

non rserv

rserv

rserv

rserv

rserv

RIGHT

rserv (peut tre une rserv


fonction ou un type)

rserv

rserv

rserv

ROLE

non rserv

non rserv

non rserv

rserv

ROLLBACK

non rserv

rserv

rserv

rserv

ROLLUP

rserv

rserv

rserv

ROUTINE

non rserv

non rserv

rserv

1375

rserv

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

ROUTINE_CATALOG

non rserv

non rserv

non rserv

ROUTINE_NAME

non rserv

non rserv

non rserv

non rserv

ROUTINE_SCHEMA

non rserv

non rserv

ROW

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

ROWS

non rserv

SQL-92

rserv

rserv

rserv

rserv

ROW_COUNT

non rserv

non rserv

non rserv

non rserv

ROW_NUMBER

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

non rserv

non rserv

RULE

non rserv

SAVEPOINT

non rserv

SCALE
SCHEMA

non rserv

non rserv

rserv

rserv

SCHEMA_NAME

non rserv

non rserv

non rserv

non rserv

non rserv

SCOPE

rserv

rserv

rserv

SCOPE_CATALOG

non rserv

non rserv

SCOPE_NAME

non rserv

non rserv

SCOPE_SCHEMA

non rserv

non rserv

SCROLL

non rserv

rserv

rserv

rserv

SEARCH

non rserv

rserv

rserv

rserv

SECOND

non rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

rserv

rserv

SECTION

rserv

SECURITY

non rserv

non rserv

non rserv

non rserv

SELECT

rserv

rserv

rserv

rserv

SELECTIVE

non rserv

non rserv

SELF

non rserv

non rserv

non rserv

SENSITIVE

rserv

rserv

non rserv

non rserv

non rserv

rserv
non rserv

non rserv

rserv

SEQUENCE

non rserv

SEQUENCES

non rserv

SERIALIZABLE

non rserv

non rserv

non rserv

SERVER

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

SERVER_NAME
SESSION

non rserv

non rserv

non rserv

rserv

rserv

SESSION_USER

rserv

rserv

rserv

rserv

rserv

SET

non rserv

rserv

rserv

rserv

rserv

SETOF

non rserv (ne peut


pas tre une fonction
ou un type)
non rserv

non rserv

rserv

SETS
SHARE

non rserv

SHOW

non rserv

SIMILAR

rserv (peut tre une rserv


fonction ou un type)

rserv

non rserv

SIMPLE

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

SIZE
SMALLINT

non rserv (ne peut rserv


1376

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

SQL-92

rserv

rserv

rserv

rserv

SOURCE

non rserv

non rserv

non rserv

SPACE

non rserv

non rserv

rserv

SPECIFIC

rserv

rserv

rserv

SPECIFICTYPE

rserv

rserv

rserv

SPECIFIC_NAME

non rserv

non rserv

non rserv

SQL

rserv

rserv

rserv

pas tre une fonction


ou un type)
SOME

rserv

rserv

rserv

SQLCODE

rserv

SQLERROR

rserv

SQLEXCEPTION

rserv

rserv

rserv

SQLSTATE

rserv

rserv

rserv

SQLWARNING

rserv

rserv

rserv

SQRT

rserv

rserv

STABLE

non rserv

STANDALONE

non rserv

non rserv

non rserv

START

non rserv

rserv

rserv

rserv

non rserv

non rserv

rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

STATE
STATEMENT

non rserv

STATIC
STATISTICS

non rserv

STDDEV_POP
STDDEV_SAMP
STDIN

non rserv

STDOUT

non rserv

STORAGE

non rserv

STRICT

non rserv

STRIP

non rserv

non rserv

non rserv

STRUCTURE

non rserv

non rserv

rserv

STYLE

non rserv

non rserv

non rserv

SUBCLASS_ORIGIN

non rserv

non rserv

non rserv

SUBLIST
rserv

rserv

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

non rserv

rserv

rserv

rserv

non rserv

rserv

rserv

rserv

non rserv

rserv

rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

SUBSTRING_REGEX

rserv

SUM
SYMMETRIC

rserv

SYSID

non rserv

SYSTEM

non rserv

SYSTEM_USER
T
TABLE

non rserv

non rserv

SUBMULTISET
SUBSTRING

rserv

non rserv
rserv

rserv
1377

Mots-cl SQL

Mot-cl

PostgreSQL

TABLES

non rserv

TABLESAMPLE
TABLESPACE

SQL:2008

SQL:2003

SQL:1999

SQL-92

rserv

rserv

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

rserv

non rserv

TABLE_NAME
TEMP

non rserv

TEMPLATE

non rserv

TEMPORARY

non rserv

TERMINATE
TEXT

rserv
non rserv

THAN
THEN

rserv
rserv

TIES

rserv

rserv

non rserv

non rserv

rserv

rserv

TIME

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

TIMESTAMP

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

TIMEZONE_HOUR

rserv

rserv

rserv

rserv

TIMEZONE_MINUTE

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

TO

rserv

TOKEN
TOP_LEVEL_COUNT

non rserv

non rserv

TRAILING

rserv

rserv

rserv

rserv

rserv

TRANSACTION

non rserv

non rserv

non rserv

rserv

rserv

TRANSACTIONS_COMMITTED

non rserv

non rserv

non rserv

TRANSACTIONS_ROLLED_BACK

non rserv

non rserv

non rserv

TRANSACTION_ACTIVE

non rserv

non rserv

non rserv

TRANSFORM

non rserv

non rserv

non rserv

TRANSFORMS

non rserv

non rserv

non rserv

TRANSLATE

rserv

rserv

non rserv

rserv

TRANSLATE_REGEX

rserv
rserv

TRANSLATION

rserv

rserv

rserv

TREAT

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

TRIGGER

non rserv

rserv

rserv

rserv

TRIGGER_CATALOG

non rserv

non rserv

non rserv

TRIGGER_NAME

non rserv

non rserv

non rserv

TRIGGER_SCHEMA

non rserv

non rserv

non rserv

rserv

non rserv

rserv

rserv

rserv

rserv

TRIM

non rserv (ne peut rserv


pas tre une fonction
ou un type)

TRIM_ARRAY

rserv

TRUE

rserv

rserv

TRUNCATE

non rserv

rserv

TRUSTED

non rserv
1378

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

SQL-92

TYPE

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

rserv
non rserv

UESCAPE
UNBOUNDED

non rserv

non rserv

non rserv

UNCOMMITTED

non rserv

non rserv

non rserv

non rserv

non rserv

non rserv

rserv

UNDER
UNENCRYPTED

non rserv

UNION

rserv

rserv

rserv

rserv

rserv

UNIQUE

rserv

rserv

rserv

rserv

rserv

UNKNOWN

non rserv

rserv

rserv

rserv

rserv

non rserv

non rserv

UNNAMED

non rserv

non rserv

non rserv

non rserv

UNNEST

rserv

rserv

rserv

rserv

rserv

rserv

rserv

UPPER

rserv

rserv

non rserv

rserv

URI

non rserv

USAGE

non rserv

non rserv

rserv

rserv

rserv

rserv

rserv

rserv

USER_DEFINED_TYPE_CATALOG

non rserv

non rserv

non rserv

USER_DEFINED_TYPE_CODE

non rserv

non rserv

USER_DEFINED_TYPE_NAME

non rserv

non rserv

non rserv

USER_DEFINED_TYPE_SCHEMA

non rserv

non rserv

non rserv

rserv

rserv

rserv

rserv

UNLINK
UNLISTEN

non rserv

UNLOGGED

non rserv

UNTIL

non rserv

UNTYPED
UPDATE

USER

non rserv
non rserv

rserv

USING

rserv

VACUUM

non rserv

VALID

non rserv

VALIDATE

non rserv

VALIDATOR

non rserv

VALUE

non rserv

rserv

rserv

rserv

rserv

VALUES

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

rserv

rserv

rserv

rserv

rserv

non rserv

VARBINARY
VARCHAR

rserv
non rserv (ne peut rserv
pas tre une fonction
ou un type)

VARIABLE

rserv

VARIADIC

rserv

VARYING

non rserv

rserv

rserv

VAR_POP

rserv

rserv

VAR_SAMP

rserv

rserv

non rserv

non rserv

VERBOSE

rserv (peut tre une


fonction ou un type)

VERSION

non rserv
1379

rserv

rserv

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

SQL:2003

SQL:1999

SQL-92

VIEW

non rserv

non rserv

non rserv

rserv

rserv

VOLATILE

non rserv

WHEN

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

rserv

WHENEVER
WHERE

rserv

rserv

rserv

WHITESPACE

non rserv

non rserv

non rserv

rserv

rserv

WIDTH_BUCKET
WINDOW

rserv

rserv

rserv

WITH

rserv

rserv

rserv

rserv

rserv

WITHIN
WITHOUT

non rserv

rserv

rserv

rserv

WORK

non rserv

non rserv

non rserv

rserv

rserv

WRAPPER

non rserv

non rserv

non rserv

WRITE

non rserv

non rserv

non rserv

rserv

rserv

XML

non rserv

rserv

rserv

rserv

rserv

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

XMLBINARY

rserv

rserv

XMLCAST

rserv

XMLCOMMENT

rserv

rserv

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

XMLAGG
XMLATTRIBUTES

XMLCONCAT

XMLDECLARATION

non rserv

XMLDOCUMENT

rserv

XMLELEMENT

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

XMLEXISTS

non rserv (ne peut


pas tre une fonction
ou un type)

rserv

XMLFOREST

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

XMLITERATE

rserv

XMLNAMESPACES

rserv

rserv

XMLPARSE

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

XMLPI

non rserv (ne peut rserv


pas tre une fonction
ou un type)

rserv

XMLQUERY
XMLROOT

rserv
non rserv (ne peut
pas tre une fonction
ou un type)

XMLSCHEMA

rserv

non rserv
1380

Mots-cl SQL

Mot-cl

PostgreSQL

SQL:2008

XMLSERIALIZE

non rserv (ne peut rserv


pas tre une fonction
ou un type)

XMLTABLE

rserv

XMLTEXT

rserv

XMLVALIDATE

rserv

YEAR

non rserv

rserv

YES

non rserv

non rserv

ZONE

non rserv

non rserv

1381

SQL:2003

SQL:1999

SQL-92

rserv

rserv

rserv

non rserv

rserv

rserv

rserv

Annexe D. Conformit SQL


Cette section explique dans quelle mesure PostgreSQL se conforme la norme SQL en vigueur. Les informations qui suivent ne
reprsentent pas une liste exhaustive de conformance, mais prsentent les thmes principaux utilement et raisonnablement dtaills.
Le nom complet du standard SQL est ISO/IEC 9075 Database Language SQL . Le standard est modifi de temps en temps. La
mise jour la plus rcente apparat en 2008. La version 2008 est rfrence ISO/IEC 9075:2008, ou plus simplement SQL:2008.
Les versions antrieures taient SQL:2003, SQL:1999 et SQL-92. Chaque version remplace la prcdente. Il n'y a donc aucun mrite revendiquer une compatibilit avec une version antrieure du standard.
Le dveloppement de PostgreSQL respecte le standard en vigueur, tant que celui-ci ne s'oppose pas aux fonctionnalits traditionnelles ou au bon sens. Un grand nombre des fonctionnalits requises par le standard SQL sont dj supportes. Parfois avec
une syntaxe ou un fonctionnement lgrement diffrents. Une meilleure compatibilit est attendue pour les prochaines versions.
SQL-92 dfinit trois niveaux de conformit : basique (Entry), intermdiaire (Intermediate) et complte (Full). La majorit des systmes de gestion de bases de donnes se prtendaient compatibles au standard SQL ds lors qu'ils se conformaient au niveau Entry ; l'ensemble des fonctionnalits des niveaux Intermediate et Full taient, soit trop volumineux, soit en conflit avec les fonctionnalits implantes.
partir de SQL99, le standard SQL dfinit un vaste ensemble de fonctionnalits individuelles la place des trois niveaux de fonctionnalits dfinis dans SQL-92. Une grande partie reprsente les fonctionnalits centrales que chaque implantation conforme
de SQL doit fournir. Les fonctionnalits restantes sont purement optionnelles. Certaines sont regroupes au sein de paquetages
auxquels une implantation peut se dclarer conforme. On parle alors de conformit un groupe de fonctionnalits.
Les standards SQL:2008 et SQL:2003 sont galement divis en parties. Chacune est connue par un pseudonyme. Leur numrotation n'est pas conscutive :

ISO/IEC 9075-1 Framework (SQL/Framework)

ISO/IEC 9075-2 Foundation (SQL/Foundation)

ISO/IEC 9075-3 Call Level Interface (SQL/CLI)

ISO/IEC 9075-4 Persistent Stored Modules (SQL/PSM)

ISO/IEC 9075-9 Management of External Data (SQL/MED)

ISO/IEC 9075-10 Object Language Bindings (SQL/OLB)

ISO/IEC 9075-11 Information and Definition Schemas (SQL/Schemata)

ISO/IEC 9075-13 Routines and Types using the Java Language (SQL/JRT)

ISO/IEC 9075-14 XML-related specifications (SQL/XML)

PostgreSQL couvre les parties 1, 2, 9, 11 et 14. La partie 3 est couverte par l'interface ODBC, et la partie 13 est couverte par le
plugin PL/Java, mais une conformance exacte n'est pas actuellement vrifie par ses composants. Il n'y a pas actuellement
d'implantations des parties 4 et 10 pour PostgreSQL.
PostgreSQL supporte la plupart des fonctionnalits majeures de SQL:2008. Sur les 179 fonctionnalits requises pour une conformit centrale complte (full Core conformance), PostgreSQL se conforme plus de 160. De plus, il existe une longue liste de
fonctionnalits optionelles supportes. la date de rdaction de ce document, aucune version de quelque systme de gestion de
bases de donnes que ce soit n'affiche une totale conformit au cur de SQL:2008.
Les deux sections qui suivent prsentent la liste des fonctionnalits supportes par PostgreSQL et celle des fonctionnalits dfinies dans SQL:2008 qui ne sont pas encore prises en compte. Ces deux listes sont approximatives : certains dtails d'une fonctionnalit prsente comme supporte peuvent ne pas tre conformes, alors que de grandes parties d'une fonctionnalit non supporte
peuvent tre implantes. La documentation principale fournit les informations prcises sur ce qui est, ou non, support.

Note
Les codes de fonctionnalit contenant un tiret sont des sous-fonctionnalits. Si une sous-fonctionnalit n'est pas
supporte, la fonctionnalit elle-mme sera dclare non supporte, alors mme que d'autres de ses sousfonctionnalits le sont.

1382

Conformit SQL

D.1. Fonctionnalits supportes


Identifiant

Paquetage

Description

B012

Embedded C

B021

Direct SQL

Commentaire

E011

Core

Numeric data types

E011-01

Core

INTEGER and SMALLINT data types

E011-02

Core

REAL, DOUBLE PRECISION, and FLOAT data types

E011-03

Core

DECIMAL and NUMERIC data types

E011-04

Core

Arithmetic operators

E011-05

Core

Numeric comparison

E011-06

Core

Implicit casting among the numeric data types

E021

Core

Character data types

E021-01

Core

CHARACTER data type

E021-02

Core

CHARACTER VARYING data type

E021-03

Core

Character literals

E021-04

Core

CHARACTER_LENGTH function

E021-05

Core

OCTET_LENGTH function

E021-06

Core

SUBSTRING function

E021-07

Core

Character concatenation

E021-08

Core

UPPER and LOWER functions

E021-09

Core

TRIM function

E021-10

Core

Implicit casting among the character string types

E021-11

Core

POSITION function

E021-12

Core

Character comparison

E031

Core

Identifiers

E031-01

Core

Delimited identifiers

E031-02

Core

Lower case identifiers

E031-03

Core

Trailing underscore

E051

Core

Basic query specification

E051-01

Core

SELECT DISTINCT

E051-02

Core

GROUP BY clause

E051-04

Core

GROUP BY can contain columns not in <select list>

E051-05

Core

Select list items can be renamed

E051-06

Core

HAVING clause

E051-07

Core

Qualified * in select list

E051-08

Core

Correlation names in the FROM clause

E051-09

Core

Rename columns in the FROM clause

E061

Core

Basic predicates and search conditions

E061-01

Core

Comparison predicate

E061-02

Core

BETWEEN predicate

E061-03

Core

IN predicate with list of values

E061-04

Core

LIKE predicate

E061-05

Core

LIKE predicate ESCAPE clause


1383

trims trailing spaces from


CHARACTER values before
counting

Conformit SQL

Identifiant

Paquetage

Description

E061-06

Core

NULL predicate

Commentaire

E061-07

Core

Quantified comparison predicate

E061-08

Core

EXISTS predicate

E061-09

Core

Subqueries in comparison predicate

E061-11

Core

Subqueries in IN predicate

E061-12

Core

Subqueries in quantified comparison predicate

E061-13

Core

Correlated subqueries

E061-14

Core

Search condition

E071

Core

Basic query expressions

E071-01

Core

UNION DISTINCT table operator

E071-02

Core

UNION ALL table operator

E071-03

Core

EXCEPT DISTINCT table operator

E071-05

Core

Columns combined via table operators need not have


exactly the same data type

E071-06

Core

Table operators in subqueries

E081-01

Core

SELECT privilege

E081-02

Core

DELETE privilege

E081-03

Core

INSERT privilege at the table level

E081-04

Core

UPDATE privilege at the table level

E081-05

Core

UPDATE privilege at the column level

E081-06

Core

REFERENCES privilege at the table level

E081-07

Core

REFERENCES privilege at the column level

E081-08

Core

WITH GRANT OPTION

E081-10

Core

EXECUTE privilege

E091

Core

Set functions

E091-01

Core

AVG

E091-02

Core

COUNT

E091-03

Core

MAX

E091-04

Core

MIN

E091-05

Core

SUM

E091-06

Core

ALL quantifier

E091-07

Core

DISTINCT quantifier

E101

Core

Basic data manipulation

E101-01

Core

INSERT statement

E101-03

Core

Searched UPDATE statement

E101-04

Core

Searched DELETE statement

E111

Core

Single row SELECT statement

E121

Core

Basic cursor support

E121-01

Core

DECLARE CURSOR

E121-02

Core

ORDER BY columns need not be in select list

E121-03

Core

Value expressions in ORDER BY clause

E121-04

Core

OPEN statement

E121-06

Core

Positioned UPDATE statement

E121-07

Core

Positioned DELETE statement


1384

Conformit SQL

Identifiant

Paquetage

Description

E121-08

Core

CLOSE statement

Commentaire

E121-10

Core

FETCH statement implicit NEXT

E121-17

Core

WITH HOLD cursors

E131

Core

Null value support (nulls in lieu of values)

E141

Core

Basic integrity constraints

E141-01

Core

NOT NULL constraints

E141-02

Core

UNIQUE constraints of NOT NULL columns

E141-03

Core

PRIMARY KEY constraints

E141-04

Core

Basic FOREIGN KEY constraint with the NO ACTION


default for both referential delete action and referential
update action

E141-06

Core

CHECK constraints

E141-07

Core

Column defaults

E141-08

Core

NOT NULL inferred on PRIMARY KEY

E141-10

Core

Names in a foreign key can be specified in any order

E151

Core

Transaction support

E151-01

Core

COMMIT statement

E151-02

Core

ROLLBACK statement

E152

Core

Basic SET TRANSACTION statement

E152-01

Core

SET TRANSACTION statement: ISOLATION LEVEL


SERIALIZABLE clause

E152-02

Core

SET TRANSACTION statement: READ ONLY and


READ WRITE clauses

E161

Core

SQL comments using leading double minus

E171

Core

SQLSTATE support

F021

Core

Basic information schema

F021-01

Core

COLUMNS view

F021-02

Core

TABLES view

F021-03

Core

VIEWS view

F021-04

Core

TABLE_CONSTRAINTS view

F021-05

Core

REFERENTIAL_CONSTRAINTS view

F021-06

Core

CHECK_CONSTRAINTS view

F031

Core

Basic schema manipulation

F031-01

Core

CREATE TABLE statement to create persistent base


tables

F031-02

Core

CREATE VIEW statement

F031-03

Core

GRANT statement

F031-04

Core

ALTER TABLE statement: ADD COLUMN clause

F031-13

Core

DROP TABLE statement: RESTRICT clause

F031-16

Core

DROP VIEW statement: RESTRICT clause

F031-19

Core

REVOKE statement: RESTRICT clause

F032

CASCADE drop behavior

F033

ALTER TABLE statement: DROP COLUMN clause

F034

Extended REVOKE statement

F034-01

REVOKE statement performed by other than the owner


of a schema object
1385

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

F034-02

REVOKE statement: GRANT OPTION FOR clause

F034-03

REVOKE statement to revoke a privilege that the grantee


has WITH GRANT OPTION

F041

Core

Basic joined table

F041-01

Core

Inner join (but not necessarily the INNER keyword)

F041-02

Core

INNER keyword

F041-03

Core

LEFT OUTER JOIN

F041-04

Core

RIGHT OUTER JOIN

F041-05

Core

Outer joins can be nested

F041-07

Core

The inner table in a left or right outer join can also be


used in an inner join

F041-08

Core

All comparison operators are supported (rather than just


=)

F051

Core

Basic date and time

F051-01

Core

DATE data type (including support of DATE literal)

F051-02

Core

TIME data type (including support of TIME literal) with


fractional seconds precision of at least 0

F051-03

Core

TIMESTAMP data type (including support of TIMESTAMP literal) with fractional seconds precision of at
least 0 and 6

F051-04

Core

Comparison predicate on DATE, TIME, and TIMESTAMP data types

F051-05

Core

Explicit CAST between datetime types and character


string types

F051-06

Core

CURRENT_DATE

F051-07

Core

LOCALTIME

F051-08

Core

LOCALTIMESTAMP

F052

Enhanced date- Intervals and datetime arithmetic


time facilities

F053
F081

OVERLAPS predicate
Core

UNION and EXCEPT in views

F111

Isolation levels other than SERIALIZABLE

F111-01

READ UNCOMMITTED isolation level

F111-02

READ COMMITTED isolation level

F111-03

REPEATABLE READ isolation level

F131

Core

Grouped operations

F131-01

Core

WHERE, GROUP BY, and HAVING clauses supported


in queries with grouped views

F131-02

Core

Multiple tables supported in queries with grouped views

F131-03

Core

Set functions supported in queries with grouped views

F131-04

Core

Subqueries with GROUP BY and HAVING clauses and


grouped views

F131-05

Core

Single row SELECT with GROUP BY and HAVING


clauses and grouped views

F171
F191

Multiple schemas per user


Enhanced integri- Referential delete actions
ty management
1386

Conformit SQL

Identifiant

Paquetage

F200

Description

Commentaire

TRUNCATE TABLE statement

F201

Core

CAST function

F221

Core

Explicit defaults

F222

INSERT statement: DEFAULT VALUES clause

F231

Privilege tables

F231-01

TABLE_PRIVILEGES view

F231-02

COLUMN_PRIVILEGES view

F231-03

USAGE_PRIVILEGES view

F251

Domain support

F261

Core

CASE expression

F261-01

Core

Simple CASE

F261-02

Core

Searched CASE

F261-03

Core

NULLIF

F261-04

Core

COALESCE

F262

Extended CASE expression

F271

Compound character literals

F281

LIKE enhancements

F302

INTERSECT table operator

F302-01

INTERSECT DISTINCT table operator

F302-02

INTERSECT ALL table operator

F304

EXCEPT ALL table operator

F311-01

Core

CREATE SCHEMA

F311-02

Core

CREATE TABLE for persistent base tables

F311-03

Core

CREATE VIEW

F311-05

Core

GRANT statement

F321

User authorization

F361

Subprogram support

F381

Extended schema manipulation

F381-01

ALTER TABLE statement: ALTER COLUMN clause

F381-02

ALTER TABLE statement: ADD CONSTRAINT clause

F381-03

ALTER TABLE statement: DROP CONSTRAINT


clause

F382

Alter column data type

F391

Long identifiers

F392

Unicode escapes in identifiers

F393

Unicode escapes in literals

F401

Extended joined table

F401-01

NATURAL JOIN

F401-02

FULL OUTER JOIN

F401-04

CROSS JOIN

F402

Named column joins for LOBs, arrays, and multisets

F411
F421

Enhanced date- Time zone specification


time facilities
National character
1387

differences regarding literal interpretation

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

F431

Read-only scrollable cursors

F431-01

FETCH with explicit NEXT

F431-02

FETCH FIRST

F431-03

FETCH LAST

F431-04

FETCH PRIOR

F431-05

FETCH ABSOLUTE

F431-06

FETCH RELATIVE

F441

Extended set function support

F442

Mixed column references in set functions

F471

Core

Scalar subquery values

F481

Core

Expanded NULL predicate

F491

Enhanced integri- Constraint management


ty management

F501

Core

Features and conformance views

F501-01

Core

SQL_FEATURES view

F501-02

Core

SQL_SIZING view

F501-03

Core

SQL_LANGUAGES view

F502

Enhanced documentation tables

F502-01

SQL_SIZING_PROFILES view

F502-02

SQL_IMPLEMENTATION_INFO view

F502-03

SQL_PACKAGES view

F531

Temporary tables

F555

Enhanced date- Enhanced seconds precision


time facilities

F561

Full value expressions

F571

Truth value tests

F591

Derived tables

F611

Indicator data types

F641

Row and table constructors

F651

Catalog name qualifiers

F661

Simple tables

F672

Retrospective check constraints

F690

Collation support

F692

Extended collation support

F701

but no character set support

Enhanced integri- Referential update actions


ty management

F711

ALTER domain

F731

INSERT column privileges

F761

Session management

F762

CURRENT_CATALOG

F763

CURRENT_SCHEMA

F771

Connection management

F781

Self-referencing operations

F791

Insensitive cursors

F801

Full set function


1388

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

F850

Top-level <order by clause> in <query expression>

F851

<order by clause> in subqueries

F852

Top-level <order by clause> in views

F855

Nested <order by clause> in <query expression>

F856

Nested <fetch first clause> in <query expression>

F857

Top-level <fetch first clause> in <query expression>

F858

<fetch first clause> in subqueries

F859

Top-level <fetch first clause> in views

F860

<fetch first row count> in <fetch first clause>

F861

Top-level <result offset clause> in <query expression>

F862

<result offset clause> in subqueries

F863

Nested <result offset clause> in <query expression>

F864

Top-level <result offset clause> in views

F865

<offset row count> in <result offset clause>

S071

Enhanced
support

object SQL paths in function and type name resolution

S092

Arrays of user-defined types

S095

Array constructors by query

S096

Optional array bounds

S098

ARRAY_AGG

S111

Enhanced
support

object ONLY in query expressions

S201

SQL-invoked routines on arrays

S201-01

Array parameters

S201-02

Array as result type of functions

S211

Enhanced
support

object User-defined cast functions

T031

BOOLEAN data type

T071

BIGINT data type

T121

WITH (excluding RECURSIVE) in query expression

T122

WITH (excluding RECURSIVE) in subquery

T131

Recursive query

T132

Recursive query in subquery

T141

SIMILAR predicate

T151

DISTINCT predicate

T152

DISTINCT predicate with negation

T171

LIKE clause in table definition

T172

AS subquery clause in table definition

T173

Extended LIKE clause in table definition

T191

Enhanced integri- Referential action RESTRICT


ty management

T201

Enhanced integri- Comparable data types for referential constraints


ty management

T211-01

Active database, Triggers activated on UPDATE, INSERT, or DELETE of


Enhanced integri- one base table
ty management
1389

Conformit SQL

Identifiant

Paquetage

T211-02

Active database, BEFORE triggers


Enhanced integrity management

Description

Commentaire

T211-03

Active database, AFTER triggers


Enhanced integrity management

T211-04

Active database, FOR EACH ROW triggers


Enhanced integrity management

T211-05

Active database, Ability to specify a search condition that must be true beEnhanced integri- fore the trigger is invoked
ty management

T211-07

Active database, TRIGGER privilege


Enhanced integrity management

T212

Enhanced integri- Enhanced trigger capability


ty management

T213

INSTEAD OF triggers

T231

Sensitive cursors

T241

START TRANSACTION statement

T271

Savepoints

T281

SELECT privilege with column granularity

T312

OVERLAY function

T321-01

Core

User-defined functions with no overloading

T321-03

Core

Function invocation

T321-06

Core

ROUTINES view

T321-07

Core

PARAMETERS view

T322

PSM

Overloading of SQL-invoked functions and procedures

T323

Explicit security for external routines

T331

Basic roles

T351

Bracketed SQL comments (/*...*/ comments)

T441

ABS and MOD functions

T461

Symmetric BETWEEN predicate

T501

Enhanced EXISTS predicate

T551

Optional key words for default syntax

T581

Regular expression substring function

T591

UNIQUE constraints of possibly null columns

T614

NTILE function

T615

LEAD and LAG functions

T617

FIRST_VALUE and LAST_VALUE function

T621

Enhanced numeric functions

T631

Core

IN predicate with one list element

T651

SQL-schema statements in SQL routines

T655

Cyclically dependent routines

X010

XML type

X011

Arrays of XML type

X016

Persistent XML values


1390

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

X020

XMLConcat

X031

XMLElement

X032

XMLForest

X034

XMLAgg

X035

XMLAgg: ORDER BY option

X036

XMLComment

X037

XMLPI

X040

Basic table mapping

X041

Basic table mapping: nulls absent

X042

Basic table mapping: null as nil

X043

Basic table mapping: table as forest

X044

Basic table mapping: table as element

X045

Basic table mapping: with target namespace

X046

Basic table mapping: data mapping

X047

Basic table mapping: metadata mapping

X048

Basic table mapping: base64 encoding of binary strings

X049

Basic table mapping: hex encoding of binary strings

X050

Advanced table mapping

X051

Advanced table mapping: nulls absent

X052

Advanced table mapping: null as nil

X053

Advanced table mapping: table as forest

X054

Advanced table mapping: table as element

X055

Advanced table mapping: target namespace

X056

Advanced table mapping: data mapping

X057

Advanced table mapping: metadata mapping

X058

Advanced table mapping: base64 encoding of binary


strings

X059

Advanced table mapping: hex encoding of binary strings

X060

XMLParse: Character string input and CONTENT option

X061

XMLParse: Character string input and DOCUMENT option

X070

XMLSerialize: Character
CONTENT option

X071

XMLSerialize: Character string serialization and DOCUMENT option

X072

XMLSerialize: Character string serialization

X090

XML document predicate

X120

XML parameters in SQL routines

X121

XML parameters in external routines

X400

Name and identifier mapping

string

serialization

and

D.2. Fonctionnalits non supportes


Les fonctionnalits suivantes dfinies dans SQL:2008 ne sont pas implantes dans cette version de PostgreSQL. Dans certains
cas, des fonctionnalits similaires sont disponibles.
1391

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

B011

Embedded Ada

B013

Embedded COBOL

B014

Embedded Fortran

B015

Embedded MUMPS

B016

Embedded Pascal

B017

Embedded PL/I

B031

Basic dynamic SQL

B032

Extended dynamic SQL

B032-01

<describe input statement>

B033

Untyped SQL-invoked function arguments

B034

Dynamic specification of cursor attributes

B035

Non-extended descriptor names

B041

Extensions to embedded SQL exception declarations

B051

Enhanced execution rights

B111

Module language Ada

B112

Module language C

B113

Module language COBOL

B114

Module language Fortran

B115

Module language MUMPS

B116

Module language Pascal

B117

Module language PL/I

B121

Routine language Ada

B122

Routine language C

B123

Routine language COBOL

B124

Routine language Fortran

B125

Routine language MUMPS

B126

Routine language Pascal

B127

Routine language PL/I

B128

Routine language SQL

E081

Core

Basic Privileges

E081-09

Core

USAGE privilege

E153

Core

Updatable queries with subqueries

E182

Core

Module language

F121

Basic diagnostics management

F121-01

GET DIAGNOSTICS statement

F121-02

SET TRANSACTION statement: DIAGNOSTICS SIZE


clause

F122

Enhanced diagnostics management

F123

All diagnostics

F181

Core

Multiple module support

F202

TRUNCATE TABLE: identity column restart option

F263

Comma-separated predicates in simple CASE expression

F291

UNIQUE predicate

F301

CORRESPONDING in query expressions


1392

Conformit SQL

Identifiant

Paquetage

Description

F311

Core

Schema definition statement

Commentaire

F311-04

Core

CREATE VIEW: WITH CHECK OPTION

F312

MERGE statement

F313

Enhanced MERGE statement

F341

Usage tables

F394

Optional normal form specification

F403

Partitioned joined tables

F451

Character set definition

F461

no
tables

ROUTINE_*_USAGE

Named character sets

F521

Enhanced integri- Assertions


ty management

F671

Enhanced integri- Subqueries in CHECK


ty management

intentionally omitted

F693

SQL-session and client module collations

F695

Translation support

F696

Additional translation documentation

F721

Deferrable constraints

foreign and unique keys only

F741

Referential MATCH types

no partial match yet

F751
F812

View CHECK enhancements


Core

Basic flagging

F813

Extended flagging

F821

Local table references

F831

Full cursor update

F831-01

Updatable scrollable cursors

F831-02

Updatable ordered cursors

F841

LIKE_REGEX predicate

F842

OCCURENCES_REGEX function

F843

POSITION_REGEX function

F844

SUBSTRING_REGEX function

F845

TRANSLATE_REGEX function

F846

Octet support in regular expression operators

F847

Nonconstant regular expressions

S011

Core

Distinct data types

S011-01

Core

USER_DEFINED_TYPES view

S023

Basic object sup- Basic structured types


port

S024

Enhanced
support

object Enhanced structured types

S025

Final structured types

S026

Self-referencing structured types

S027

Create method by specific method name

S028

Permutable UDT options list

S041

Basic object sup- Basic reference types


port

S043

Enhanced

object Enhanced reference types


1393

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

support
S051

Basic object sup- Create table of type


port

S081

Enhanced
support

partially supported

object Subtables

S091

Basic array support

S091-01

Arrays of built-in data types

S091-02

Arrays of distinct types

S091-03

Array expressions

S094

Arrays of reference types

S097

Array element assignment

S151

Basic object sup- Type predicate


port

S161

Enhanced
support

partially supported

object Subtype treatment

S162

Subtype treatment for references

S202

SQL-invoked routines on multisets

S231

Enhanced
support

object Structured type locators

S232

Array locators

S233

Multiset locators

S241

Transform functions

S242

Alter transform statement

S251

User-defined orderings

S261

Specific type method

S271

Basic multiset support

S272

Multisets of user-defined types

S274

Multisets of reference types

S275

Advanced multiset support

S281

Nested collection types

S291

Unique constraint on entire row

S301

Enhanced UNNEST

S401

Distinct types based on array types

S402

Distinct types based on distinct types

S403

MAX_CARDINALITY

S404

TRIM_ARRAY

T011

Timestamp in Information Schema

T021

BINARY and VARBINARY data types

T022

Advanced support for BINARY and VARBINARY data


types

T023

Compound binary literal

T024

Spaces in binary literals

T041

Basic object sup- Basic LOB data type support


port

T041-01

Basic object sup- BLOB data type


port
1394

Conformit SQL

Identifiant

Paquetage

T041-02

Basic object sup- CLOB data type


port

Description

Commentaire

T041-03

Basic object sup- POSITION, LENGTH, LOWER, TRIM, UPPER, and


port
SUBSTRING functions for LOB data types

T041-04

Basic object sup- Concatenation of LOB data types


port

T041-05

Basic object sup- LOB locator: non-holdable


port

T042

Extended LOB data type support

T043

Multiplier T

T044

Multiplier P

T051

Row types

T052

MAX and MIN for row types

T053

Explicit aliases for all-fields reference

T061

UCS support

T101

Enhanced nullability determination

T111

Updatable joins, unions, and columns

T174

Identity columns

T175

Generated columns

T176

Sequence generator support

T177

Sequence generator support: simple restart option

T178

Identity columns: simple restart option

T211

Active database, Basic trigger capability


Enhanced integrity management

T211-06

Active database, Support for run-time rules for the interaction of triggers
Enhanced integri- and constraints
ty management

T211-08

Active database, Multiple triggers for the same event are executed in the intentionally omitted
Enhanced integri- order in which they were created in the catalog
ty management

T251

SET TRANSACTION statement: LOCAL option

T261

Chained transactions

T272

Enhanced savepoint management

T285

Enhanced derived column names

T301

Functional dependencies

T321

Core

Basic SQL-invoked routines

T321-02

Core

User-defined stored procedures with no overloading

T321-04

Core

CALL statement

T321-05

Core

RETURN statement

T324

Explicit security for SQL routines

T325

Qualified SQL parameter references

T326

Table functions

T332

Extended roles

T431

OLAP

partially supported

mostly supported

Extended grouping capabilities

T432

Nested and concatenated GROUPING SETS

T433

Multiargument GROUPING function


1395

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

T434

GROUP BY DISTINCT

T471

Result sets return value

T491

LATERAL derived table

T511

Transaction counts

T541

Updatable table references

T561

Holdable locators

T571

Array-returning external SQL-invoked functions

T572

Multiset-returning external SQL-invoked functions

T601

Local cursor references

T611

OLAP

Elementary OLAP operations

most forms supported

T612

Advanced OLAP operations

some forms supported

T613

Sampling

T616

Null treatment option for LEAD and LAG functions

T618

NTH_VALUE function

function exists, but some options missing

T641

Multiple column assignment

only some syntax variants supported

T652

SQL-dynamic statements in SQL routines

T653

SQL-schema statements in external routines

T654

SQL-dynamic statements in external routines

M001

Datalinks

M002

Datalinks via SQL/CLI

M003

Datalinks via Embedded SQL

M004

Foreign data support

M005

Foreign schema support

M006

GetSQLString routine

M007

TransmitRequest

M009

GetOpts and GetStatistics routines

M010

Foreign data wrapper support

M011

Datalinks via Ada

M012

Datalinks via C

M013

Datalinks via COBOL

M014

Datalinks via Fortran

M015

Datalinks via M

M016

Datalinks via Pascal

M017

Datalinks via PL/I

M018

Foreign data wrapper interface routines in Ada

M019

Foreign data wrapper interface routines in C

M020

Foreign data wrapper interface routines in COBOL

M021

Foreign data wrapper interface routines in Fortran

M022

Foreign data wrapper interface routines in MUMPS

M023

Foreign data wrapper interface routines in Pascal

M024

Foreign data wrapper interface routines in PL/I

M030

SQL-server foreign data support

partially supported

1396

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

M031

Foreign data wrapper general routines

X012

Multisets of XML type

X013

Distinct types of XML type

X014

Attributes of XML type

X015

Fields of XML type

X025

XMLCast

X030

XMLDocument

X038

XMLText

X065

XMLParse: BLOB input and CONTENT option

X066

XMLParse: BLOB input and DOCUMENT option

X068

XMLSerialize: BOM

X069

XMLSerialize: INDENT

X073

XMLSerialize: BLOB serialization and CONTENT option

X074

XMLSerialize: BLOB serialization and DOCUMENT


option

X075

XMLSerialize: BLOB serialization

X076

XMLSerialize: VERSION

X077

XMLSerialize: explicit ENCODING option

X078

XMLSerialize: explicit XML declaration

X080

Namespaces in XML publishing

X081

Query-level XML namespace declarations

X082

XML namespace declarations in DML

X083

XML namespace declarations in DDL

X084

XML namespace declarations in compound statements

X085

Predefined namespace prefixes

X086

XML namespace declarations in XMLTable

X091

XML content predicate

X096

XMLExists

X100

Host language support for XML: CONTENT option

X101

Host language support for XML: DOCUMENT option

X110

Host language support for XML: VARCHAR mapping

X111

Host language support for XML: CLOB mapping

X112

Host language support for XML: BLOB mapping

X113

Host language support for XML: STRIP WHITESPACE


option

X114

Host language support for XML: PRESERVE WHITESPACE option

X131

Query-level XMLBINARY clause

X132

XMLBINARY clause in DML

X133

XMLBINARY clause in DDL

X134

XMLBINARY clause in compound statements

X135

XMLBINARY clause in subqueries

X141

IS VALID predicate: data-driven case

X142

IS VALID predicate: ACCORDING TO clause


1397

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

X143

IS VALID predicate: ELEMENT clause

X144

IS VALID predicate: schema location

X145

IS VALID predicate outside check constraints

X151

IS VALID predicate with DOCUMENT option

X152

IS VALID predicate with CONTENT option

X153

IS VALID predicate with SEQUENCE option

X155

IS VALID predicate: NAMESPACE without ELEMENT


clause

X157

IS VALID predicate: NO NAMESPACE with ELEMENT clause

X160

Basic Information Schema for registered XML Schemas

X161

Advanced Information Schema for registered XML Schemas

X170

XML null handling options

X171

NIL ON NO CONTENT option

X181

XML(DOCUMENT(UNTYPED)) type

X182

XML(DOCUMENT(ANY)) type

X190

XML(SEQUENCE) type

X191

XML(DOCUMENT(XMLSCHEMA)) type

X192

XML(CONTENT(XMLSCHEMA)) type

X200

XMLQuery

X201

XMLQuery: RETURNING CONTENT

X202

XMLQuery: RETURNING SEQUENCE

X203

XMLQuery: passing a context item

X204

XMLQuery: initializing an XQuery variable

X205

XMLQuery: EMPTY ON EMPTY option

X206

XMLQuery: NULL ON EMPTY option

X211

XML 1.1 support

X221

XML passing mechanism BY VALUE

X222

XML passing mechanism BY REF

X231

XML(CONTENT(UNTYPED)) type

X232

XML(CONTENT(ANY)) type

X241

RETURNING CONTENT in XML publishing

X242

RETURNING SEQUENCE in XML publishing

X251

Persistent
XML
values
XML(DOCUMENT(UNTYPED)) type

X252

Persistent XML values of XML(DOCUMENT(ANY))


type

X253

Persistent
XML
values
XML(CONTENT(UNTYPED)) type

X254

Persistent XML values of XML(CONTENT(ANY)) type

X255

Persistent XML values of XML(SEQUENCE) type

X256

Persistent
XML
values
XML(DOCUMENT(XMLSCHEMA)) type

of

X257

Persistent
XML
values
XML(CONTENT(XMLSCHEMA)) type

of

1398

of

of

Conformit SQL

Identifiant

Paquetage

Description

Commentaire

X260

XML type: ELEMENT clause

X261

XML type: NAMESPACE without ELEMENT clause

X263

XML type: NO NAMESPACE with ELEMENT clause

X264

XML type: schema location

X271

XMLValidate: data-driven case

X272

XMLValidate: ACCORDING TO clause

X273

XMLValidate: ELEMENT clause

X274

XMLValidate: schema location

X281

XMLValidate: with DOCUMENT option

X282

XMLValidate with CONTENT option

X283

XMLValidate with SEQUENCE option

X284

XMLValidate NAMESPACE without ELEMENT clause

X286

XMLValidate: NO NAMESPACE with ELEMENT


clause

X300

XMLTable

X301

XMLTable: derived column list option

X302

XMLTable: ordinality column option

X303

XMLTable: column default option

X304

XMLTable: passing a context item

X305

XMLTable: initializing an XQuery variable

1399

Annexe E. Notes de version


Les notes de version contiennent les modifications significatives apparaissant dans chaque version de PostgreSQL. Elles
contiennent aussi les fonctionnalits majeures et les problmes de migration ventuels. Les notes de version ne contiennent pas les
modifications qui n'affectent que peu d'utilisateurs ainsi que les modifications internes, non visibles pour les utilisateurs. Par
exemple, l'optimiseur est amlior dans pratiquement chaque version, mais les amliorations ne sont visibles par les utilisateurs
que par la plus grande rapidit des requtes.
Une liste complte de modifications est rcuprable pour chaque version en lisant les validations Git. La liste de diffusion pgsql-committers enregistre en plus toutes les modifications du code source. Il existe aussi une interface web montrant les modifications sur chaque fichier.
Le nom apparaissant auprs de chaque lment prcise le dveloppeur principal de cet lment. Bien sr, toutes les modifications
impliquent des discussions de la communaut et une relecture des correctifs, donc chaque lment est vraiment un travail de la
communaut.

E.1. Release 9.1.14


Release Date
2014-07-24
This release contains a variety of fixes from 9.1.13. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.1.1. Migration to Version 9.1.14


A dump/restore is not required for those running 9.1.X.
However, this release corrects an index corruption problem in some GiST indexes. See the first changelog entry below to find out
whether your installation has been affected and what steps you should take if so.
Also, if you are upgrading from a version earlier than 9.1.11, see Section E.4, Release 9.1.11 .

E.1.2. Changes

Correctly initialize padding bytes in contrib/btree_gist indexes on bit columns (Heikki Linnakangas)
This error could result in incorrect query results due to values that should compare equal not being seen as equal. Users with
GiST indexes on bit or bit varying columns should REINDEX those indexes after installing this update.

Protect against torn pages when deleting GIN list pages (Heikki Linnakangas)
This fix prevents possible index corruption if a system crash occurs while the page update is being written to disk.

Don't clear the right-link of a GiST index page while replaying updates from WAL (Heikki Linnakangas)
This error could lead to transiently wrong answers from GiST index scans performed in Hot Standby.

Fix feedback status when hot_standby is turned off on-the-fly (Simon Riggs)

Fix possibly-incorrect cache invalidation during nested calls to ReceiveSharedInvalidMessages (Andres Freund)

Fix could not find pathkey item to sort planner failures with UNION ALL over subqueries reading from tables with allance
children (Tom Lane)

Don't assume a subquery's output is unique if there's a set-returning function in its targetlist (David Rowley)
This oversight could lead to misoptimization of constructs like WHERE x IN (SELECT y, generate_series(1,10) FROM t GROUP BY y).

Fix failure to detoast fields in composite elements of structured types (Tom Lane)
This corrects cases where TOAST pointers could be copied into other tables without being dereferenced. If the original data is
later deleted, it would lead to errors like missing chunk number 0 for toast value ... when the now-dangling pointer is used.

Fix record type has not been registered failures with whole-row references to the output of Append plan nodes (Tom Lane)
1400

Notes de version

Fix possible crash when invoking a user-defined function while rewinding a cursor (Tom Lane)

Fix query-lifespan memory leak while evaluating the arguments for a function in FROM (Tom Lane)

Fix session-lifespan memory leaks in regular-expression processing (Tom Lane, Arthur O'Dwyer, Greg Stark)

Fix data encoding error in hungarian.stop (Tom Lane)

Prevent foreign tables from being created with OIDS when default_with_oids is true (Etsuro Fujita)

Fix liveness checks for rows that were inserted in the current transaction and then deleted by a now-rolled-back subtransaction
(Andres Freund)
This could cause problems (at least spurious warnings, and at worst an infinite loop) if CREATE INDEX or CLUSTER were
done later in the same transaction.

Clear pg_stat_activity.xact_start during PREPARE TRANSACTION (Andres Freund)


After the PREPARE, the originating session is no longer in a transaction, so it should not continue to display a transaction
start time.

Fix REASSIGN OWNED to not fail for text search objects (lvaro Herrera)

Block signals during postmaster startup (Tom Lane)


This ensures that the postmaster will properly clean up after itself if, for example, it receives SIGINT while still starting up.

Fix client host name lookup when processing pg_hba.conf entries that specify host names instead of IP addresses (Tom
Lane)
Ensure that reverse-DNS lookup failures are reported, instead of just silently not matching such entries. Also ensure that we
make only one reverse-DNS lookup attempt per connection, not one per host name entry, which is what previously happened
if the lookup attempts failed.

Secure Unix-domain sockets of temporary postmasters started during make check (Noah Misch)
Any local user able to access the socket file could connect as the server's bootstrap superuser, then proceed to execute arbitrary
code as the operating-system user running the test, as we previously noted in CVE-2014-0067. This change defends against
that risk by placing the server's socket in a temporary, mode 0700 subdirectory of /tmp. The hazard remains however on platforms where Unix sockets are not supported, notably Windows, because then the temporary postmaster must accept local TCP
connections.
A useful side effect of this change is to simplify make check testing in builds that override DEFAULT_PGSOCKET_DIR.
Popular non-default values like /var/run/postgresql are often not writable by the build user, requiring workarounds
that will no longer be necessary.

Fix tablespace creation WAL replay to work on Windows (MauMau)

Fix detection of socket creation failures on Windows (Bruce Momjian)

On Windows, allow new sessions to absorb values of PGC_BACKEND parameters (such as log_connections) from the configuration file (Amit Kapila)
Previously, if such a parameter were changed in the file post-startup, the change would have no effect.

Properly quote executable path names on Windows (Nikhil Deshpande)


This oversight could cause initdb and pg_upgrade to fail on Windows, if the installation path contained both spaces and @ signs.

Fix linking of libpython on OS X (Tom Lane)


The method we previously used can fail with the Python library supplied by Xcode 5.0 and later.

Avoid buffer bloat in libpq when the server consistently sends data faster than the client can absorb it (Shin-ichi Morita, Tom
Lane)
libpq could be coerced into enlarging its input buffer until it runs out of memory (which would be reported misleadingly as
lost synchronization with server ). Under ordinary circumstances it's quite far-fetched that data could be continuously transmitted more quickly than the recv() loop can absorb it, but this has been observed when the client is artificially slowed by
scheduler constraints.

Ensure that LDAP lookup attempts in libpq time out as intended (Laurenz Albe)

Fix ecpg to do the right thing when an array of char * is the target for a FETCH statement returning more than one row, as
1401

Notes de version

well as some other array-handling fixes (Ashutosh Bapat)

Fix pg_restore's processing of old-style large object comments (Tom Lane)


A direct-to-database restore from an archive file generated by a pre-9.0 version of pg_dump would usually fail if the archive
contained more than a few comments for large objects.

In contrib/pgcrypto functions, ensure sensitive information is cleared from stack variables before returning (Marko
Kreen)

In contrib/uuid-ossp, cache the state of the OSSP UUID library across calls (Tom Lane)
This improves the efficiency of UUID generation and reduces the amount of entropy drawn from /dev/urandom, on platforms that have that.

Update time zone data files to tzdata release 2014e for DST law changes in Crimea, Egypt, and Morocco.

E.2. Release 9.1.13


Release Date
2014-03-20
This release contains a variety of fixes from 9.1.12. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.2.1. Migration to Version 9.1.13


A dump/restore is not required for those running 9.1.X.
However, if you are upgrading from a version earlier than 9.1.11, see Section E.4, Release 9.1.11 .

E.2.2. Changes

Restore GIN metapages unconditionally to avoid torn-page risk (Heikki Linnakangas)


Although this oversight could theoretically result in a corrupted index, it is unlikely to have caused any problems in practice,
since the active part of a GIN metapage is smaller than a standard 512-byte disk sector.

Avoid race condition in checking transaction commit status during receipt of a NOTIFY message (Marko Tiikkaja)
This prevents a scenario wherein a sufficiently fast client might respond to a notification before database updates made by the
notifier have become visible to the recipient.

Allow regular-expression operators to be terminated early by query cancel requests (Tom Lane)
This prevents scenarios wherein a pathological regular expression could lock up a server process uninterruptably for a long
time.

Remove incorrect code that tried to allow OVERLAPS with single-element row arguments (Joshua Yanovski)
This code never worked correctly, and since the case is neither specified by the SQL standard nor documented, it seemed better to remove it than fix it.

Avoid getting more than AccessShareLock when de-parsing a rule or view (Dean Rasheed)
This oversight resulted in pg_dump unexpectedly acquiring RowExclusiveLock locks on tables mentioned as the targets
of INSERT/UPDATE/DELETE commands in rules. While usually harmless, that could interfere with concurrent transactions
that tried to acquire, for example, ShareLock on those tables.

Improve performance of index endpoint probes during planning (Tom Lane)


This change fixes a significant performance problem that occurred when there were many not-yet-committed rows at the end
of the index, which is a common situation for indexes on sequentially-assigned values such as timestamps or sequence-generated identifiers.

Fix walsender's failure to shut down cleanly when client is pg_receivexlog (Fujii Masao)

Fix test to see if hot standby connections can be allowed immediately after a crash (Heikki Linnakangas)
1402

Notes de version

Prevent interrupts while reporting non-ERROR messages (Tom Lane)


This guards against rare server-process freezeups due to recursive entry to syslog(), and perhaps other related problems.

Fix memory leak in PL/Perl when returning a composite result, including multiple-OUT-parameter cases (Alex Hunsaker)

Prevent intermittent could not reserve shared memory region failures on recent Windows versions (MauMau)

Update time zone data files to tzdata release 2014a for DST law changes in Fiji and Turkey, plus historical changes in Israel
and Ukraine.

E.3. Release 9.1.12


Release Date
2014-02-20
This release contains a variety of fixes from 9.1.11. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.3.1. Migration to Version 9.1.12


A dump/restore is not required for those running 9.1.X.
However, if you are upgrading from a version earlier than 9.1.11, see Section E.4, Release 9.1.11 .

E.3.2. Changes

Shore up GRANT ... WITH ADMIN OPTION restrictions (Noah Misch)


Granting a role without ADMIN OPTION is supposed to prevent the grantee from adding or removing members from the
granted role, but this restriction was easily bypassed by doing SET ROLE first. The security impact is mostly that a role member can revoke the access of others, contrary to the wishes of his grantor. Unapproved role member additions are a lesser
concern, since an uncooperative role member could provide most of his rights to others anyway by creating views or SECURITY DEFINER functions. (CVE-2014-0060)

Prevent privilege escalation via manual calls to PL validator functions (Andres Freund)
The primary role of PL validator functions is to be called implicitly during CREATE FUNCTION, but they are also normal
SQL functions that a user can call explicitly. Calling a validator on a function actually written in some other language was not
checked for and could be exploited for privilege-escalation purposes. The fix involves adding a call to a privilege-checking
function in each validator function. Non-core procedural languages will also need to make this change to their own validator
functions, if any. (CVE-2014-0061)

Avoid multiple name lookups during table and index DDL (Robert Haas, Andres Freund)
If the name lookups come to different conclusions due to concurrent activity, we might perform some parts of the DDL on a
different table than other parts. At least in the case of CREATE INDEX, this can be used to cause the permissions checks to
be performed against a different table than the index creation, allowing for a privilege escalation attack. (CVE-2014-0062)

Prevent buffer overrun with long datetime strings (Noah Misch)


The MAXDATELEN constant was too small for the longest possible value of type interval, allowing a buffer overrun in interval_out(). Although the datetime input functions were more careful about avoiding buffer overrun, the limit was short
enough to cause them to reject some valid inputs, such as input containing a very long timezone name. The ecpg library
contained these vulnerabilities along with some of its own. (CVE-2014-0063)

Prevent buffer overrun due to integer overflow in size calculations (Noah Misch, Heikki Linnakangas)
Several functions, mostly type input functions, calculated an allocation size without checking for overflow. If overflow did occur, a too-small buffer would be allocated and then written past. (CVE-2014-0064)

Prevent overruns of fixed-size buffers (Peter Eisentraut, Jozef Mlich)


Use strlcpy() and related functions to provide a clear guarantee that fixed-size buffers are not overrun. Unlike the preceding items, it is unclear whether these cases really represent live issues, since in most cases there appear to be previous
constraints on the size of the input string. Nonetheless it seems prudent to silence all Coverity warnings of this type.
1403

Notes de version

(CVE-2014-0065)

Avoid crashing if crypt() returns NULL (Honza Horak, Bruce Momjian)


There are relatively few scenarios in which crypt() could return NULL, but contrib/chkpass would crash if it did.
One practical case in which this could be an issue is if libc is configured to refuse to execute unapproved hashing algorithms
(e.g., FIPS mode ). (CVE-2014-0066)

Document risks of make check in the regression testing instructions (Noah Misch, Tom Lane)
Since the temporary server started by make check uses trust authentication, another user on the same machine could
connect to it as database superuser, and then potentially exploit the privileges of the operating-system user who started the
tests. A future release will probably incorporate changes in the testing procedure to prevent this risk, but some public discussion is needed first. So for the moment, just warn people against using make check when there are untrusted users on the
same machine. (CVE-2014-0067)

Fix possible mis-replay of WAL records when some segments of a relation aren't full size (Greg Stark, Tom Lane)
The WAL update could be applied to the wrong page, potentially many pages past where it should have been. Aside from corrupting data, this error has been observed to result in significant bloat of standby servers compared to their masters, due to
updates being applied far beyond where the end-of-file should have been. This failure mode does not appear to be a significant
risk during crash recovery, only when initially synchronizing a standby created from a base backup taken from a quicklychanging master.

Fix bug in determining when recovery has reached consistency (Tomonari Katsumata, Heikki Linnakangas)
In some cases WAL replay would mistakenly conclude that the database was already consistent at the start of replay, thus possibly allowing hot-standby queries before the database was really consistent. Other symptoms such as PANIC: WAL
contains references to invalid pages were also possible.

Fix improper locking of btree index pages while replaying a VACUUM operation in hot-standby mode (Andres Freund, Heikki
Linnakangas, Tom Lane)
This error could result in PANIC: WAL contains references to invalid pages failures.

Ensure that insertions into non-leaf GIN index pages write a full-page WAL record when appropriate (Heikki Linnakangas)
The previous coding risked index corruption in the event of a partial-page write during a system crash.

When pause_at_recovery_target and recovery_target_inclusive are both set, ensure the target record is
applied before pausing, not after (Heikki Linnakangas)

Fix race conditions during server process exit (Robert Haas)


Ensure that signal handlers don't attempt to use the process's MyProc pointer after it's no longer valid.

Fix race conditions in walsender shutdown logic and walreceiver SIGHUP signal handler (Tom Lane)

Fix unsafe references to errno within error reporting logic (Christian Kruse)
This would typically lead to odd behaviors such as missing or inappropriate HINT fields.

Fix possible crashes from using ereport() too early during server startup (Tom Lane)
The principal case we've seen in the field is a crash if the server is started in a directory it doesn't have permission to read.

Clear retry flags properly in OpenSSL socket write function (Alexander Kukushkin)
This omission could result in a server lockup after unexpected loss of an SSL-encrypted connection.

Fix length checking for Unicode identifiers (U&"..." syntax) containing escapes (Tom Lane)
A spurious truncation warning would be printed for such identifiers if the escaped form of the identifier was too long, but the
identifier actually didn't need truncation after de-escaping.

Allow keywords that are type names to be used in lists of roles (Stephen Frost)
A previous patch allowed such keywords to be used without quoting in places such as role identifiers; but it missed cases
where a list of role identifiers was permitted, such as DROP ROLE.

Fix parser crash for EXISTS(SELECT * FROM zero_column_table) (Tom Lane)

Fix possible crash due to invalid plan for nested sub-selects, such as WHERE (... x IN (SELECT ...) ...) IN
(SELECT ...) (Tom Lane)

1404

Notes de version

Ensure that ANALYZE creates statistics for a table column even when all the values in it are too wide (Tom Lane)
ANALYZE intentionally omits very wide values from its histogram and most-common-values calculations, but it neglected to
do something sane in the case that all the sampled entries are too wide.

In ALTER TABLE ... SET TABLESPACE, allow the database's default tablespace to be used without a permissions
check (Stephen Frost)
CREATE TABLE has always allowed such usage, but ALTER TABLE didn't get the memo.

Fix cannot accept a set error when some arms of a CASE return a set and others don't (Tom Lane)

Fix checks for all-zero client addresses in pgstat functions (Kevin Grittner)

Fix possible misclassification of multibyte characters by the text search parser (Tom Lane)
Non-ASCII characters could be misclassified when using C locale with a multibyte encoding. On Cygwin, non-C locales could
fail as well.

Fix possible misbehavior in plainto_tsquery() (Heikki Linnakangas)


Use memmove() not memcpy() for copying overlapping memory regions. There have been no field reports of this actually
causing trouble, but it's certainly risky.

Fix placement of permissions checks in pg_start_backup() and pg_stop_backup() (Andres Freund, Magnus Hagander)
The previous coding might attempt to do catalog access when it shouldn't.

Accept SHIFT_JIS as an encoding name for locale checking purposes (Tatsuo Ishii)

Fix misbehavior of PQhost() on Windows (Fujii Masao)


It should return localhost if no host has been specified.

Improve error handling in libpq and psql for failures during COPY TO STDOUT/FROM STDIN (Tom Lane)
In particular this fixes an infinite loop that could occur in 9.2 and up if the server connection was lost during COPY FROM
STDIN. Variants of that scenario might be possible in older versions, or with other client applications.

Fix possible incorrect printing of filenames in pg_basebackup's verbose mode (Magnus Hagander)

Avoid including tablespaces inside PGDATA twice in base backups (Dimitri Fontaine, Magnus Hagander)

Fix misaligned descriptors in ecpg (MauMau)

In ecpg, handle lack of a hostname in the connection parameters properly (Michael Meskes)

Fix performance regression in contrib/dblink connection startup (Joe Conway)


Avoid an unnecessary round trip when client and server encodings match.

In contrib/isn, fix incorrect calculation of the check digit for ISMN values (Fabien Coelho)

Ensure client-code-only installation procedure works as documented (Peter Eisentraut)

In Mingw and Cygwin builds, install the libpq DLL in the bin directory (Andrew Dunstan)
This duplicates what the MSVC build has long done. It should fix problems with programs like psql failing to start because
they can't find the DLL.

Avoid using the deprecated dllwrap tool in Cygwin builds (Marco Atzeri)

Don't generate plain-text HISTORY and src/test/regress/README files anymore (Tom Lane)
These text files duplicated the main HTML and PDF documentation formats. The trouble involved in maintaining them greatly
outweighs the likely audience for plain-text format. Distribution tarballs will still contain files by these names, but they'll just
be stubs directing the reader to consult the main documentation. The plain-text INSTALL file will still be maintained, as there
is arguably a use-case for that.

Update time zone data files to tzdata release 2013i for DST law changes in Jordan and historical changes in Cuba.
In addition, the zones Asia/Riyadh87, Asia/Riyadh88, and Asia/Riyadh89 have been removed, as they are no longer maintained by IANA, and never represented actual civil timekeeping practice.

1405

Notes de version

E.4. Release 9.1.11


Release Date
2013-12-05
This release contains a variety of fixes from 9.1.10. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.4.1. Migration to Version 9.1.11


A dump/restore is not required for those running 9.1.X.
However, this release corrects a number of potential data corruption issues. See the first two changelog entries below to find out
whether your installation has been affected and what steps you can take if so.
Also, if you are upgrading from a version earlier than 9.1.9, see Section E.6, Release 9.1.9 .

E.4.2. Changes

Fix VACUUM's tests to see whether it can update relfrozenxid (Andres Freund)
In some cases VACUUM (either manual or autovacuum) could incorrectly advance a table's relfrozenxid value, allowing
tuples to escape freezing, causing those rows to become invisible once 2^31 transactions have elapsed. The probability of data
loss is fairly low since multiple incorrect advancements would need to happen before actual loss occurs, but it's not zero. Users
upgrading from releases 9.0.4 or 8.4.8 or earlier are not affected, but all later versions contain the bug.
The issue can be ameliorated by, after upgrading, vacuuming all tables in all databases while having vacuum_freeze_table_age set to zero. This will fix any latent corruption but will not be able to fix all pre-existing data
errors. However, an installation can be presumed safe after performing this vacuuming if it has executed fewer than 2^31 update transactions in its lifetime (check this with SELECT txid_current() < 2^31).

Fix initialization of pg_clog and pg_subtrans during hot standby startup (Andres Freund, Heikki Linnakangas)
This bug can cause data loss on standby servers at the moment they start to accept hot-standby queries, by marking committed
transactions as uncommitted. The likelihood of such corruption is small unless, at the time of standby startup, the primary server has executed many updating transactions since its last checkpoint. Symptoms include missing rows, rows that should have
been deleted being still visible, and obsolete versions of updated rows being still visible alongside their newer versions.
This bug was introduced in versions 9.3.0, 9.2.5, 9.1.10, and 9.0.14. Standby servers that have only been running earlier releases are not at risk. It's recommended that standby servers that have ever run any of the buggy releases be re-cloned from the
primary (e.g., with a new base backup) after upgrading.

Truncate pg_multixact contents during WAL replay (Andres Freund)


This avoids ever-increasing disk space consumption in standby servers.

Fix race condition in GIN index posting tree page deletion (Heikki Linnakangas)
This could lead to transient wrong answers or query failures.

Avoid flattening a subquery whose SELECT list contains a volatile function wrapped inside a sub-SELECT (Tom Lane)
This avoids unexpected results due to extra evaluations of the volatile function.

Fix planner's processing of non-simple-variable subquery outputs nested within outer joins (Tom Lane)
This error could lead to incorrect plans for queries involving multiple levels of subqueries within JOIN syntax.

Fix incorrect generation of optimized MIN()/MAX() plans for allance trees (Tom Lane)
The planner could fail in cases where the MIN()/MAX() argument was an expression rather than a simple variable.

Fix premature deletion of temporary files (Andres Freund)

Fix possible read past end of memory in rule printing (Peter Eisentraut)

Fix array slicing of int2vector and oidvector values (Tom Lane)


Expressions of this kind are now implicitly promoted to regular int2 or oid arrays.

Fix incorrect behaviors when using a SQL-standard, simple GMT offset timezone (Tom Lane)
1406

Notes de version

In some cases, the system would use the simple GMT offset value when it should have used the regular timezone setting that
had prevailed before the simple offset was selected. This change also causes the timeofday function to honor the simple
GMT offset zone.

Prevent possible misbehavior when logging translations of Windows error codes (Tom Lane)

Properly quote generated command lines in pg_ctl (Naoya Anzai and Tom Lane)
This fix applies only to Windows.

Fix pg_dumpall to work when a source database sets default_transaction_read_only via ALTER DATABASE
SET (Kevin Grittner)
Previously, the generated script would fail during restore.

Make ecpg search for quoted cursor names case-sensitively (Zoltn Bszrmnyi)

Fix ecpg's processing of lists of variables declared varchar (Zoltn Bszrmnyi)

Make contrib/lo defend against incorrect trigger definitions (Marc Cousin)

Update time zone data files to tzdata release 2013h for DST law changes in Argentina, Brazil, Jordan, Libya, Liechtenstein,
Morocco, and Palestine. Also, new timezone abbreviations WIB, WIT, WITA for Indonesia.

E.5. Release 9.1.10


Release Date
2013-10-10
This release contains a variety of fixes from 9.1.9. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.5.1. Migration to Version 9.1.10


A dump/restore is not required for those running 9.1.X.
However, if you are upgrading from a version earlier than 9.1.9, see Section E.6, Release 9.1.9 .

E.5.2. Changes

Prevent corruption of multi-byte characters when attempting to case-fold identifiers (Andrew Dunstan)
PostgreSQL case-folds non-ASCII characters only when using a single-byte server encoding.

Fix checkpoint memory leak in background writer when wal_level = hot_standby (Naoya Anzai)

Fix memory leak caused by lo_open() failure (Heikki Linnakangas)

Fix memory overcommit bug when work_mem is using more than 24GB of memory (Stephen Frost)

Serializable snapshot fixes (Kevin Grittner, Heikki Linnakangas)

Fix deadlock bug in libpq when using SSL (Stephen Frost)

Fix possible SSL state corruption in threaded libpq applications (Nick Phillips, Stephen Frost)

Properly compute row estimates for boolean columns containing many NULL values (Andrew Gierth)
Previously tests like col IS NOT TRUE and col IS NOT FALSE did not properly factor in NULL values when estimating plan costs.

Prevent pushing down WHERE clauses into unsafe UNION/INTERSECT subqueries (Tom Lane)
Subqueries of a UNION or INTERSECT that contain set-returning functions or volatile functions in their SELECT lists could
be improperly optimized, leading to run-time errors or incorrect query results.

Fix rare case of failed to locate grouping columns planner failure (Tom Lane)

Fix pg_dump of foreign tables with dropped columns (Andrew Dunstan)


1407

Notes de version

Previously such cases could cause a pg_upgrade error.

Reorder pg_dump processing of extension-related rules and event triggers (Joe Conway)

Force dumping of extension tables if specified by pg_dump -t or -n (Joe Conway)

Improve view dumping code's handling of dropped columns in referenced tables (Tom Lane)

Fix pg_restore -l with the directory archive to display the correct format name (Fujii Masao)

Properly record index comments created using UNIQUE and PRIMARY KEY syntax (Andres Freund)
This fixes a parallel pg_restore failure.

Properly guarantee transmission of WAL files before clean switchover (Fujii Masao)
Previously, the streaming replication connection might close before all WAL files had been replayed on the standby.

Fix WAL segment timeline handling during recovery (Mitsumasa Kondo, Heikki Linnakangas)
WAL file recycling during standby recovery could lead to premature recovery completion, resulting in data loss.

Fix REINDEX TABLE and REINDEX DATABASE to properly revalidate constraints and mark invalidated indexes as valid
(Noah Misch)
REINDEX INDEX has always worked properly.

Fix possible deadlock during concurrent CREATE INDEX CONCURRENTLY operations (Tom Lane)

Fix regexp_matches() handling of zero-length matches (Jeevan Chalke)


Previously, zero-length matches like '^' could return too many matches.

Fix crash for overly-complex regular expressions (Heikki Linnakangas)

Fix regular expression match failures for back references combined with non-greedy quantifiers (Jeevan Chalke)

Prevent CREATE FUNCTION from checking SET variables unless function body checking is enabled (Tom Lane)

Allow ALTER DEFAULT PRIVILEGES to operate on schemas without requiring CREATE permission (Tom Lane)

Loosen restriction on keywords used in queries (Tom Lane)


Specifically, lessen keyword restrictions for role names, language names, EXPLAIN and COPY options, and SET values.
This allows COPY ... (FORMAT BINARY) to work as expected; previously BINARY needed to be quoted.

Fix pgp_pub_decrypt() so it works for secret keys with passwords (Marko Kreen)

Make pg_upgrade use pg_dump --quote-all-identifiers to avoid problems with keyword changes between releases (Tom Lane)

Remove rare inaccurate warning during vacuum of index-less tables (Heikki Linnakangas)

Ensure that VACUUM ANALYZE still runs the ANALYZE phase if its attempt to truncate the file is cancelled due to lock
conflicts (Kevin Grittner)

Avoid possible failure when performing transaction control commands (e.g ROLLBACK) in prepared queries (Tom Lane)

Ensure that floating-point data input accepts standard spellings of infinity on all platforms (Tom Lane)
The C99 standard says that allowable spellings are inf, +inf, -inf, infinity, +infinity, and -infinity. Make
sure we recognize these even if the platform's strtod function doesn't.

Expand ability to compare rows to records and arrays (Rafal Rzepecki, Tom Lane)

Update time zone data files to tzdata release 2013d for DST law changes in Israel, Morocco, Palestine, and Paraguay. Also,
historical zone data corrections for Macquarie Island.

E.6. Release 9.1.9


Release Date
2013-04-04

1408

Notes de version

This release contains a variety of fixes from 9.1.8. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.6.1. Migration to Version 9.1.9


A dump/restore is not required for those running 9.1.X.
However, this release corrects several errors in management of GiST indexes. After installing this update, it is advisable to REINDEX any GiST indexes that meet one or more of the conditions described below.
Also, if you are upgrading from a version earlier than 9.1.6, see Section E.9, Release 9.1.6 .

E.6.2. Changes

Fix insecure parsing of server command-line switches (Mitsumasa Kondo, Kyotaro Horiguchi)
A connection request containing a database name that begins with - could be crafted to damage or destroy files within the
server's data directory, even if the request is eventually rejected. (CVE-2013-1899)

Reset OpenSSL randomness state in each postmaster child process (Marko Kreen)
This avoids a scenario wherein random numbers generated by contrib/pgcrypto functions might be relatively easy for
another database user to guess. The risk is only significant when the postmaster is configured with ssl = on but most connections don't use SSL encryption. (CVE-2013-1900)

Make REPLICATION privilege checks test current user not authenticated user (Noah Misch)
An unprivileged database user could exploit this mistake to call pg_start_backup() or pg_stop_backup(), thus
possibly interfering with creation of routine backups. (CVE-2013-1901)

Fix GiST indexes to not use fuzzy geometric comparisons when it's not appropriate to do so (Alexander Korotkov)
The core geometric types perform comparisons using fuzzy equality, but gist_box_same must do exact comparisons,
else GiST indexes using it might become inconsistent. After installing this update, users should REINDEX any GiST indexes
on box, polygon, circle, or point columns, since all of these use gist_box_same.

Fix erroneous range-union and penalty logic in GiST indexes that use contrib/btree_gist for variable-width data
types, that is text, bytea, bit, and numeric columns (Tom Lane)
These errors could result in inconsistent indexes in which some keys that are present would not be found by searches, and also
in useless index bloat. Users are advised to REINDEX such indexes after installing this update.

Fix bugs in GiST page splitting code for multi-column indexes (Tom Lane)
These errors could result in inconsistent indexes in which some keys that are present would not be found by searches, and also
in indexes that are unnecessarily inefficient to search. Users are advised to REINDEX multi-column GiST indexes after installing this update.

Fix gist_point_consistent to handle fuzziness consistently (Alexander Korotkov)


Index scans on GiST indexes on point columns would sometimes yield results different from a sequential scan, because
gist_point_consistent disagreed with the underlying operator code about whether to do comparisons exactly or fuzzily.

Fix buffer leak in WAL replay (Heikki Linnakangas)


This bug could result in incorrect local pin count errors during replay, making recovery impossible.

Fix race condition in DELETE RETURNING (Tom Lane)


Under the right circumstances, DELETE RETURNING could attempt to fetch data from a shared buffer that the current process no longer has any pin on. If some other process changed the buffer meanwhile, this would lead to garbage RETURNING
output, or even a crash.

Fix infinite-loop risk in regular expression compilation (Tom Lane, Don Porter)

Fix potential null-pointer dereference in regular expression compilation (Tom Lane)

Fix to_char() to use ASCII-only case-folding rules where appropriate (Tom Lane)
This fixes misbehavior of some template patterns that should be locale-independent, but mishandled I and i in Turkish
locales.
1409

Notes de version

Fix unwanted rejection of timestamp 1999-12-31 24:00:00 (Tom Lane)

Fix logic error when a single transaction does UNLISTEN then LISTEN (Tom Lane)
The session wound up not listening for notify events at all, though it surely should listen in this case.

Fix possible planner crash after columns have been added to a view that's depended on by another view (Tom Lane)

Remove useless picksplit doesn't support secondary split log messages (Josh Hansen, Tom Lane)
This message seems to have been added in expectation of code that was never written, and probably never will be, since
GiST's default handling of secondary splits is actually pretty good. So stop nagging end users about it.

Fix possible failure to send a session's last few transaction commit/abort counts to the statistics collector (Tom Lane)

Eliminate memory leaks in PL/Perl's spi_prepare() function (Alex Hunsaker, Tom Lane)

Fix pg_dumpall to handle database names containing = correctly (Heikki Linnakangas)

Avoid crash in pg_dump when an incorrect connection string is given (Heikki Linnakangas)

Ignore invalid indexes in pg_dump and pg_upgrade (Michael Paquier, Bruce Momjian)
Dumping invalid indexes can cause problems at restore time, for example if the reason the index creation failed was because it
tried to enforce a uniqueness condition not satisfied by the table's data. Also, if the index creation is in fact still in progress, it
seems reasonable to consider it to be an uncommitted DDL change, which pg_dump wouldn't be expected to dump anyway.
pg_upgrade now also skips invalid indexes rather than failing.

In pg_basebackup, include only the current server version's subdirectory when backing up a tablespace (Heikki Linnakangas)

Add a server version check in pg_basebackup and pg_receivexlog, so they fail cleanly with version combinations that won't
work (Heikki Linnakangas)

Fix contrib/pg_trgm's similarity() function to return zero for trigram-less strings (Tom Lane)
Previously it returned NaN due to internal division by zero.

Update time zone data files to tzdata release 2013b for DST law changes in Chile, Haiti, Morocco, Paraguay, and some Russian areas. Also, historical zone data corrections for numerous places.
Also, update the time zone abbreviation files for recent changes in Russia and elsewhere: CHOT, GET, IRKT, KGT, KRAT,
MAGT, MAWT, MSK, NOVT, OMST, TKT, VLAT, WST, YAKT, YEKT now follow their current meanings, and VOLT
(Europe/Volgograd) and MIST (Antarctica/Macquarie) are added to the default abbreviations list.

E.7. Release 9.1.8


Release Date
2013-02-07
This release contains a variety of fixes from 9.1.7. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.7.1. Migration to Version 9.1.8


A dump/restore is not required for those running 9.1.X.
However, if you are upgrading from a version earlier than 9.1.6, see Section E.9, Release 9.1.6 .

E.7.2. Changes

Prevent execution of enum_recv from SQL (Tom Lane)


The function was misdeclared, allowing a simple SQL command to crash the server. In principle an attacker might be able to
use it to examine the contents of server memory. Our thanks to Sumit Soni (via Secunia SVCRP) for reporting this issue.
(CVE-2013-0255)

Fix multiple problems in detection of when a consistent database state has been reached during WAL replay (Fujii Masao,
Heikki Linnakangas, Simon Riggs, Andres Freund)
1410

Notes de version

Update minimum recovery point when truncating a relation file (Heikki Linnakangas)
Once data has been discarded, it's no longer safe to stop recovery at an earlier point in the timeline.

Fix recycling of WAL segments after changing recovery target timeline (Heikki Linnakangas)

Fix missing cancellations in hot standby mode (Noah Misch, Simon Riggs)
The need to cancel conflicting hot-standby queries would sometimes be missed, allowing those queries to see inconsistent data.

Prevent recovery pause feature from pausing before users can connect (Tom Lane)

Fix SQL grammar to allow subscripting or field selection from a sub-SELECT result (Tom Lane)

Fix performance problems with autovacuum truncation in busy workloads (Jan Wieck)
Truncation of empty pages at the end of a table requires exclusive lock, but autovacuum was coded to fail (and release the
table lock) when there are conflicting lock requests. Under load, it is easily possible that truncation would never occur, resulting in table bloat. Fix by performing a partial truncation, releasing the lock, then attempting to re-acquire the lock and continue. This fix also greatly reduces the average time before autovacuum releases the lock after a conflicting request arrives.

Protect against race conditions when scanning pg_tablespace (Stephen Frost, Tom Lane)
CREATE DATABASE and DROP DATABASE could misbehave if there were concurrent updates of pg_tablespace entries.

Prevent DROP OWNED from trying to drop whole databases or tablespaces (lvaro Herrera)
For safety, ownership of these objects must be reassigned, not dropped.

Fix error in vacuum_freeze_table_age implementation (Andres Freund)


In installations that have existed for more than vacuum_freeze_min_age transactions, this mistake prevented autovacuum from using partial-table scans, so that a full-table scan would always happen instead.

Prevent misbehavior when a RowExpr or XmlExpr is parse-analyzed twice (Andres Freund, Tom Lane)
This mistake could be user-visible in contexts such as CREATE TABLE LIKE INCLUDING INDEXES.

Improve defenses against integer overflow in hashtable sizing calculations (Jeff Davis)

Fix failure to ignore leftover temporary tables after a server crash (Tom Lane)

Reject out-of-range dates in to_date() (Hitoshi Harada)

Fix pg_extension_config_dump() to handle extension-update cases properly (Tom Lane)


This function will now replace any existing entry for the target table, making it usable in extension update scripts.

Fix PL/Python's handling of functions used as triggers on multiple tables (Andres Freund)

Ensure that non-ASCII prompt strings are translated to the correct code page on Windows (Alexander Law, Noah Misch)
This bug affected psql and some other client programs.

Fix possible crash in psql's \? command when not connected to a database (Meng Qingzhong)

Fix possible error if a relation file is removed while pg_basebackup is running (Heikki Linnakangas)

Make pg_dump exclude data of unlogged tables when running on a hot-standby server (Magnus Hagander)
This would fail anyway because the data is not available on the standby server, so it seems most convenient to assume -no-unlogged-table-data automatically.

Fix pg_upgrade to deal with invalid indexes safely (Bruce Momjian)

Fix one-byte buffer overrun in libpq's PQprintTuples (Xi Wang)


This ancient function is not used anywhere by PostgreSQL itself, but it might still be used by some client code.

Make ecpglib use translated messages properly (Chen Huajun)

Properly install ecpg_compat and pgtypes libraries on MSVC (Jiang Guiqing)

Include our version of isinf() in libecpg if it's not provided by the system (Jiang Guiqing)

Rearrange configure's tests for supplied functions so it is not fooled by bogus exports from libedit/libreadline (Christoph Berg)

Ensure Windows build number increases over time (Magnus Hagander)


1411

Notes de version

Make pgxs build executables with the right .exe suffix when cross-compiling for Windows (Zoltan Boszormenyi)

Add new timezone abbreviation FET (Tom Lane)


This is now used in some eastern-European time zones.

E.8. Release 9.1.7


Release Date
2012-12-06
This release contains a variety of fixes from 9.1.6. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.8.1. Migration to Version 9.1.7


A dump/restore is not required for those running 9.1.X.
However, if you are upgrading from a version earlier than 9.1.6, see Section E.9, Release 9.1.6 .

E.8.2. Changes

Fix multiple bugs associated with CREATE INDEX CONCURRENTLY (Andres Freund, Tom Lane)
Fix CREATE INDEX CONCURRENTLY to use in-place updates when changing the state of an index's pg_index row. This
prevents race conditions that could cause concurrent sessions to miss updating the target index, thus resulting in corrupt
concurrently-created indexes.
Also, fix various other operations to ensure that they ignore invalid indexes resulting from a failed CREATE INDEX
CONCURRENTLY command. The most important of these is VACUUM, because an auto-vacuum could easily be launched
on the table before corrective action can be taken to fix or remove the invalid index.

Fix buffer locking during WAL replay (Tom Lane)


The WAL replay code was insufficiently careful about locking buffers when replaying WAL records that affect more than one
page. This could result in hot standby queries transiently seeing inconsistent states, resulting in wrong answers or unexpected
failures.

Fix an error in WAL generation logic for GIN indexes (Tom Lane)
This could result in index corruption, if a torn-page failure occurred.

Properly remove startup process's virtual XID lock when promoting a hot standby server to normal running (Simon Riggs)
This oversight could prevent subsequent execution of certain operations such as CREATE INDEX CONCURRENTLY.

Avoid bogus out-of-sequence timeline ID errors in standby mode (Heikki Linnakangas)

Prevent the postmaster from launching new child processes after it's received a shutdown signal (Tom Lane)
This mistake could result in shutdown taking longer than it should, or even never completing at all without additional user action.

Avoid corruption of internal hash tables when out of memory (Hitoshi Harada)

Prevent file descriptors for dropped tables from being held open past transaction end (Tom Lane)
This should reduce problems with long-since-dropped tables continuing to occupy disk space.

Prevent database-wide crash and restart when a new child process is unable to create a pipe for its latch (Tom Lane)
Although the new process must fail, there is no good reason to force a database-wide restart, so avoid that. This improves robustness when the kernel is nearly out of file descriptors.

Fix planning of non-strict equivalence clauses above outer joins (Tom Lane)
The planner could derive incorrect constraints from a clause equating a non-strict construct to something else, for example
WHERE COALESCE(foo, 0) = 0 when foo is coming from the nullable side of an outer join.

Fix SELECT DISTINCT with index-optimized MIN/MAX on an allance tree (Tom Lane)
1412

Notes de version

The planner would fail with failed to re-find MinMaxAggInfo record given this combination of factors.

Improve planner's ability to prove exclusion constraints from equivalence classes (Tom Lane)

Fix partial-row matching in hashed subplans to handle cross-type cases correctly (Tom Lane)
This affects multicolumn NOT IN subplans, such as WHERE (a, b) NOT IN (SELECT x, y FROM ...) when for
instance b and y are int4 and int8 respectively. This mistake led to wrong answers or crashes depending on the specific datatypes involved.

Acquire buffer lock when re-fetching the old tuple for an AFTER ROW UPDATE/DELETE trigger (Andres Freund)
In very unusual circumstances, this oversight could result in passing incorrect data to a trigger WHEN condition, or to the precheck logic for a foreign-key enforcement trigger. That could result in a crash, or in an incorrect decision about whether to fire
the trigger.

Fix ALTER COLUMN TYPE to handle alled check constraints properly (Pavan Deolasee)
This worked correctly in pre-8.4 releases, and now works correctly in 8.4 and later.

Fix ALTER EXTENSION SET SCHEMA's failure to move some subsidiary objects into the new schema (lvaro Herrera,
Dimitri Fontaine)

Fix REASSIGN OWNED to handle grants on tablespaces (lvaro Herrera)

Ignore incorrect pg_attribute entries for system columns for views (Tom Lane)
Views do not have any system columns. However, we forgot to remove such entries when converting a table to a view. That's
fixed properly for 9.3 and later, but in previous branches we need to defend against existing mis-converted views.

Fix rule printing to dump INSERT INTO table DEFAULT VALUES correctly (Tom Lane)

Guard against stack overflow when there are too many UNION/INTERSECT/EXCEPT clauses in a query (Tom Lane)

Prevent platform-dependent failures when dividing the minimum possible integer value by -1 (Xi Wang, Tom Lane)

Fix possible access past end of string in date parsing (Hitoshi Harada)

Fix failure to advance XID epoch if XID wraparound happens during a checkpoint and wal_level is hot_standby (Tom
Lane, Andres Freund)
While this mistake had no particular impact on PostgreSQL itself, it was bad for applications that rely on
txid_current() and related functions: the TXID value would appear to go backwards.

Fix display of pg_stat_replication.sync_state at a page boundary (Kyotaro Horiguchi)

Produce an understandable error message if the length of the path name for a Unix-domain socket exceeds the platform-specific limit (Tom Lane, Andrew Dunstan)
Formerly, this would result in something quite unhelpful, such as Non-recoverable failure in name resolution .

Fix memory leaks when sending composite column values to the client (Tom Lane)

Make pg_ctl more robust about reading the postmaster.pid file (Heikki Linnakangas)
Fix race conditions and possible file descriptor leakage.

Fix possible crash in psql if incorrectly-encoded data is presented and the client_encoding setting is a client-only encoding, such as SJIS (Jiang Guiqing)

Make pg_dump dump SEQUENCE SET items in the data not pre-data section of the archive (Tom Lane)
This change fixes dumping of sequences that are marked as extension configuration tables.

Fix bugs in the restore.sql script emitted by pg_dump in tar output format (Tom Lane)
The script would fail outright on tables whose names include upper-case characters. Also, make the script capable of restoring
data in --inserts mode as well as the regular COPY mode.

Fix pg_restore to accept POSIX-conformant tar files (Brian Weaver, Tom Lane)
The original coding of pg_dump's tar output mode produced files that are not fully conformant with the POSIX standard.
This has been corrected for version 9.3. This patch updates previous branches so that they will accept both the incorrect and
the corrected formats, in hopes of avoiding compatibility problems when 9.3 comes out.

Fix tar files emitted by pg_basebackup to be POSIX conformant (Brian Weaver, Tom Lane)
1413

Notes de version

Fix pg_resetxlog to locate postmaster.pid correctly when given a relative path to the data directory (Tom Lane)
This mistake could lead to pg_resetxlog not noticing that there is an active postmaster using the data directory.

Fix libpq's lo_import() and lo_export() functions to report file I/O errors properly (Tom Lane)

Fix ecpg's processing of nested structure pointer variables (Muhammad Usama)

Fix ecpg's ecpg_get_data function to handle arrays properly (Michael Meskes)

Make contrib/pageinspect's btree page inspection functions take buffer locks while examining pages (Tom Lane)

Ensure that make install for an extension creates the extension installation directory (Cdric Villemain)
Previously, this step was missed if MODULEDIR was set in the extension's Makefile.

Fix pgxs support for building loadable modules on AIX (Tom Lane)
Building modules outside the original source tree didn't work on AIX.

Update time zone data files to tzdata release 2012j for DST law changes in Cuba, Israel, Jordan, Libya, Palestine, Western Samoa, and portions of Brazil.

E.9. Release 9.1.6


Release Date
2012-09-24
This release contains a variety of fixes from 9.1.5. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.9.1. Migration to Version 9.1.6


A dump/restore is not required for those running 9.1.X.
However, you may need to perform REINDEX operations to recover from the effects of the data corruption bug described in the
first changelog item below.
Also, if you are upgrading from a version earlier than 9.1.4, see Section E.11, Release 9.1.4 .

E.9.2. Changes

Fix persistence marking of shared buffers during WAL replay (Jeff Davis)
This mistake can result in buffers not being written out during checkpoints, resulting in data corruption if the server later
crashes without ever having written those buffers. Corruption can occur on any server following crash recovery, but it is significantly more likely to occur on standby slave servers since those perform much more WAL replay. There is a low probability
of corruption of btree and GIN indexes. There is a much higher probability of corruption of table visibility maps . Fortunately, visibility maps are non-critical data in 9.1, so the worst consequence of such corruption in 9.1 installations is transient inefficiency of vacuuming. Table data proper cannot be corrupted by this bug.
While no index corruption due to this bug is known to have occurred in the field, as a precautionary measure it is recommended that production installations REINDEX all btree and GIN indexes at a convenient time after upgrading to 9.1.6.
Also, if you intend to do an in-place upgrade to 9.2.X, before doing so it is recommended to perform a VACUUM of all tables
while having vacuum_freeze_table_age set to zero. This will ensure that any lingering wrong data in the visibility
maps is corrected before 9.2.X can depend on it. vacuum_cost_delay can be adjusted to reduce the performance impact
of vacuuming, while causing it to take longer to finish.

Fix planner's assignment of executor parameters, and fix executor's rescan logic for CTE plan nodes (Tom Lane)
These errors could result in wrong answers from queries that scan the same WITH subquery multiple times.

Fix misbehavior when default_transaction_isolation is set to serializable (Kevin Grittner, Tom Lane,
Heikki Linnakangas)
Symptoms include crashes at process start on Windows, and crashes in hot standby operation.

Improve selectivity estimation for text search queries involving prefixes, i.e. word:* patterns (Tom Lane)
1414

Notes de version

Improve page-splitting decisions in GiST indexes (Alexander Korotkov, Robert Haas, Tom Lane)
Multi-column GiST indexes might suffer unexpected bloat due to this error.

Fix cascading privilege revoke to stop if privileges are still held (Tom Lane)
If we revoke a grant option from some role X, but X still holds that option via a grant from someone else, we should not recursively revoke the corresponding privilege from role(s) Y that X had granted it to.

Disallow extensions from containing the schema they are assigned to (Thom Brown)
This situation creates circular dependencies that confuse pg_dump and probably other things. It's confusing for humans too, so
disallow it.

Improve error messages for Hot Standby misconfiguration errors (Gurjeet Singh)

Make configure probe for mbstowcs_l (Tom Lane)


This fixes build failures on some versions of AIX.

Fix handling of SIGFPE when PL/Perl is in use (Andres Freund)


Perl resets the process's SIGFPE handler to SIG_IGN, which could result in crashes later on. Restore the normal Postgres signal handler after initializing PL/Perl.

Prevent PL/Perl from crashing if a recursive PL/Perl function is redefined while being executed (Tom Lane)

Work around possible misoptimization in PL/Perl (Tom Lane)


Some Linux distributions contain an incorrect version of pthread.h that results in incorrect compiled code in PL/Perl, leading to crashes if a PL/Perl function calls another one that throws an error.

Fix bugs in contrib/pg_trgm's LIKE pattern analysis code (Fujii Masao)


LIKE queries using a trigram index could produce wrong results if the pattern contained LIKE escape characters.

Fix pg_upgrade's handling of line endings on Windows (Andrew Dunstan)


Previously, pg_upgrade might add or remove carriage returns in places such as function bodies.

On Windows, make pg_upgrade use backslash path separators in the scripts it emits (Andrew Dunstan)

Remove unnecessary dependency on pg_config from pg_upgrade (Peter Eisentraut)

Update time zone data files to tzdata release 2012f for DST law changes in Fiji

E.10. Release 9.1.5


Release Date
2012-08-17
This release contains a variety of fixes from 9.1.4. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.10.1. Migration to Version 9.1.5


A dump/restore is not required for those running 9.1.X.
However, if you are upgrading from a version earlier than 9.1.4, see Section E.11, Release 9.1.4 .

E.10.2. Changes

Prevent access to external files/URLs via XML entity references (Noah Misch, Tom Lane)
xml_parse() would attempt to fetch external files or URLs as needed to resolve DTD and entity references in an XML value, thus allowing unprivileged database users to attempt to fetch data with the privileges of the database server. While the external data wouldn't get returned directly to the user, portions of it could be exposed in error messages if the data didn't parse
as valid XML; and in any case the mere ability to check existence of a file might be useful to an attacker. (CVE-2012-3489)
1415

Notes de version

Prevent access to external files/URLs via contrib/xml2's xslt_process() (Peter Eisentraut)


libxslt offers the ability to read and write both files and URLs through stylesheet commands, thus allowing unprivileged database users to both read and write data with the privileges of the database server. Disable that through proper use of libxslt's security options. (CVE-2012-3488)
Also, remove xslt_process()'s ability to fetch documents and stylesheets from external files/URLs. While this was a documented feature , it was long regarded as a bad idea. The fix for CVE-2012-3489 broke that capability, and rather than expend effort on trying to fix it, we're just going to summarily remove it.

Prevent too-early recycling of btree index pages (Noah Misch)


When we allowed read-only transactions to skip assigning XIDs, we introduced the possibility that a deleted btree page could
be recycled while a read-only transaction was still in flight to it. This would result in incorrect index search results. The probability of such an error occurring in the field seems very low because of the timing requirements, but nonetheless it should be
fixed.

Fix crash-safety bug with newly-created-or-reset sequences (Tom Lane)


If ALTER SEQUENCE was executed on a freshly created or reset sequence, and then precisely one nextval() call was
made on it, and then the server crashed, WAL replay would restore the sequence to a state in which it appeared that no nextval() had been done, thus allowing the first sequence value to be returned again by the next nextval() call. In particular
this could manifest for serial columns, since creation of a serial column's sequence includes an ALTER SEQUENCE OWNED BY step.

Fix race condition in enum-type value comparisons (Robert Haas, Tom Lane)
Comparisons could fail when encountering an enum value added since the current query started.

Fix txid_current() to report the correct epoch when not in hot standby (Heikki Linnakangas)
This fixes a regression introduced in the previous minor release.

Prevent selection of unsuitable replication connections as the synchronous standby (Fujii Masao)
The master might improperly choose pseudo-servers such as pg_receivexlog or pg_basebackup as the synchronous standby,
and then wait indefinitely for them.

Fix bug in startup of Hot Standby when a master transaction has many subtransactions (Andres Freund)
This mistake led to failures reported as out-of-order XID insertion in KnownAssignedXids .

Ensure the backup_label file is fsync'd after pg_start_backup() (Dave Kerr)

Fix timeout handling in walsender processes (Tom Lane)


WAL sender background processes neglected to establish a SIGALRM handler, meaning they would wait forever in some corner cases where a timeout ought to happen.

Wake walsenders after each background flush by walwriter (Andres Freund, Simon Riggs)
This greatly reduces replication delay when the workload contains only asynchronously-committed transactions.

Fix LISTEN/NOTIFY to cope better with I/O problems, such as out of disk space (Tom Lane)
After a write failure, all subsequent attempts to send more NOTIFY messages would fail with messages like Could not read
from file "pg_notify/nnnn" at offset nnnnn: Success .

Only allow autovacuum to be auto-canceled by a directly blocked process (Tom Lane)


The original coding could allow inconsistent behavior in some cases; in particular, an autovacuum could get canceled after less
than deadlock_timeout grace period.

Improve logging of autovacuum cancels (Robert Haas)

Fix log collector so that log_truncate_on_rotation works during the very first log rotation after server start (Tom
Lane)

Fix WITH attached to a nested set operation (UNION/INTERSECT/EXCEPT) (Tom Lane)

Ensure that a whole-row reference to a subquery doesn't include any extra GROUP BY or ORDER BY columns (Tom Lane)

Fix dependencies generated during ALTER TABLE ... ADD CONSTRAINT USING INDEX (Tom Lane)
This command left behind a redundant pg_depend entry for the index, which could confuse later operations, notably ALTER
1416

Notes de version

TABLE ... ALTER COLUMN TYPE on one of the indexed columns.

Fix REASSIGN OWNED to work on extensions (Alvaro Herrera)

Disallow copying whole-row references in CHECK constraints and index definitions during CREATE TABLE (Tom Lane)
This situation can arise in CREATE TABLE with LIKE or INHERITS. The copied whole-row variable was incorrectly labeled with the row type of the original table not the new one. Rejecting the case seems reasonable for LIKE, since the row types
might well diverge later. For INHERITS we should ideally allow it, with an implicit coercion to the parent table's row type;
but that will require more work than seems safe to back-patch.

Fix memory leak in ARRAY(SELECT ...) subqueries (Heikki Linnakangas, Tom Lane)

Fix planner to pass correct collation to operator selectivity estimators (Tom Lane)
This was not previously required by any core selectivity estimation function, but third-party code might need it.

Fix extraction of common prefixes from regular expressions (Tom Lane)


The code could get confused by quantified parenthesized subexpressions, such as ^(foo)?bar. This would lead to incorrect
index optimization of searches for such patterns.

Fix bugs with parsing signed hh:mm and hh:mm:ss fields in interval constants (Amit Kapila, Tom Lane)

Fix pg_dump to better handle views containing partial GROUP BY lists (Tom Lane)
A view that lists only a primary key column in GROUP BY, but uses other table columns as if they were grouped, gets marked
as depending on the primary key. Improper handling of such primary key dependencies in pg_dump resulted in poorly-ordered
dumps, which at best would be inefficient to restore and at worst could result in outright failure of a parallel pg_restore run.

In PL/Perl, avoid setting UTF8 flag when in SQL_ASCII encoding (Alex Hunsaker, Kyotaro Horiguchi, Alvaro Herrera)

Use Postgres' encoding conversion functions, not Python's, when converting a Python Unicode string to the server encoding in
PL/Python (Jan Urbanski)
This avoids some corner-case problems, notably that Python doesn't support all the encodings Postgres does. A notable functional change is that if the server encoding is SQL_ASCII, you will get the UTF-8 representation of the string; formerly, any
non-ASCII characters in the string would result in an error.

Fix mapping of PostgreSQL encodings to Python encodings in PL/Python (Jan Urbanski)

Report errors properly in contrib/xml2's xslt_process() (Tom Lane)

Update time zone data files to tzdata release 2012e for DST law changes in Morocco and Tokelau

E.11. Release 9.1.4


Release Date
2012-06-04
This release contains a variety of fixes from 9.1.3. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.11.1. Migration to Version 9.1.4


A dump/restore is not required for those running 9.1.X.
However, if you use the citext data type, and you upgraded from a previous major release by running pg_upgrade, you should run
CREATE EXTENSION citext FROM unpackaged to avoid collation-related failures in citext operations. The same is necessary if you restore a dump from a pre-9.1 database that contains an instance of the citext data type. If you've already run the
CREATE EXTENSION command before upgrading to 9.1.4, you will instead need to do manual catalog updates as explained in
the third changelog item below.
Also, if you are upgrading from a version earlier than 9.1.2, see Section E.13, Release 9.1.2 .

E.11.2. Changes

Fix incorrect password transformation in contrib/pgcrypto's DES crypt() function (Solar Designer)
1417

Notes de version

If a password string contained the byte value 0x80, the remainder of the password was ignored, causing the password to be
much weaker than it appeared. With this fix, the rest of the string is properly included in the DES hash. Any stored password
values that are affected by this bug will thus no longer match, so the stored values may need to be updated. (CVE-2012-2143)

Ignore SECURITY DEFINER and SET attributes for a procedural language's call handler (Tom Lane)
Applying such attributes to a call handler could crash the server. (CVE-2012-2655)

Make contrib/citext's upgrade script fix collations of citext arrays and domains over citext (Tom Lane)
Release 9.1.2 provided a fix for collations of citext columns and indexes in databases upgraded or reloaded from pre-9.1 installations, but that fix was incomplete: it neglected to handle arrays and domains over citext. This release extends the module's
upgrade script to handle these cases. As before, if you have already run the upgrade script, you'll need to run the collation update commands by hand instead. See the 9.1.2 release notes for more information about doing this.

Allow numeric timezone offsets in timestamp input to be up to 16 hours away from UTC (Tom Lane)
Some historical time zones have offsets larger than 15 hours, the previous limit. This could result in dumped data values being
rejected during reload.

Fix timestamp conversion to cope when the given time is exactly the last DST transition time for the current timezone (Tom
Lane)
This oversight has been there a long time, but was not noticed previously because most DST-using zones are presumed to have
an indefinite sequence of future DST transitions.

Fix text to name and char to name casts to perform string truncation correctly in multibyte encodings (Karl Schnaitter)

Fix memory copying bug in to_tsquery() (Heikki Linnakangas)

Ensure txid_current() reports the correct epoch when executed in hot standby (Simon Riggs)

Fix planner's handling of outer PlaceHolderVars within subqueries (Tom Lane)


This bug concerns sub-SELECTs that reference variables coming from the nullable side of an outer join of the surrounding
query. In 9.1, queries affected by this bug would fail with ERROR: Upper-level PlaceHolderVar found where not
expected . But in 9.0 and 8.4, you'd silently get possibly-wrong answers, since the value transmitted into the subquery
wouldn't go to null when it should.

Fix planning of UNION ALL subqueries with output columns that are not simple variables (Tom Lane)
Planning of such cases got noticeably worse in 9.1 as a result of a misguided fix for MergeAppend child's targetlist doesn't
match MergeAppend errors. Revert that fix and do it another way.

Fix slow session startup when pg_attribute is very large (Tom Lane)
If pg_attribute exceeds one-fourth of shared_buffers, cache rebuilding code that is sometimes needed during session
start would trigger the synchronized-scan logic, causing it to take many times longer than normal. The problem was particularly acute if many new sessions were starting at once.

Ensure sequential scans check for query cancel reasonably often (Merlin Moncure)
A scan encountering many consecutive pages that contain no live tuples would not respond to interrupts meanwhile.

Ensure the Windows implementation of PGSemaphoreLock() clears ImmediateInterruptOK before returning (Tom
Lane)
This oversight meant that a query-cancel interrupt received later in the same query could be accepted at an unsafe time, with
unpredictable but not good consequences.

Show whole-row variables safely when printing views or rules (Abbas Butt, Tom Lane)
Corner cases involving ambiguous names (that is, the name could be either a table or column name of the query) were printed
in an ambiguous way, risking that the view or rule would be interpreted differently after dump and reload. Avoid the ambiguous case by attaching a no-op cast.

Fix COPY FROM to properly handle null marker strings that correspond to invalid encoding (Tom Lane)
A null marker string such as E'\\0' should work, and did work in the past, but the case got broken in 8.4.

Fix EXPLAIN VERBOSE for writable CTEs containing RETURNING clauses (Tom Lane)

Fix PREPARE TRANSACTION to work correctly in the presence of advisory locks (Tom Lane)

1418

Notes de version

Historically, PREPARE TRANSACTION has simply ignored any session-level advisory locks the session holds, but this
case was accidentally broken in 9.1.

Fix truncation of unlogged tables (Robert Haas)

Ignore missing schemas during non-interactive assignments of search_path (Tom Lane)


This re-aligns 9.1's behavior with that of older branches. Previously 9.1 would throw an error for nonexistent schemas mentioned in search_path settings obtained from places such as ALTER DATABASE SET.

Fix bugs with temporary or transient tables used in extension scripts (Tom Lane)
This includes cases such as a rewriting ALTER TABLE within an extension update script, since that uses a transient table behind the scenes.

Ensure autovacuum worker processes perform stack depth checking properly (Heikki Linnakangas)
Previously, infinite recursion in a function invoked by auto-ANALYZE could crash worker processes.

Fix logging collector to not lose log coherency under high load (Andrew Dunstan)
The collector previously could fail to reassemble large messages if it got too busy.

Fix logging collector to ensure it will restart file rotation after receiving SIGHUP (Tom Lane)

Fix too many LWLocks taken failure in GiST indexes (Heikki Linnakangas)

Fix WAL replay logic for GIN indexes to not fail if the index was subsequently dropped (Tom Lane)

Correctly detect SSI conflicts of prepared transactions after a crash (Dan Ports)

Avoid synchronous replication delay when committing a transaction that only modified temporary tables (Heikki Linnakangas)
In such a case the transaction's commit record need not be flushed to standby servers, but some of the code didn't know that
and waited for it to happen anyway.

Fix error handling in pg_basebackup (Thomas Ogrisegg, Fujii Masao)

Fix walsender to not go into a busy loop if connection is terminated (Fujii Masao)

Fix memory leak in PL/pgSQL's RETURN NEXT command (Joe Conway)

Fix PL/pgSQL's GET DIAGNOSTICS command when the target is the function's first variable (Tom Lane)

Ensure that PL/Perl package-qualifies the _TD variable (Alex Hunsaker)


This bug caused trigger invocations to fail when they are nested within a function invocation that changes the current package.

Fix PL/Python functions returning composite types to accept a string for their result value (Jan Urbanski)
This case was accidentally broken by the 9.1 additions to allow a composite result value to be supplied in other formats, such
as dictionaries.

Fix potential access off the end of memory in psql's expanded display (\x) mode (Peter Eisentraut)

Fix several performance problems in pg_dump when the database contains many objects (Jeff Janes, Tom Lane)
pg_dump could get very slow if the database contained many schemas, or if many objects are in dependency loops, or if there
are many owned sequences.

Fix memory and file descriptor leaks in pg_restore when reading a directory-format archive (Peter Eisentraut)

Fix pg_upgrade for the case that a database stored in a non-default tablespace contains a table in the cluster's default tablespace (Bruce Momjian)

In ecpg, fix rare memory leaks and possible overwrite of one byte after the sqlca_t structure (Peter Eisentraut)

Fix contrib/dblink's dblink_exec() to not leak temporary database connections upon error (Tom Lane)

Fix contrib/dblink to report the correct connection name in error messages (Kyotaro Horiguchi)

Fix contrib/vacuumlo to use multiple transactions when dropping many large objects (Tim Lewis, Robert Haas, Tom
Lane)
This change avoids exceeding max_locks_per_transaction when many objects need to be dropped. The behavior can
be adjusted with the new -l (limit) option.
1419

Notes de version

Update time zone data files to tzdata release 2012c for DST law changes in Antarctica, Armenia, Chile, Cuba, Falkland Islands, Gaza, Haiti, Hebron, Morocco, Syria, and Tokelau Islands; also historical corrections for Canada.

E.12. Release 9.1.3


Release Date
2012-02-27
This release contains a variety of fixes from 9.1.2. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.12.1. Migration to Version 9.1.3


A dump/restore is not required for those running 9.1.X.
However, if you are upgrading from a version earlier than 9.1.2, see Section E.13, Release 9.1.2 .

E.12.2. Changes

Require execute permission on the trigger function for CREATE TRIGGER (Robert Haas)
This missing check could allow another user to execute a trigger function with forged input data, by installing it on a table he
owns. This is only of significance for trigger functions marked SECURITY DEFINER, since otherwise trigger functions run
as the table owner anyway. (CVE-2012-0866)

Remove arbitrary limitation on length of common name in SSL certificates (Heikki Linnakangas)
Both libpq and the server truncated the common name extracted from an SSL certificate at 32 bytes. Normally this would
cause nothing worse than an unexpected verification failure, but there are some rather-implausible scenarios in which it might
allow one certificate holder to impersonate another. The victim would have to have a common name exactly 32 bytes long, and
the attacker would have to persuade a trusted CA to issue a certificate in which the common name has that string as a prefix.
Impersonating a server would also require some additional exploit to redirect client connections. (CVE-2012-0867)

Convert newlines to spaces in names written in pg_dump comments (Robert Haas)


pg_dump was incautious about sanitizing object names that are emitted within SQL comments in its output script. A name
containing a newline would at least render the script syntactically incorrect. Maliciously crafted object names could present a
SQL injection risk when the script is reloaded. (CVE-2012-0868)

Fix btree index corruption from insertions concurrent with vacuuming (Tom Lane)
An index page split caused by an insertion could sometimes cause a concurrently-running VACUUM to miss removing index
entries that it should remove. After the corresponding table rows are removed, the dangling index entries would cause errors
(such as could not read block N in file ... ) or worse, silently wrong query results after unrelated rows are re-inserted at the
now-free table locations. This bug has been present since release 8.2, but occurs so infrequently that it was not diagnosed until
now. If you have reason to suspect that it has happened in your database, reindexing the affected index will fix things.

Fix transient zeroing of shared buffers during WAL replay (Tom Lane)
The replay logic would sometimes zero and refill a shared buffer, so that the contents were transiently invalid. In hot standby
mode this can result in a query that's executing in parallel seeing garbage data. Various symptoms could result from that, but
the most common one seems to be invalid memory alloc request size .

Fix handling of data-modifying WITH subplans in READ COMMITTED rechecking (Tom Lane)
A WITH clause containing INSERT/UPDATE/DELETE would crash if the parent UPDATE or DELETE command needed
to be re-evaluated at one or more rows due to concurrent updates in READ COMMITTED mode.

Fix corner case in SSI transaction cleanup (Dan Ports)


When finishing up a read-write serializable transaction, a crash could occur if all remaining active serializable transactions are
read-only.

Fix postmaster to attempt restart after a hot-standby crash (Tom Lane)


A logic error caused the postmaster to terminate, rather than attempt to restart the cluster, if any backend process crashed while
operating in hot standby mode.
1420

Notes de version

Fix CLUSTER/VACUUM FULL handling of toast values owned by recently-updated rows (Tom Lane)
This oversight could lead to duplicate key value violates unique constraint errors being reported against the toast table's index during one of these commands.

Update per-column permissions, not only per-table permissions, when changing table owner (Tom Lane)
Failure to do this meant that any previously granted column permissions were still shown as having been granted by the old
owner. This meant that neither the new owner nor a superuser could revoke the now-untraceable-to-table-owner permissions.

Support foreign data wrappers and foreign servers in REASSIGN OWNED (Alvaro Herrera)
This command failed with unexpected classid errors if it needed to change the ownership of any such objects.

Allow non-existent values for some settings in ALTER USER/DATABASE SET (Heikki Linnakangas)
Allow default_text_search_config, default_tablespace, and temp_tablespaces to be set to names that
are not known. This is because they might be known in another database where the setting is intended to be used, or for the tablespace cases because the tablespace might not be created yet. The same issue was previously recognized for
search_path, and these settings now act like that one.

Fix unsupported node type error caused by COLLATE in an INSERT expression (Tom Lane)

Avoid crashing when we have problems deleting table files post-commit (Tom Lane)
Dropping a table should lead to deleting the underlying disk files only after the transaction commits. In event of failure then
(for instance, because of wrong file permissions) the code is supposed to just emit a warning message and go on, since it's too
late to abort the transaction. This logic got broken as of release 8.4, causing such situations to result in a PANIC and an unrestartable database.

Recover from errors occurring during WAL replay of DROP TABLESPACE (Tom Lane)
Replay will attempt to remove the tablespace's directories, but there are various reasons why this might fail (for example, incorrect ownership or permissions on those directories). Formerly the replay code would panic, rendering the database unrestartable without manual intervention. It seems better to log the problem and continue, since the only consequence of failure to remove the directories is some wasted disk space.

Fix race condition in logging AccessExclusiveLocks for hot standby (Simon Riggs)
Sometimes a lock would be logged as being held by transaction zero . This is at least known to produce assertion failures
on slave servers, and might be the cause of more serious problems.

Track the OID counter correctly during WAL replay, even when it wraps around (Tom Lane)
Previously the OID counter would remain stuck at a high value until the system exited replay mode. The practical consequences of that are usually nil, but there are scenarios wherein a standby server that's been promoted to master might take a
long time to advance the OID counter to a reasonable value once values are needed.

Prevent emitting misleading consistent recovery state reached log message at the beginning of crash recovery (Heikki Linnakangas)

Fix initial value of pg_stat_replication.replay_location (Fujii Masao)


Previously, the value shown would be wrong until at least one WAL record had been replayed.

Fix regular expression back-references with * attached (Tom Lane)


Rather than enforcing an exact string match, the code would effectively accept any string that satisfies the pattern subexpression referenced by the back-reference symbol.
A similar problem still afflicts back-references that are embedded in a larger quantified expression, rather than being the immediate subject of the quantifier. This will be addressed in a future PostgreSQL release.

Fix recently-introduced memory leak in processing of inet/cidr values (Heikki Linnakangas)


A patch in the December 2011 releases of PostgreSQL caused memory leakage in these operations, which could be significant in scenarios such as building a btree index on such a column.

Fix planner's ability to push down index-expression restrictions through UNION ALL (Tom Lane)
This type of optimization was inadvertently disabled by a fix for another problem in 9.1.2.

Fix planning of WITH clauses referenced in UPDATE/DELETE on an alled table (Tom Lane)
This bug led to could not find plan for CTE failures.
1421

Notes de version

Fix GIN cost estimation to handle column IN (...) index conditions (Marti Raudsepp)
This oversight would usually lead to crashes if such a condition could be used with a GIN index.

Prevent assertion failure when exiting a session with an open, failed transaction (Tom Lane)
This bug has no impact on normal builds with asserts not enabled.

Fix dangling pointer after CREATE TABLE AS/SELECT INTO in a SQL-language function (Tom Lane)
In most cases this only led to an assertion failure in assert-enabled builds, but worse consequences seem possible.

Avoid double close of file handle in syslogger on Windows (MauMau)


Ordinarily this error was invisible, but it would cause an exception when running on a debug version of Windows.

Fix I/O-conversion-related memory leaks in plpgsql (Andres Freund, Jan Urbanski, Tom Lane)
Certain operations would leak memory until the end of the current function.

Work around bug in perl's SvPVutf8() function (Andrew Dunstan)


This function crashes when handed a typeglob or certain read-only objects such as $^V. Make plperl avoid passing those to it.

In pg_dump, don't dump contents of an extension's configuration tables if the extension itself is not being dumped (Tom Lane)

Improve pg_dump's handling of alled table columns (Tom Lane)


pg_dump mishandled situations where a child column has a different default expression than its parent column. If the default is
textually identical to the parent's default, but not actually the same (for instance, because of schema search path differences) it
would not be recognized as different, so that after dump and restore the child would be allowed to all the parent's default.
Child columns that are NOT NULL where their parent is not could also be restored subtly incorrectly.

Fix pg_restore's direct-to-database mode for INSERT-style table data (Tom Lane)
Direct-to-database restores from archive files made with --inserts or --column-inserts options fail when using
pg_restore from a release dated September or December 2011, as a result of an oversight in a fix for another problem. The archive file itself is not at fault, and text-mode output is okay.

Teach pg_upgrade to handle renaming of plpython's shared library (Bruce Momjian)


Upgrading a pre-9.1 database that included plpython would fail because of this oversight.

Allow pg_upgrade to process tables containing regclass columns (Bruce Momjian)


Since pg_upgrade now takes care to preserve pg_class OIDs, there was no longer any reason for this restriction.

Make libpq ignore ENOTDIR errors when looking for an SSL client certificate file (Magnus Hagander)
This allows SSL connections to be established, though without a certificate, even when the user's home directory is set to something like /dev/null.

Fix some more field alignment issues in ecpg's SQLDA area (Zoltan Boszormenyi)

Allow AT option in ecpg DEALLOCATE statements (Michael Meskes)


The infrastructure to support this has been there for awhile, but through an oversight there was still an error check rejecting the
case.

Do not use the variable name when defining a varchar structure in ecpg (Michael Meskes)

Fix contrib/auto_explain's JSON output mode to produce valid JSON (Andrew Dunstan)
The output used brackets at the top level, when it should have used braces.

Fix error in contrib/intarray's int[] & int[] operator (Guillaume Lelarge)


If the smallest integer the two input arrays have in common is 1, and there are smaller values in either array, then 1 would be
incorrectly omitted from the result.

Fix error detection in contrib/pgcrypto's encrypt_iv() and decrypt_iv() (Marko Kreen)


These functions failed to report certain types of invalid-input errors, and would instead return random garbage values for incorrect input.

Fix one-byte buffer overrun in contrib/test_parser (Paul Guyot)


The code would try to read one more byte than it should, which would crash in corner cases. Since contrib/
1422

Notes de version

test_parser is only example code, this is not a security issue in itself, but bad example code is still bad.

Use __sync_lock_test_and_set() for spinlocks on ARM, if available (Martin Pitt)


This function replaces our previous use of the SWPB instruction, which is deprecated and not available on ARMv6 and later.
Reports suggest that the old code doesn't fail in an obvious way on recent ARM boards, but simply doesn't interlock concurrent accesses, leading to bizarre failures in multiprocess operation.

Use -fexcess-precision=standard option when building with gcc versions that accept it (Andrew Dunstan)
This prevents assorted scenarios wherein recent versions of gcc will produce creative results.

Allow use of threaded Python on FreeBSD (Chris Rees)


Our configure script previously believed that this combination wouldn't work; but FreeBSD fixed the problem, so remove that
error check.

Allow MinGW builds to use standardly-named OpenSSL libraries (Tomasz Ostrowski)

E.13. Release 9.1.2


Release Date
2011-12-05
This release contains a variety of fixes from 9.1.1. For information about new features in the 9.1 major release, see Section E.15,
Release 9.1 .

E.13.1. Migration to Version 9.1.2


A dump/restore is not required for those running 9.1.X.
However,
a
longstanding
error
was
discovered
in
the
definition
of
the
information_schema.referential_constraints view. If you rely on correct results from that view, you should replace its definition as explained in the first changelog item below.
Also, if you use the citext data type, and you upgraded from a previous major release by running pg_upgrade, you should run
CREATE EXTENSION citext FROM unpackaged to avoid collation-related failures in citext operations. The same is necessary if you restore a dump from a pre-9.1 database that contains an instance of the citext data type. If you've already run the
CREATE EXTENSION command before upgrading to 9.1.2, you will instead need to do manual catalog updates as explained in
the second changelog item.

E.13.2. Changes

Fix bugs in information_schema.referential_constraints view (Tom Lane)


This view was being insufficiently careful about matching the foreign-key constraint to the depended-on primary or unique
key constraint. That could result in failure to show a foreign key constraint at all, or showing it multiple times, or claiming that
it depends on a different constraint than the one it really does.
Since the view definition is installed by initdb, merely upgrading will not fix the problem. If you need to fix this in an existing
installation, you can (as a superuser) drop the information_schema schema then re-create it by sourcing SHAREDIR/
information_schema.sql. (Run pg_config --sharedir if you're uncertain where SHAREDIR is.) This must be
repeated in each database to be fixed.

Make contrib/citext's upgrade script fix collations of citext columns and indexes (Tom Lane)
Existing citext columns and indexes aren't correctly marked as being of a collatable data type during pg_upgrade from a pre9.1 server, or when a pre-9.1 dump containing the citext type is loaded into a 9.1 server. That leads to operations on these columns failing with errors such as could not determine which collation to use for string comparison . This change allows
them to be fixed by the same script that upgrades the citext module into a proper 9.1 extension during CREATE EXTENSION
citext FROM unpackaged.
If you have a previously-upgraded database that is suffering from this problem, and you already ran the CREATE EXTENSION command, you can manually run (as superuser) the UPDATE commands found at the end of SHAREDIR/
extension/citext--unpackaged--1.0.sql. (Run pg_config --sharedir if you're uncertain where SHAREDIR is.) There is no harm in doing this again if unsure.
1423

Notes de version

Fix possible crash during UPDATE or DELETE that joins to the output of a scalar-returning function (Tom Lane)
A crash could only occur if the target row had been concurrently updated, so this problem surfaced only intermittently.

Fix incorrect replay of WAL records for GIN index updates (Tom Lane)
This could result in transiently failing to find index entries after a crash, or on a hot-standby server. The problem would be repaired by the next VACUUM of the index, however.

Fix TOAST-related data corruption during CREATE TABLE dest AS SELECT * FROM src or INSERT INTO
dest SELECT * FROM src (Tom Lane)
If a table has been modified by ALTER TABLE ADD COLUMN, attempts to copy its data verbatim to another table could
produce corrupt results in certain corner cases. The problem can only manifest in this precise form in 8.4 and later, but we patched earlier versions as well in case there are other code paths that could trigger the same bug.

Fix possible failures during hot standby startup (Simon Riggs)

Start hot standby faster when initial snapshot is incomplete (Simon Riggs)

Fix race condition during toast table access from stale syscache entries (Tom Lane)
The typical symptom was transient errors like missing chunk number 0 for toast value NNNNN in pg_toast_2619 , where
the cited toast table would always belong to a system catalog.

Track dependencies of functions on items used in parameter default expressions (Tom Lane)
Previously, a referenced object could be dropped without having dropped or modified the function, leading to misbehavior
when the function was used. Note that merely installing this update will not fix the missing dependency entries; to do that,
you'd need to CREATE OR REPLACE each such function afterwards. If you have functions whose defaults depend on nonbuilt-in objects, doing so is recommended.

Fix incorrect management of placeholder variables in nestloop joins (Tom Lane)


This bug is known to lead to variable not found in subplan target list planner errors, and could possibly result in wrong
query output when outer joins are involved.

Fix window functions that sort by expressions involving aggregates (Tom Lane)
Previously these could fail with could not find pathkey item to sort planner errors.

Fix MergeAppend child's targetlist doesn't match MergeAppend planner errors (Tom Lane)

Fix index matching for operators with both collatable and noncollatable inputs (Tom Lane)
In 9.1.0, an indexable operator that has a non-collatable left-hand input type and a collatable right-hand input type would not
be recognized as matching the left-hand column's index. An example is the hstore ? text operator.

Allow inlining of set-returning SQL functions with multiple OUT parameters (Tom Lane)

Don't trust deferred-unique indexes for join removal (Tom Lane and Marti Raudsepp)
A deferred uniqueness constraint might not hold intra-transaction, so assuming that it does could give incorrect query results.

Make DatumGetInetP() unpack inet datums that have a 1-byte header, and add a new macro, DatumGetInetPP(),
that does not (Heikki Linnakangas)
This change affects no core code, but might prevent crashes in add-on code that expects DatumGetInetP() to produce an
unpacked datum as per usual convention.

Improve locale support in money type's input and output (Tom Lane)
Aside from not supporting all standard lc_monetary formatting options, the input and output functions were inconsistent,
meaning there were locales in which dumped money values could not be re-read.

Don't let transform_null_equals affect CASE foo WHEN NULL ... constructs (Heikki Linnakangas)
transform_null_equals is only supposed to affect foo = NULL expressions written directly by the user, not equality
checks generated internally by this form of CASE.

Change foreign-key trigger creation order to better support self-referential foreign keys (Tom Lane)
For a cascading foreign key that references its own table, a row update will fire both the ON UPDATE trigger and the CHECK
trigger as one event. The ON UPDATE trigger must execute first, else the CHECK will check a non-final state of the row and
possibly throw an inappropriate error. However, the firing order of these triggers is determined by their names, which general1424

Notes de version

ly sort in creation order since the triggers have auto-generated names following the convention
RI_ConstraintTrigger_NNNN . A proper fix would require modifying that convention, which we will do in 9.2, but it
seems risky to change it in existing releases. So this patch just changes the creation order of the triggers. Users encountering
this type of error should drop and re-create the foreign key constraint to get its triggers into the right order.

Fix IF EXISTS to work correctly in DROP OPERATOR FAMILY (Robert Haas)

Disallow dropping of an extension from within its own script (Tom Lane)
This prevents odd behavior in case of incorrect management of extension dependencies.

Don't mark auto-generated types as extension members (Robert Haas)


Relation rowtypes and automatically-generated array types do not need to have their own extension membership entries in
pg_depend, and creating such entries complicates matters for extension upgrades.

Cope with invalid pre-existing search_path settings during CREATE EXTENSION (Tom Lane)

Avoid floating-point underflow while tracking buffer allocation rate (Greg Matthews)
While harmless in itself, on certain platforms this would result in annoying kernel log messages.

Prevent autovacuum transactions from running in serializable mode (Tom Lane)


Autovacuum formerly used the cluster-wide default transaction isolation level, but there is no need for it to use anything higher than READ COMMITTED, and using SERIALIZABLE could result in unnecessary delays for other processes.

Ensure walsender processes respond promptly to SIGTERM (Magnus Hagander)

Exclude postmaster.opts from base backups (Magnus Hagander)

Preserve configuration file name and line number values when starting child processes under Windows (Tom Lane)
Formerly, these would not be displayed correctly in the pg_settings view.

Fix incorrect field alignment in ecpg's SQLDA area (Zoltan Boszormenyi)

Preserve blank lines within commands in psql's command history (Robert Haas)
The former behavior could cause problems if an empty line was removed from within a string literal, for example.

Avoid platform-specific infinite loop in pg_dump (Steve Singer)

Fix compression of plain-text output format in pg_dump (Adrian Klaver and Tom Lane)
pg_dump has historically understood -Z with no -F switch to mean that it should emit a gzip-compressed version of its plain
text output. Restore that behavior.

Fix pg_dump to dump user-defined casts between auto-generated types, such as table rowtypes (Tom Lane)

Fix missed quoting of foreign server names in pg_dump (Tom Lane)

Assorted fixes for pg_upgrade (Bruce Momjian)


Handle exclusion constraints correctly, avoid failures on Windows, don't complain about mismatched toast table names in 8.4
databases.

In PL/pgSQL, allow foreign tables to define row types (Alexander Soudakov)

Fix up conversions of PL/Perl functions' results (Alex Hunsaker and Tom Lane)
Restore the pre-9.1 behavior that PL/Perl functions returning void ignore the result value of their last Perl statement; 9.1.0
would throw an error if that statement returned a reference. Also, make sure it works to return a string value for a composite
type, so long as the string meets the type's input format. In addition, throw errors for attempts to return Perl arrays or hashes
when the function's declared result type is not an array or composite type, respectively. (Pre-9.1 versions rather uselessly returned strings like ARRAY(0x221a9a0) or HASH(0x221aa90) in such cases.)

Ensure PL/Perl strings are always correctly UTF8-encoded (Amit Khandekar and Alex Hunsaker)

Use the preferred version of xsubpp to build PL/Perl, not necessarily the operating system's main copy (David Wheeler and
Alex Hunsaker)

Correctly propagate SQLSTATE in PL/Python exceptions (Mika Eloranta and Jan Urbanski)

Do not install PL/Python extension files for Python major versions other than the one built against (Peter Eisentraut)

Change all the contrib extension script files to report a useful error message if they are fed to psql (Andrew Dunstan and
1425

Notes de version

Tom Lane)
This should help teach people about the new method of using CREATE EXTENSION to load these files. In most cases, sourcing the scripts directly would fail anyway, but with harder-to-interpret messages.

Fix incorrect coding in contrib/dict_int and contrib/dict_xsyn (Tom Lane)


Some functions incorrectly assumed that memory returned by palloc() is guaranteed zeroed.

Remove contrib/sepgsql tests from the regular regression test mechanism (Tom Lane)
Since these tests require root privileges for setup, they're impractical to run automatically. Switch over to a manual approach
instead, and provide a testing script to help with that.

Fix assorted errors in contrib/unaccent's configuration file parsing (Tom Lane)

Honor query cancel interrupts promptly in pgstatindex() (Robert Haas)

Fix incorrect quoting of log file name in Mac OS X start script (Sidar Lopez)

Revert unintentional enabling of WAL_DEBUG (Robert Haas)


Fortunately, as debugging tools go, this one is pretty cheap; but it's not intended to be enabled by default, so revert.

Ensure VPATH builds properly install all server header files (Peter Eisentraut)

Shorten file names reported in verbose error messages (Peter Eisentraut)


Regular builds have always reported just the name of the C file containing the error message call, but VPATH builds formerly
reported an absolute path name.

Fix interpretation of Windows timezone names for Central America (Tom Lane)
Map Central America Standard Time to CST6, not CST6CDT, because DST is generally not observed anywhere in Central
America.

Update time zone data files to tzdata release 2011n for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa;
also historical corrections for Alaska and British East Africa.

E.14. Release 9.1.1


Release Date
2011-09-26
This release contains a small number of fixes from 9.1.0. For information about new features in the 9.1 major release, see Section E.15, Release 9.1 .

E.14.1. Migration to Version 9.1.1


A dump/restore is not required for those running 9.1.X.

E.14.2. Changes

Make pg_options_to_table return NULL for an option with no value (Tom Lane)
Previously such cases would result in a server crash.

Fix memory leak at end of a GiST index scan (Tom Lane)


Commands that perform many separate GiST index scans, such as verification of a new GiST-based exclusion constraint on a
table already containing many rows, could transiently require large amounts of memory due to this leak.

Fix explicit reference to pg_temp schema in CREATE TEMPORARY TABLE (Robert Haas)
This used to be allowed, but failed in 9.1.0.

E.15. Release 9.1


1426

Notes de version

Release Date
2011-09-12

E.15.1. Overview
This release shows PostgreSQL moving beyond the traditional relational-database feature set with new, ground-breaking functionality that is unique to PostgreSQL. The streaming replication feature introduced in release 9.0 is significantly enhanced by
adding a synchronous-replication option, streaming backups, and monitoring improvements. Major enhancements include:

Allow synchronous replication

Add support for foreign tables

Add per-column collation support

Add extensions which simplify packaging of additions to PostgreSQL

Add a true serializable isolation level

Support unlogged tables using the UNLOGGED option in CREATE TABLE

Allow data-modification commands (INSERT/UPDATE/DELETE) in WITH clauses

Add nearest-neighbor (order-by-operator) searching to GiST indexes

Add a SECURITY LABEL command and support for SELinux permissions control

Update the PL/Python server-side language

The above items are explained in more detail in the sections below.

E.15.2. Migration to Version 9.1


A dump/restore using pg_dump, or use of pg_upgrade, is required for those wishing to migrate data from any previous release.
Version 9.1 contains a number of changes that may affect compatibility with previous releases. Observe the following incompatibilities:

E.15.2.1. Strings

Change the default value of standard_conforming_strings to on (Robert Haas)


By default, backslashes are now ordinary characters in string literals, not escape characters. This change removes a longstanding incompatibility with the SQL standard. escape_string_warning has produced warnings about this usage for
years. E'' strings are the proper way to embed backslash escapes in strings and are unaffected by this change.

Avertissement
This change can break applications that are not expecting it and do their own string escaping according to the
old rules. The consequences could be as severe as introducing SQL-injection security holes. Be sure to test applications that are exposed to untrusted input, to ensure that they correctly handle single quotes and backslashes
in text strings.

E.15.2.2. Casting

Disallow function-style and attribute-style data type casts for composite types (Tom Lane)
For example, disallow composite_value.text and text(composite_value). Unintentional uses of this syntax
have frequently resulted in bug reports; although it was not a bug, it seems better to go back to rejecting such expressions. The
CAST and :: syntaxes are still available for use when a cast of an entire composite value is actually intended.

Tighten casting checks for domains based on arrays (Tom Lane)


When a domain is based on an array type, it is allowed to look through the domain type to access the array elements, including subscripting the domain value to fetch or assign an element. Assignment to an element of such a domain value, for ins1427

Notes de version

tance via UPDATE ... SET domaincol[5] = ..., will now result in rechecking the domain type's constraints, whereas before the checks were skipped.

E.15.2.3. Arrays

Change string_to_array() to return an empty array for a zero-length string (Pavel Stehule)
Previously this returned a null value.

Change string_to_array() so a NULL separator splits the string into characters (Pavel Stehule)
Previously this returned a null value.

E.15.2.4. Object Modification

Fix improper checks for before/after triggers (Tom Lane)


Triggers can now be fired in three cases: BEFORE, AFTER, or INSTEAD OF some action. Trigger function authors should
verify that their logic behaves sanely in all three cases.

Require superuser or CREATEROLE permissions in order to set comments on roles (Tom Lane)

E.15.2.5. Server Settings

Change pg_last_xlog_receive_location() so it never moves backwards (Fujii Masao)


Previously, the value of pg_last_xlog_receive_location() could move backward when streaming replication is
restarted.

Have logging of replication connections honor log_connections (Magnus Hagander)


Previously, replication connections were always logged.

E.15.2.6. PL/pgSQL Server-Side Language

Change PL/pgSQL's RAISE command without parameters to be catchable by the attached exception block (Piyush Newe)
Previously RAISE in a code block was always scoped to an attached exception block, so it was uncatchable at the same scope.

Adjust PL/pgSQL's error line numbering code to be consistent with other PLs (Pavel Stehule)
Previously, PL/pgSQL would ignore (not count) an empty line at the start of the function body. Since this was inconsistent
with all other languages, the special case was removed.

Make PL/pgSQL complain about conflicting IN and OUT parameter names (Tom Lane)
Formerly, the collision was not detected, and the name would just silently refer to only the OUT parameter.

Type modifiers of PL/pgSQL variables are now visible to the SQL parser (Tom Lane)
A type modifier (such as a varchar length limit) attached to a PL/pgSQL variable was formerly enforced during assignments,
but was ignored for all other purposes. Such variables will now behave more like table columns declared with the same modifier. This is not expected to make any visible difference in most cases, but it could result in subtle changes for some SQL commands issued by PL/pgSQL functions.

E.15.2.7. Contrib

All contrib modules are now installed with CREATE EXTENSION rather than by manually invoking their SQL scripts
(Dimitri Fontaine, Tom Lane)
To update an existing database containing the 9.0 version of a contrib module, use CREATE EXTENSION ... FROM unpackaged to wrap the existing contrib module's objects into an extension. When updating from a pre-9.0 version, drop the
contrib module's objects using its old uninstall script, then use CREATE EXTENSION.

E.15.2.8. Other Incompatibilities


1428

Notes de version

Make pg_stat_reset() reset all database-level statistics (Tomas Vondra)


Some pg_stat_database counters were not being reset.

Fix some information_schema.triggers column names to match the new SQL-standard names (Dean Rasheed)

Treat ECPG cursor names as case-insensitive (Zoltan Boszormenyi)

E.15.3. Changes
Below you will find a detailed account of the changes between PostgreSQL 9.1 and the previous major release.

E.15.3.1. Server
E.15.3.1.1. Performance

Support unlogged tables using the UNLOGGED option in CREATE TABLE (Robert Haas)
Such tables provide better update performance than regular tables, but are not crash-safe: their contents are automatically cleared in case of a server crash. Their contents do not propagate to replication slaves, either.

Allow FULL OUTER JOIN to be implemented as a hash join, and allow either side of a LEFT OUTER JOIN or RIGHT
OUTER JOIN to be hashed (Tom Lane)
Previously FULL OUTER JOIN could only be implemented as a merge join, and LEFT OUTER JOIN and RIGHT OUTER
JOIN could hash only the nullable side of the join. These changes provide additional query optimization possibilities.

Merge duplicate fsync requests (Robert Haas, Greg Smith)


This greatly improves performance under heavy write loads.

Improve performance of commit_siblings (Greg Smith)


This allows the use of commit_siblings with less overhead.

Reduce the memory requirement for large ispell dictionaries (Pavel Stehule, Tom Lane)

Avoid leaving data files open after blind writes (Alvaro Herrera)
This fixes scenarios in which backends might hold files open long after they were deleted, preventing the kernel from reclaiming disk space.

E.15.3.1.2. Optimizer

Allow allance table scans to return meaningfully-sorted results (Greg Stark, Hans-Jurgen Schonig, Robert Haas, Tom Lane)
This allows better optimization of queries that use ORDER BY, LIMIT, or MIN/MAX with alled tables.

Improve GIN index scan cost estimation (Teodor Sigaev)

Improve cost estimation for aggregates and window functions (Tom Lane)

E.15.3.1.3. Authentication

Support host names and host suffixes (e.g. .example.com) in pg_hba.conf (Peter Eisentraut)
Previously only host IP addresses and CIDR values were supported.

Support the key word all in the host column of pg_hba.conf (Peter Eisentraut)
Previously people used 0.0.0.0/0 or ::/0 for this.

Reject local lines in pg_hba.conf on platforms that don't support Unix-socket connections (Magnus Hagander)
Formerly, such lines were silently ignored, which could be surprising. This makes the behavior more like other unsupported
cases.

Allow GSSAPI to be used to authenticate to servers via SSPI (Christian Ullrich)


Specifically this allows Unix-based GSSAPI clients to do SSPI authentication with Windows servers.

ident authentication over local sockets is now known as peer (Magnus Hagander)
1429

Notes de version

The old term is still accepted for backward compatibility, but since the two methods are fundamentally different, it seemed
better to adopt different names for them.

Rewrite peer authentication to avoid use of credential control messages (Tom Lane)
This change makes the peer authentication code simpler and better-performing. However, it requires the platform to provide
the getpeereid function or an equivalent socket operation. So far as is known, the only platform for which peer authentication worked before and now will not is pre-5.0 NetBSD.

E.15.3.1.4. Monitoring

Add details to the logging of restartpoints and checkpoints, which is controlled by log_checkpoints (Fujii Masao, Greg
Smith)
New details include WAL file and sync activity.

Add log_file_mode which controls the permissions on log files created by the logging collector (Martin Pihlak)

Reduce the default maximum line length for syslog logging to 900 bytes plus prefixes (Noah Misch)
This avoids truncation of long log lines on syslog implementations that have a 1KB length limit, rather than the more common
2KB.

E.15.3.1.5. Statistical Views

Add client_hostname column to pg_stat_activity (Peter Eisentraut)


Previously only the client address was reported.

Add pg_stat_xact_* statistics functions and views (Joel Jacobson)


These are like the database-wide statistics counter views, but reflect counts for only the current transaction.

Add time of last reset in database-level and background writer statistics views (Tomas Vondra)

Add columns showing the number of vacuum and analyze operations in pg_stat_*_tables views (Magnus Hagander)

Add buffers_backend_fsync column to pg_stat_bgwriter (Greg Smith)


This new column counts the number of times a backend fsyncs a buffer.

E.15.3.1.6. Server Settings

Provide auto-tuning of wal_buffers (Greg Smith)


By default, the value of wal_buffers is now chosen automatically based on the value of shared_buffers.

Increase the maximum values for deadlock_timeout, log_min_duration_statement, and


log_autovacuum_min_duration (Peter Eisentraut)
The maximum value for each of these parameters was previously only about 35 minutes. Much larger values are now allowed.

E.15.3.2. Replication and Recovery


E.15.3.2.1. Streaming Replication and Continuous Archiving

Allow synchronous replication (Simon Riggs, Fujii Masao)


This allows the primary server to wait for a standby to write a transaction's information to disk before acknowledging the commit. One standby at a time can take the role of the synchronous standby, as controlled by the synchronous_standby_names setting. Synchronous replication can be enabled or disabled on a per-transaction basis using the
synchronous_commit setting.

Add protocol support for sending file system backups to standby servers using the streaming replication network connection
(Magnus Hagander, Heikki Linnakangas)
This avoids the requirement of manually transferring a file system backup when setting up a standby server.

Add replication_timeout setting (Fujii Masao, Heikki Linnakangas)


1430

Notes de version

Replication connections that are idle for more than the replication_timeout interval will be terminated automatically.
Formerly, a failed connection was typically not detected until the TCP timeout elapsed, which is inconveniently long in many
situations.

Add command-line tool pg_basebackup for creating a new standby server or database backup (Magnus Hagander)

Add a replication permission for roles (Magnus Hagander)


This is a read-only permission used for streaming replication. It allows a non-superuser role to be used for replication connections. Previously only superusers could initiate replication connections; superusers still have this permission by default.

E.15.3.2.2. Replication Monitoring

Add system view pg_stat_replication which displays activity of WAL sender processes (Itagaki Takahiro, Simon Riggs)
This reports the status of all connected standby servers.

Add monitoring function pg_last_xact_replay_timestamp() (Fujii Masao)


This returns the time at which the primary generated the most recent commit or abort record applied on the standby.

E.15.3.2.3. Hot Standby

Add configuration parameter hot_standby_feedback to enable standbys to postpone cleanup of old row versions on the
primary (Simon Riggs)
This helps avoid canceling long-running queries on the standby.

Add the pg_stat_database_conflicts system view to show queries that have been canceled and the reason (Magnus Hagander)
Cancellations can occur because of dropped tablespaces, lock timeouts, old snapshots, pinned buffers, and deadlocks.

Add a conflicts count to pg_stat_database (Magnus Hagander)


This is the number of conflicts that occurred in the database.

Increase the maximum values for max_standby_archive_delay and max_standby_streaming_delay


The maximum value for each of these parameters was previously only about 35 minutes. Much larger values are now allowed.

Add ERRCODE_T_R_DATABASE_DROPPED error code to report recovery conflicts due to dropped databases (Tatsuo Ishii)
This is useful for connection pooling software.

E.15.3.2.4. Recovery Control

Add functions to control streaming replication replay (Simon Riggs)


The new functions are pg_xlog_replay_pause(), pg_xlog_replay_resume(), and the status function
pg_is_xlog_replay_paused().

Add recovery.conf setting pause_at_recovery_target to pause recovery at target (Simon Riggs)


This allows a recovery server to be queried to check whether the recovery point is the one desired.

Add the ability to create named restore points using pg_create_restore_point() (Jaime Casanova)
These named restore points can be specified as recovery targets using the new recovery.conf setting recovery_target_name.

Allow standby recovery to switch to a new timeline automatically (Heikki Linnakangas)


Now standby servers scan the archive directory for new timelines periodically.

Add restart_after_crash setting which disables automatic server restart after a backend crash (Robert Haas)
This allows external cluster management software to control whether the database server restarts or not.

Allow recovery.conf to use the same quoting behavior as postgresql.conf (Dimitri Fontaine)
Previously all values had to be quoted.

1431

Notes de version

E.15.3.3. Queries

Add a true serializable isolation level (Kevin Grittner, Dan Ports)


Previously, asking for serializable isolation guaranteed only that a single MVCC snapshot would be used for the entire transaction, which allowed certain documented anomalies. The old snapshot isolation behavior is still available by requesting the REPEATABLE READ isolation level.

Allow data-modification commands (INSERT/UPDATE/DELETE) in WITH clauses (Marko Tiikkaja, Hitoshi Harada)
These commands can use RETURNING to pass data up to the containing query.

Allow WITH clauses to be attached to INSERT, UPDATE, DELETE statements (Marko Tiikkaja, Hitoshi Harada)

Allow non-GROUP BY columns in the query target list when the primary key is specified in the GROUP BY clause (Peter Eisentraut)
The SQL standard allows this behavior, and because of the primary key, the result is unambiguous.

Allow use of the key word DISTINCT in UNION/INTERSECT/EXCEPT clauses (Tom Lane)
DISTINCT is the default behavior so use of this key word is redundant, but the SQL standard allows it.

Fix ordinary queries with rules to use the same snapshot behavior as EXPLAIN ANALYZE (Marko Tiikkaja)
Previously EXPLAIN ANALYZE used slightly different snapshot timing for queries involving rules. The EXPLAIN ANALYZE behavior was judged to be more logical.

E.15.3.3.1. Strings

Add per-column collation support (Peter Eisentraut, Tom Lane)


Previously collation (the sort ordering of text strings) could only be chosen at database creation. Collation can now be set per
column, domain, index, or expression, via the SQL-standard COLLATE clause.

E.15.3.4. Object Manipulation

Add extensions which simplify packaging of additions to PostgreSQL (Dimitri Fontaine, Tom Lane)
Extensions are controlled by the new CREATE/ALTER/DROP EXTENSION commands. This replaces ad-hoc methods of
grouping objects that are added to a PostgreSQL installation.

Add support for foreign tables (Shigeru Hanada, Robert Haas, Jan Urbanski, Heikki Linnakangas)
This allows data stored outside the database to be used like native PostgreSQL-stored data. Foreign tables are currently
read-only, however.

Allow new values to be added to an existing enum type via ALTER TYPE (Andrew Dunstan)

Add ALTER TYPE ... ADD/DROP/ALTER/RENAME ATTRIBUTE (Peter Eisentraut)


This allows modification of composite types.

E.15.3.4.1. ALTER Object

Add RESTRICT/CASCADE to ALTER TYPE operations on typed tables (Peter Eisentraut)


This controls ADD/DROP/ALTER/RENAME ATTRIBUTE cascading behavior.

Support ALTER TABLE name {OF | NOT OF} type (Noah Misch)
This syntax allows a standalone table to be made into a typed table, or a typed table to be made standalone.

Add support for more object types in ALTER ... SET SCHEMA commands (Dimitri Fontaine)
This command is now supported for conversions, operators, operator classes, operator families, text search configurations, text
search dictionaries, text search parsers, and text search templates.

E.15.3.4.2. CREATE/ALTER TABLE

1432

Notes de version

Add ALTER TABLE ... ADD UNIQUE/PRIMARY KEY USING INDEX (Gurjeet Singh)
This allows a primary key or unique constraint to be defined using an existing unique index, including a concurrently created
unique index.

Allow ALTER TABLE to add foreign keys without validation (Simon Riggs)
The new option is called NOT VALID. The constraint's state can later be modified to VALIDATED and validation checks performed. Together these allow you to add a foreign key with minimal impact on read and write operations.

Allow ALTER TABLE ... SET DATA TYPE to avoid table rewrites in appropriate cases (Noah Misch, Robert Haas)
For example, converting a varchar column to text no longer requires a rewrite of the table. However, increasing the length
constraint on a varchar column still requires a table rewrite.

Add CREATE TABLE IF NOT EXISTS syntax (Robert Haas)


This allows table creation without causing an error if the table already exists.

Fix possible tuple concurrently updated error when two backends attempt to add an allance child to the same table at the
same time (Robert Haas)
ALTER TABLE now takes a stronger lock on the parent table, so that the sessions cannot try to update it simultaneously.

E.15.3.4.3. Object Permissions

Add a SECURITY LABEL command (KaiGai Kohei)


This allows security labels to be assigned to objects.

E.15.3.5. Utility Operations

Add transaction-level advisory locks (Marko Tiikkaja)


These are similar to the existing session-level advisory locks, but such locks are automatically released at transaction end.

Make TRUNCATE ... RESTART IDENTITY restart sequences transactionally (Steve Singer)
Previously the counter could have been left out of sync if a backend crashed between the on-commit truncation activity and
commit completion.

E.15.3.5.1. COPY

Add ENCODING option to COPY TO/FROM (Hitoshi Harada, Itagaki Takahiro)


This allows the encoding of the COPY file to be specified separately from client encoding.

Add bidirectional COPY protocol support (Fujii Masao)


This is currently only used by streaming replication.

E.15.3.5.2. EXPLAIN

Make EXPLAIN VERBOSE show the function call expression in a FunctionScan node (Tom Lane)

E.15.3.5.3. VACUUM

Add additional details to the output of VACUUM FULL VERBOSE and CLUSTER VERBOSE (Itagaki Takahiro)
New information includes the live and dead tuple count and whether CLUSTER is using an index to rebuild.

Prevent autovacuum from waiting if it cannot acquire a table lock (Robert Haas)
It will try to vacuum that table later.

E.15.3.5.4. CLUSTER

Allow CLUSTER to sort the table rather than scanning the index when it seems likely to be cheaper (Leonardo Francalanci)
1433

Notes de version

E.15.3.5.5. Indexes

Add nearest-neighbor (order-by-operator) searching to GiST indexes (Teodor Sigaev, Tom Lane)
This allows GiST indexes to quickly return the N closest values in a query with LIMIT. For example
SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
finds the ten places closest to a given target point.

Allow GIN indexes to index null and empty values (Tom Lane)
This allows full GIN index scans, and fixes various corner cases in which GIN scans would fail.

Allow GIN indexes to better recognize duplicate search entries (Tom Lane)
This reduces the cost of index scans, especially in cases where it avoids unnecessary full index scans.

Fix GiST indexes to be fully crash-safe (Heikki Linnakangas)


Previously there were rare cases where a REINDEX would be required (you would be informed).

E.15.3.6. Data Types

Allow numeric to use a more compact, two-byte header in common cases (Robert Haas)
Previously all numeric values had four-byte headers; this change saves on disk storage.

Add support for dividing money by money (Andy Balholm)

Allow binary I/O on type void (Radoslaw Smogura)

Improve hypotenuse calculations for geometric operators (Paul Matthews)


This avoids unnecessary overflows, and may also be more accurate.

Support hashing array values (Tom Lane)


This provides additional query optimization possibilities.

Don't treat a composite type as sortable unless all its column types are sortable (Tom Lane)
This avoids possible could not identify a comparison function failures at runtime, if it is possible to implement the query
without sorting. Also, ANALYZE won't try to use inappropriate statistics-gathering methods for columns of such composite
types.

E.15.3.6.1. Casting

Add support for casting between money and numeric (Andy Balholm)

Add support for casting from int4 and int8 to money (Joey Adams)

Allow casting a table's row type to the table's supertype if it's a typed table (Peter Eisentraut)
This is analogous to the existing facility that allows casting a row type to a supertable's row type.

E.15.3.6.2. XML

Add XML function XMLEXISTS and xpath_exists() functions (Mike Fowler)


These are used for XPath matching.

Add XML functions xml_is_well_formed(), xml_is_well_formed_document(),


xml_is_well_formed_content() (Mike Fowler)
These check whether the input is properly-formed XML. They provide functionality that was previously available only in the
deprecated contrib/xml2 module.

E.15.3.7. Functions
1434

Notes de version

Add SQL function format(text, ...), which behaves analogously to C's printf() (Pavel Stehule, Robert Haas)
It currently supports formats for strings, SQL literals, and SQL identifiers.

Add string functions concat(), concat_ws(), left(), right(), and reverse() (Pavel Stehule)
These improve compatibility with other database products.

Add function pg_read_binary_file() to read binary files (Dimitri Fontaine, Itagaki Takahiro)

Add a single-parameter version of function pg_read_file() to read an entire file (Dimitri Fontaine, Itagaki Takahiro)

Add three-parameter forms of array_to_string() and string_to_array() for null value processing control (Pavel
Stehule)

E.15.3.7.1. Object Information Functions

Add the pg_describe_object() function (Alvaro Herrera)


This function is used to obtain a human-readable string describing an object, based on the pg_class OID, object OID, and subobject ID. It can be used to help interpret the contents of pg_depend.

Update comments for built-in operators and their underlying functions (Tom Lane)
Functions that are meant to be used via an associated operator are now commented as such.

Add variable quote_all_identifiers to force the quoting of all identifiers in EXPLAIN and in system catalog functions like pg_get_viewdef() (Robert Haas)
This makes exporting schemas to tools and other databases with different quoting rules easier.

Add columns to the information_schema.sequences system view (Peter Eisentraut)


Previously, though the view existed, the columns about the sequence parameters were unimplemented.

Allow public as a pseudo-role name in has_table_privilege() and related functions (Alvaro Herrera)
This allows checking for public permissions.

E.15.3.7.2. Function and Trigger Creation

Support INSTEAD OF triggers on views (Dean Rasheed)


This feature can be used to implement fully updatable views.

E.15.3.8. Server-Side Languages


E.15.3.8.1. PL/pgSQL Server-Side Language

Add FOREACH IN ARRAY to PL/pgSQL (Pavel Stehule)


This is more efficient and readable than previous methods of iterating through the elements of an array value.

Allow RAISE without parameters to be caught in the same places that could catch a RAISE ERROR from the same location
(Piyush Newe)
The previous coding threw the error from the block containing the active exception handler. The new behavior is more
consistent with other DBMS products.

E.15.3.8.2. PL/Perl Server-Side Language

Allow generic record arguments to PL/Perl functions (Andrew Dunstan)


PL/Perl functions can now be declared to accept type record. The behavior is the same as for any named composite type.

Convert PL/Perl array arguments to Perl arrays (Alexey Klyukin, Alex Hunsaker)
String representations are still available.

Convert PL/Perl composite-type arguments to Perl hashes (Alexey Klyukin, Alex Hunsaker)
1435

Notes de version

String representations are still available.


E.15.3.8.3. PL/Python Server-Side Language

Add table function support for PL/Python (Jan Urbanski)


PL/Python can now return multiple OUT parameters and record sets.

Add a validator to PL/Python (Jan Urbanski)


This allows PL/Python functions to be syntax-checked at function creation time.

Allow exceptions for SQL queries in PL/Python (Jan Urbanski)


This allows access to SQL-generated exception error codes from PL/Python exception blocks.

Add explicit subtransactions to PL/Python (Jan Urbanski)

Add PL/Python functions for quoting strings (Jan Urbanski)


These functions are plpy.quote_ident, plpy.quote_literal, and plpy.quote_nullable.

Add traceback information to PL/Python errors (Jan Urbanski)

Report PL/Python errors from iterators with PLy_elog (Jan Urbanski)

Fix exception handling with Python 3 (Jan Urbanski)


Exception classes were previously not available in plpy under Python 3.

E.15.3.9. Client Applications

Mark createlang and droplang as deprecated now that they just invoke extension commands (Tom Lane)

E.15.3.9.1. psql

Add psql command \conninfo to show current connection information (David Christensen)

Add psql command \sf to show a function's definition (Pavel Stehule)

Add psql command \dL to list languages (Fernando Ike)

Add the S ( system ) option to psql's \dn (list schemas) command (Tom Lane)
\dn without S now suppresses system schemas.

Allow psql's \e and \ef commands to accept a line number to be used to position the cursor in the editor (Pavel Stehule)
This is passed to the editor according to the PSQL_EDITOR_LINENUMBER_ARG environment variable.

Have psql set the client encoding from the operating system locale by default (Heikki Linnakangas)
This only happens if the PGCLIENTENCODING environment variable is not set.

Make \d distinguish between unique indexes and unique constraints (Josh Kupershmidt)

Make \dt+ report pg_table_size instead of pg_relation_size when talking to 9.0 or later servers (Bernd Helmle)
This is a more useful measure of table size, but note that it is not identical to what was previously reported in the same display.

Additional tab completion support (Itagaki Takahiro, Pavel Stehule, Andrey Popp, Christoph Berg, David Fetter, Josh Kupershmidt)

E.15.3.9.2. pg_dump

Add pg_dump and pg_dumpall option --quote-all-identifiers to force quoting of all identifiers (Robert Haas)

Add directory format to pg_dump (Joachim Wieland, Heikki Linnakangas)


This is internally similar to the tar pg_dump format.

1436

Notes de version

E.15.3.9.3. pg_ctl

Fix pg_ctl so it no longer incorrectly reports that the server is not running (Bruce Momjian)
Previously this could happen if the server was running but pg_ctl could not authenticate.

Improve pg_ctl start's wait (-w) option (Bruce Momjian, Tom Lane)
The wait mode is now significantly more robust. It will not get confused by non-default postmaster port numbers, non-default
Unix-domain socket locations, permission problems, or stale postmaster lock files.

Add promote option to pg_ctl to switch a standby server to primary (Fujii Masao)

E.15.3.10. Development Tools


E.15.3.10.1. libpq

Add a libpq connection option client_encoding which behaves like the PGCLIENTENCODING environment variable
(Heikki Linnakangas)
The value auto sets the client encoding based on the operating system locale.

Add PQlibVersion() function which returns the libpq library version (Magnus Hagander)
libpq already had PQserverVersion() which returns the server version.

Allow libpq-using clients to check the user name of the server process when connecting via Unix-domain sockets, with the
new requirepeer connection option (Peter Eisentraut)
PostgreSQL already allowed servers to check the client user name when connecting via Unix-domain sockets.

Add PQping() and PQpingParams() to libpq (Bruce Momjian, Tom Lane)


These functions allow detection of the server's status without trying to open a new session.

E.15.3.10.2. ECPG

Allow ECPG to accept dynamic cursor names even in WHERE CURRENT OF clauses (Zoltan Boszormenyi)

Make ecpglib write double values with a precision of 15 digits, not 14 as formerly (Akira Kurosawa)

E.15.3.11. Build Options

Use +Olibmerrno compile flag with HP-UX C compilers that accept it (Ibrar Ahmed)
This avoids possible misbehavior of math library calls on recent HP platforms.

E.15.3.11.1. Makefiles

Improved parallel make support (Peter Eisentraut)


This allows for faster compiles. Also, make -k now works more consistently.

Require GNU make 3.80 or newer (Peter Eisentraut)


This is necessary because of the parallel-make improvements.

Add make maintainer-check target (Peter Eisentraut)


This target performs various source code checks that are not appropriate for either the build or the regression tests. Currently:
duplicate_oids, SGML syntax and tabs check, NLS syntax check.

Support make check in contrib (Peter Eisentraut)


Formerly only make installcheck worked, but now there is support for testing in a temporary installation. The top-level
make check-world target now includes testing contrib this way.

E.15.3.11.2. Windows

1437

Notes de version

On Windows, allow pg_ctl to register the service as auto-start or start-on-demand (Quan Zongliang)

Add support for collecting crash dumps on Windows (Craig Ringer, Magnus Hagander)
minidumps can now be generated by non-debug Windows binaries and analyzed by standard debugging tools.

Enable building with the MinGW64 compiler (Andrew Dunstan)


This allows building 64-bit Windows binaries even on non-Windows platforms via cross-compiling.

E.15.3.12. Source Code

Revise the API for GUC variable assign hooks (Tom Lane)
The previous functions of assign hooks are now split between check hooks and assign hooks, where the former can fail but the
latter shouldn't. This change will impact add-on modules that define custom GUC parameters.

Add latches to the source code to support waiting for events (Heikki Linnakangas)

Centralize data modification permissions-checking logic (KaiGai Kohei)

Add missing get_object_oid() functions, for consistency (Robert Haas)

Improve ability to use C++ compilers for compiling add-on modules by removing conflicting key words (Tom Lane)

Add support for DragonFly BSD (Rumko)

Expose quote_literal_cstr() for backend use (Robert Haas)

Run regression tests in the default encoding (Peter Eisentraut)


Regression tests were previously always run with SQL_ASCII encoding.

Add src/tools/git_changelog to replace cvs2cl and pgcvslog (Robert Haas, Tom Lane)

Add git-external-diff script to src/tools (Bruce Momjian)


This is used to generate context diffs from git.

Improve support for building with Clang (Peter Eisentraut)

E.15.3.12.1. Server Hooks

Add source code hooks to check permissions (Robert Haas, Stephen Frost)

Add post-object-creation function hooks for use by security frameworks (KaiGai Kohei)

Add a client authentication hook (KaiGai Kohei)

E.15.3.13. Contrib

Modify contrib modules and procedural languages to install via the new extension mechanism (Tom Lane, Dimitri Fontaine)

Add contrib/file_fdw foreign-data wrapper (Shigeru Hanada)


Foreign tables using this foreign data wrapper can read flat files in a manner very similar to COPY.

Add nearest-neighbor search support to contrib/pg_trgm and contrib/btree_gist (Teodor Sigaev)

Add contrib/btree_gist support for searching on not-equals (Jeff Davis)

Fix contrib/fuzzystrmatch's levenshtein() function to handle multibyte characters (Alexander Korotkov)

Add ssl_cipher() and ssl_version() functions to contrib/sslinfo (Robert Haas)

Fix contrib/intarray and contrib/hstore to give consistent results with indexed empty arrays (Tom Lane)
Previously an empty-array query that used an index might return different results from one that used a sequential scan.

Allow contrib/intarray to work properly on multidimensional arrays (Tom Lane)

In contrib/intarray, avoid errors complaining about the presence of nulls in cases where no nulls are actually present
(Tom Lane)
1438

Notes de version

In contrib/intarray, fix behavior of containment operators with respect to empty arrays (Tom Lane)
Empty arrays are now correctly considered to be contained in any other array.

Remove contrib/xml2's arbitrary limit on the number of parameter=value pairs that can be handled by
xslt_process() (Pavel Stehule)
The previous limit was 10.

In contrib/pageinspect, fix heap_page_item to return infomasks as 32-bit values (Alvaro Herrera)


This avoids returning negative values, which was confusing. The underlying value is a 16-bit unsigned integer.

E.15.3.13.1. Security

Add contrib/sepgsql to interface permission checks with SELinux (KaiGai Kohei)


This uses the new SECURITY LABEL facility.

Add contrib module auth_delay (KaiGai Kohei)


This causes the server to pause before returning authentication failure; it is designed to make brute force password attacks
more difficult.

Add dummy_seclabel contrib module (KaiGai Kohei)


This is used for permission regression testing.

E.15.3.13.2. Performance

Add support for LIKE and ILIKE index searches to contrib/pg_trgm (Alexander Korotkov)

Add levenshtein_less_equal() function to contrib/fuzzystrmatch, which is optimized for small distances


(Alexander Korotkov)

Improve performance of index lookups on contrib/seg columns (Alexander Korotkov)

Improve performance of pg_upgrade for databases with many relations (Bruce Momjian)

Add flag to contrib/pgbench to report per-statement latencies (Florian Pflug)

E.15.3.13.3. Fsync Testing

Move src/tools/test_fsync to contrib/pg_test_fsync (Bruce Momjian, Tom Lane)

Add O_DIRECT support to contrib/pg_test_fsync (Bruce Momjian)


This matches the use of O_DIRECT by wal_sync_method.

Add new tests to contrib/pg_test_fsync (Bruce Momjian)

E.15.3.14. Documentation

Extensive ECPG documentation improvements (Satoshi Nagayasu)

Extensive proofreading and documentation improvements (Thom Brown, Josh Kupershmidt, Susanne Ebrecht)

Add documentation for exit_on_error (Robert Haas)


This parameter causes sessions to exit on any error.

Add documentation for pg_options_to_table() (Josh Berkus)


This function shows table storage options in a readable form.

Document that it is possible to access all composite type fields using (compositeval).* syntax (Peter Eisentraut)

Document that translate() removes characters in from that don't have a corresponding to character (Josh Kupershmidt)

Merge documentation for CREATE CONSTRAINT TRIGGER and CREATE TRIGGER (Alvaro Herrera)

Centralize permission and upgrade documentation (Bruce Momjian)


1439

Notes de version

Add kernel tuning documentation for Solaris 10 (Josh Berkus)


Previously only Solaris 9 kernel tuning was documented.

Handle non-ASCII characters consistently in HISTORY file (Peter Eisentraut)


While the HISTORY file is in English, we do have to deal with non-ASCII letters in contributor names. These are now transliterated so that they are reasonably legible without assumptions about character set.

E.16. Release 9.0.18


Release Date
2014-07-24
This release contains a variety of fixes from 9.0.17. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.16.1. Migration to Version 9.0.18


A dump/restore is not required for those running 9.0.X.
However, this release corrects an index corruption problem in some GiST indexes. See the first changelog entry below to find out
whether your installation has been affected and what steps you should take if so.
Also, if you are upgrading from a version earlier than 9.0.15, see Section E.19, Release 9.0.15 .

E.16.2. Changes

Correctly initialize padding bytes in contrib/btree_gist indexes on bit columns (Heikki Linnakangas)
This error could result in incorrect query results due to values that should compare equal not being seen as equal. Users with
GiST indexes on bit or bit varying columns should REINDEX those indexes after installing this update.

Protect against torn pages when deleting GIN list pages (Heikki Linnakangas)
This fix prevents possible index corruption if a system crash occurs while the page update is being written to disk.

Don't clear the right-link of a GiST index page while replaying updates from WAL (Heikki Linnakangas)
This error could lead to transiently wrong answers from GiST index scans performed in Hot Standby.

Fix possibly-incorrect cache invalidation during nested calls to ReceiveSharedInvalidMessages (Andres Freund)

Don't assume a subquery's output is unique if there's a set-returning function in its targetlist (David Rowley)
This oversight could lead to misoptimization of constructs like WHERE x IN (SELECT y, generate_series(1,10) FROM t GROUP BY y).

Fix failure to detoast fields in composite elements of structured types (Tom Lane)
This corrects cases where TOAST pointers could be copied into other tables without being dereferenced. If the original data is
later deleted, it would lead to errors like missing chunk number 0 for toast value ... when the now-dangling pointer is used.

Fix record type has not been registered failures with whole-row references to the output of Append plan nodes (Tom Lane)

Fix possible crash when invoking a user-defined function while rewinding a cursor (Tom Lane)

Fix query-lifespan memory leak while evaluating the arguments for a function in FROM (Tom Lane)

Fix session-lifespan memory leaks in regular-expression processing (Tom Lane, Arthur O'Dwyer, Greg Stark)

Fix data encoding error in hungarian.stop (Tom Lane)

Fix liveness checks for rows that were inserted in the current transaction and then deleted by a now-rolled-back subtransaction
(Andres Freund)
This could cause problems (at least spurious warnings, and at worst an infinite loop) if CREATE INDEX or CLUSTER were
done later in the same transaction.

Clear pg_stat_activity.xact_start during PREPARE TRANSACTION (Andres Freund)


1440

Notes de version

After the PREPARE, the originating session is no longer in a transaction, so it should not continue to display a transaction
start time.

Fix REASSIGN OWNED to not fail for text search objects (lvaro Herrera)

Block signals during postmaster startup (Tom Lane)


This ensures that the postmaster will properly clean up after itself if, for example, it receives SIGINT while still starting up.

Secure Unix-domain sockets of temporary postmasters started during make check (Noah Misch)
Any local user able to access the socket file could connect as the server's bootstrap superuser, then proceed to execute arbitrary
code as the operating-system user running the test, as we previously noted in CVE-2014-0067. This change defends against
that risk by placing the server's socket in a temporary, mode 0700 subdirectory of /tmp. The hazard remains however on platforms where Unix sockets are not supported, notably Windows, because then the temporary postmaster must accept local TCP
connections.
A useful side effect of this change is to simplify make check testing in builds that override DEFAULT_PGSOCKET_DIR.
Popular non-default values like /var/run/postgresql are often not writable by the build user, requiring workarounds
that will no longer be necessary.

Fix tablespace creation WAL replay to work on Windows (MauMau)

Fix detection of socket creation failures on Windows (Bruce Momjian)

On Windows, allow new sessions to absorb values of PGC_BACKEND parameters (such as log_connections) from the configuration file (Amit Kapila)
Previously, if such a parameter were changed in the file post-startup, the change would have no effect.

Properly quote executable path names on Windows (Nikhil Deshpande)


This oversight could cause initdb and pg_upgrade to fail on Windows, if the installation path contained both spaces and @ signs.

Fix linking of libpython on OS X (Tom Lane)


The method we previously used can fail with the Python library supplied by Xcode 5.0 and later.

Avoid buffer bloat in libpq when the server consistently sends data faster than the client can absorb it (Shin-ichi Morita, Tom
Lane)
libpq could be coerced into enlarging its input buffer until it runs out of memory (which would be reported misleadingly as
lost synchronization with server ). Under ordinary circumstances it's quite far-fetched that data could be continuously transmitted more quickly than the recv() loop can absorb it, but this has been observed when the client is artificially slowed by
scheduler constraints.

Ensure that LDAP lookup attempts in libpq time out as intended (Laurenz Albe)

Fix ecpg to do the right thing when an array of char * is the target for a FETCH statement returning more than one row, as
well as some other array-handling fixes (Ashutosh Bapat)

Fix pg_restore's processing of old-style large object comments (Tom Lane)


A direct-to-database restore from an archive file generated by a pre-9.0 version of pg_dump would usually fail if the archive
contained more than a few comments for large objects.

In contrib/pgcrypto functions, ensure sensitive information is cleared from stack variables before returning (Marko
Kreen)

In contrib/uuid-ossp, cache the state of the OSSP UUID library across calls (Tom Lane)
This improves the efficiency of UUID generation and reduces the amount of entropy drawn from /dev/urandom, on platforms that have that.

Update time zone data files to tzdata release 2014e for DST law changes in Crimea, Egypt, and Morocco.

E.17. Release 9.0.17


Release Date
1441

Notes de version

2014-03-20
This release contains a variety of fixes from 9.0.16. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.17.1. Migration to Version 9.0.17


A dump/restore is not required for those running 9.0.X.
However, if you are upgrading from a version earlier than 9.0.15, see Section E.19, Release 9.0.15 .

E.17.2. Changes

Restore GIN metapages unconditionally to avoid torn-page risk (Heikki Linnakangas)


Although this oversight could theoretically result in a corrupted index, it is unlikely to have caused any problems in practice,
since the active part of a GIN metapage is smaller than a standard 512-byte disk sector.

Avoid race condition in checking transaction commit status during receipt of a NOTIFY message (Marko Tiikkaja)
This prevents a scenario wherein a sufficiently fast client might respond to a notification before database updates made by the
notifier have become visible to the recipient.

Allow regular-expression operators to be terminated early by query cancel requests (Tom Lane)
This prevents scenarios wherein a pathological regular expression could lock up a server process uninterruptably for a long
time.

Remove incorrect code that tried to allow OVERLAPS with single-element row arguments (Joshua Yanovski)
This code never worked correctly, and since the case is neither specified by the SQL standard nor documented, it seemed better to remove it than fix it.

Avoid getting more than AccessShareLock when de-parsing a rule or view (Dean Rasheed)
This oversight resulted in pg_dump unexpectedly acquiring RowExclusiveLock locks on tables mentioned as the targets
of INSERT/UPDATE/DELETE commands in rules. While usually harmless, that could interfere with concurrent transactions
that tried to acquire, for example, ShareLock on those tables.

Improve performance of index endpoint probes during planning (Tom Lane)


This change fixes a significant performance problem that occurred when there were many not-yet-committed rows at the end
of the index, which is a common situation for indexes on sequentially-assigned values such as timestamps or sequence-generated identifiers.

Fix test to see if hot standby connections can be allowed immediately after a crash (Heikki Linnakangas)

Prevent interrupts while reporting non-ERROR messages (Tom Lane)


This guards against rare server-process freezeups due to recursive entry to syslog(), and perhaps other related problems.

Prevent intermittent could not reserve shared memory region failures on recent Windows versions (MauMau)

Update time zone data files to tzdata release 2014a for DST law changes in Fiji and Turkey, plus historical changes in Israel
and Ukraine.

E.18. Release 9.0.16


Release Date
2014-02-20
This release contains a variety of fixes from 9.0.15. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.18.1. Migration to Version 9.0.16


1442

Notes de version

A dump/restore is not required for those running 9.0.X.


However, if you are upgrading from a version earlier than 9.0.15, see Section E.19, Release 9.0.15 .

E.18.2. Changes

Shore up GRANT ... WITH ADMIN OPTION restrictions (Noah Misch)


Granting a role without ADMIN OPTION is supposed to prevent the grantee from adding or removing members from the
granted role, but this restriction was easily bypassed by doing SET ROLE first. The security impact is mostly that a role member can revoke the access of others, contrary to the wishes of his grantor. Unapproved role member additions are a lesser
concern, since an uncooperative role member could provide most of his rights to others anyway by creating views or SECURITY DEFINER functions. (CVE-2014-0060)

Prevent privilege escalation via manual calls to PL validator functions (Andres Freund)
The primary role of PL validator functions is to be called implicitly during CREATE FUNCTION, but they are also normal
SQL functions that a user can call explicitly. Calling a validator on a function actually written in some other language was not
checked for and could be exploited for privilege-escalation purposes. The fix involves adding a call to a privilege-checking
function in each validator function. Non-core procedural languages will also need to make this change to their own validator
functions, if any. (CVE-2014-0061)

Avoid multiple name lookups during table and index DDL (Robert Haas, Andres Freund)
If the name lookups come to different conclusions due to concurrent activity, we might perform some parts of the DDL on a
different table than other parts. At least in the case of CREATE INDEX, this can be used to cause the permissions checks to
be performed against a different table than the index creation, allowing for a privilege escalation attack. (CVE-2014-0062)

Prevent buffer overrun with long datetime strings (Noah Misch)


The MAXDATELEN constant was too small for the longest possible value of type interval, allowing a buffer overrun in interval_out(). Although the datetime input functions were more careful about avoiding buffer overrun, the limit was short
enough to cause them to reject some valid inputs, such as input containing a very long timezone name. The ecpg library
contained these vulnerabilities along with some of its own. (CVE-2014-0063)

Prevent buffer overrun due to integer overflow in size calculations (Noah Misch, Heikki Linnakangas)
Several functions, mostly type input functions, calculated an allocation size without checking for overflow. If overflow did occur, a too-small buffer would be allocated and then written past. (CVE-2014-0064)

Prevent overruns of fixed-size buffers (Peter Eisentraut, Jozef Mlich)


Use strlcpy() and related functions to provide a clear guarantee that fixed-size buffers are not overrun. Unlike the preceding items, it is unclear whether these cases really represent live issues, since in most cases there appear to be previous
constraints on the size of the input string. Nonetheless it seems prudent to silence all Coverity warnings of this type.
(CVE-2014-0065)

Avoid crashing if crypt() returns NULL (Honza Horak, Bruce Momjian)


There are relatively few scenarios in which crypt() could return NULL, but contrib/chkpass would crash if it did.
One practical case in which this could be an issue is if libc is configured to refuse to execute unapproved hashing algorithms
(e.g., FIPS mode ). (CVE-2014-0066)

Document risks of make check in the regression testing instructions (Noah Misch, Tom Lane)
Since the temporary server started by make check uses trust authentication, another user on the same machine could
connect to it as database superuser, and then potentially exploit the privileges of the operating-system user who started the
tests. A future release will probably incorporate changes in the testing procedure to prevent this risk, but some public discussion is needed first. So for the moment, just warn people against using make check when there are untrusted users on the
same machine. (CVE-2014-0067)

Fix possible mis-replay of WAL records when some segments of a relation aren't full size (Greg Stark, Tom Lane)
The WAL update could be applied to the wrong page, potentially many pages past where it should have been. Aside from corrupting data, this error has been observed to result in significant bloat of standby servers compared to their masters, due to
updates being applied far beyond where the end-of-file should have been. This failure mode does not appear to be a significant
risk during crash recovery, only when initially synchronizing a standby created from a base backup taken from a quicklychanging master.

Fix bug in determining when recovery has reached consistency (Tomonari Katsumata, Heikki Linnakangas)
1443

Notes de version

In some cases WAL replay would mistakenly conclude that the database was already consistent at the start of replay, thus possibly allowing hot-standby queries before the database was really consistent. Other symptoms such as PANIC: WAL
contains references to invalid pages were also possible.

Fix improper locking of btree index pages while replaying a VACUUM operation in hot-standby mode (Andres Freund, Heikki
Linnakangas, Tom Lane)
This error could result in PANIC: WAL contains references to invalid pages failures.

Ensure that insertions into non-leaf GIN index pages write a full-page WAL record when appropriate (Heikki Linnakangas)
The previous coding risked index corruption in the event of a partial-page write during a system crash.

Fix race conditions during server process exit (Robert Haas)


Ensure that signal handlers don't attempt to use the process's MyProc pointer after it's no longer valid.

Fix unsafe references to errno within error reporting logic (Christian Kruse)
This would typically lead to odd behaviors such as missing or inappropriate HINT fields.

Fix possible crashes from using ereport() too early during server startup (Tom Lane)
The principal case we've seen in the field is a crash if the server is started in a directory it doesn't have permission to read.

Clear retry flags properly in OpenSSL socket write function (Alexander Kukushkin)
This omission could result in a server lockup after unexpected loss of an SSL-encrypted connection.

Fix length checking for Unicode identifiers (U&"..." syntax) containing escapes (Tom Lane)
A spurious truncation warning would be printed for such identifiers if the escaped form of the identifier was too long, but the
identifier actually didn't need truncation after de-escaping.

Allow keywords that are type names to be used in lists of roles (Stephen Frost)
A previous patch allowed such keywords to be used without quoting in places such as role identifiers; but it missed cases
where a list of role identifiers was permitted, such as DROP ROLE.

Fix possible crash due to invalid plan for nested sub-selects, such as WHERE (... x IN (SELECT ...) ...) IN
(SELECT ...) (Tom Lane)

Ensure that ANALYZE creates statistics for a table column even when all the values in it are too wide (Tom Lane)
ANALYZE intentionally omits very wide values from its histogram and most-common-values calculations, but it neglected to
do something sane in the case that all the sampled entries are too wide.

In ALTER TABLE ... SET TABLESPACE, allow the database's default tablespace to be used without a permissions
check (Stephen Frost)
CREATE TABLE has always allowed such usage, but ALTER TABLE didn't get the memo.

Fix cannot accept a set error when some arms of a CASE return a set and others don't (Tom Lane)

Fix checks for all-zero client addresses in pgstat functions (Kevin Grittner)

Fix possible misclassification of multibyte characters by the text search parser (Tom Lane)
Non-ASCII characters could be misclassified when using C locale with a multibyte encoding. On Cygwin, non-C locales could
fail as well.

Fix possible misbehavior in plainto_tsquery() (Heikki Linnakangas)


Use memmove() not memcpy() for copying overlapping memory regions. There have been no field reports of this actually
causing trouble, but it's certainly risky.

Accept SHIFT_JIS as an encoding name for locale checking purposes (Tatsuo Ishii)

Fix misbehavior of PQhost() on Windows (Fujii Masao)


It should return localhost if no host has been specified.

Improve error handling in libpq and psql for failures during COPY TO STDOUT/FROM STDIN (Tom Lane)
In particular this fixes an infinite loop that could occur in 9.2 and up if the server connection was lost during COPY FROM
STDIN. Variants of that scenario might be possible in older versions, or with other client applications.
1444

Notes de version

Fix misaligned descriptors in ecpg (MauMau)

In ecpg, handle lack of a hostname in the connection parameters properly (Michael Meskes)

Fix performance regression in contrib/dblink connection startup (Joe Conway)


Avoid an unnecessary round trip when client and server encodings match.

In contrib/isn, fix incorrect calculation of the check digit for ISMN values (Fabien Coelho)

Ensure client-code-only installation procedure works as documented (Peter Eisentraut)

In Mingw and Cygwin builds, install the libpq DLL in the bin directory (Andrew Dunstan)
This duplicates what the MSVC build has long done. It should fix problems with programs like psql failing to start because
they can't find the DLL.

Avoid using the deprecated dllwrap tool in Cygwin builds (Marco Atzeri)

Don't generate plain-text HISTORY and src/test/regress/README files anymore (Tom Lane)
These text files duplicated the main HTML and PDF documentation formats. The trouble involved in maintaining them greatly
outweighs the likely audience for plain-text format. Distribution tarballs will still contain files by these names, but they'll just
be stubs directing the reader to consult the main documentation. The plain-text INSTALL file will still be maintained, as there
is arguably a use-case for that.

Update time zone data files to tzdata release 2013i for DST law changes in Jordan and historical changes in Cuba.
In addition, the zones Asia/Riyadh87, Asia/Riyadh88, and Asia/Riyadh89 have been removed, as they are no longer maintained by IANA, and never represented actual civil timekeeping practice.

E.19. Release 9.0.15


Release Date
2013-12-05
This release contains a variety of fixes from 9.0.14. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.19.1. Migration to Version 9.0.15


A dump/restore is not required for those running 9.0.X.
However, this release corrects a number of potential data corruption issues. See the first two changelog entries below to find out
whether your installation has been affected and what steps you can take if so.
Also, if you are upgrading from a version earlier than 9.0.13, see Section E.21, Release 9.0.13 .

E.19.2. Changes

Fix VACUUM's tests to see whether it can update relfrozenxid (Andres Freund)
In some cases VACUUM (either manual or autovacuum) could incorrectly advance a table's relfrozenxid value, allowing
tuples to escape freezing, causing those rows to become invisible once 2^31 transactions have elapsed. The probability of data
loss is fairly low since multiple incorrect advancements would need to happen before actual loss occurs, but it's not zero. Users
upgrading from releases 9.0.4 or 8.4.8 or earlier are not affected, but all later versions contain the bug.
The issue can be ameliorated by, after upgrading, vacuuming all tables in all databases while having vacuum_freeze_table_age set to zero. This will fix any latent corruption but will not be able to fix all pre-existing data
errors. However, an installation can be presumed safe after performing this vacuuming if it has executed fewer than 2^31 update transactions in its lifetime (check this with SELECT txid_current() < 2^31).

Fix initialization of pg_clog and pg_subtrans during hot standby startup (Andres Freund, Heikki Linnakangas)
This bug can cause data loss on standby servers at the moment they start to accept hot-standby queries, by marking committed
transactions as uncommitted. The likelihood of such corruption is small unless, at the time of standby startup, the primary server has executed many updating transactions since its last checkpoint. Symptoms include missing rows, rows that should have
been deleted being still visible, and obsolete versions of updated rows being still visible alongside their newer versions.
1445

Notes de version

This bug was introduced in versions 9.3.0, 9.2.5, 9.1.10, and 9.0.14. Standby servers that have only been running earlier releases are not at risk. It's recommended that standby servers that have ever run any of the buggy releases be re-cloned from the
primary (e.g., with a new base backup) after upgrading.

Truncate pg_multixact contents during WAL replay (Andres Freund)


This avoids ever-increasing disk space consumption in standby servers.

Fix race condition in GIN index posting tree page deletion (Heikki Linnakangas)
This could lead to transient wrong answers or query failures.

Avoid flattening a subquery whose SELECT list contains a volatile function wrapped inside a sub-SELECT (Tom Lane)
This avoids unexpected results due to extra evaluations of the volatile function.

Fix planner's processing of non-simple-variable subquery outputs nested within outer joins (Tom Lane)
This error could lead to incorrect plans for queries involving multiple levels of subqueries within JOIN syntax.

Fix premature deletion of temporary files (Andres Freund)

Fix possible read past end of memory in rule printing (Peter Eisentraut)

Fix array slicing of int2vector and oidvector values (Tom Lane)


Expressions of this kind are now implicitly promoted to regular int2 or oid arrays.

Fix incorrect behaviors when using a SQL-standard, simple GMT offset timezone (Tom Lane)
In some cases, the system would use the simple GMT offset value when it should have used the regular timezone setting that
had prevailed before the simple offset was selected. This change also causes the timeofday function to honor the simple
GMT offset zone.

Prevent possible misbehavior when logging translations of Windows error codes (Tom Lane)

Properly quote generated command lines in pg_ctl (Naoya Anzai and Tom Lane)
This fix applies only to Windows.

Fix pg_dumpall to work when a source database sets default_transaction_read_only via ALTER DATABASE
SET (Kevin Grittner)
Previously, the generated script would fail during restore.

Fix ecpg's processing of lists of variables declared varchar (Zoltn Bszrmnyi)

Make contrib/lo defend against incorrect trigger definitions (Marc Cousin)

Update time zone data files to tzdata release 2013h for DST law changes in Argentina, Brazil, Jordan, Libya, Liechtenstein,
Morocco, and Palestine. Also, new timezone abbreviations WIB, WIT, WITA for Indonesia.

E.20. Release 9.0.14


Release Date
2013-10-10
This release contains a variety of fixes from 9.0.13. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.20.1. Migration to Version 9.0.14


A dump/restore is not required for those running 9.0.X.
However, if you are upgrading from a version earlier than 9.0.13, see Section E.21, Release 9.0.13 .

E.20.2. Changes

Prevent corruption of multi-byte characters when attempting to case-fold identifiers (Andrew Dunstan)
1446

Notes de version

PostgreSQL case-folds non-ASCII characters only when using a single-byte server encoding.

Fix checkpoint memory leak in background writer when wal_level = hot_standby (Naoya Anzai)

Fix memory leak caused by lo_open() failure (Heikki Linnakangas)

Fix memory overcommit bug when work_mem is using more than 24GB of memory (Stephen Frost)

Fix deadlock bug in libpq when using SSL (Stephen Frost)

Fix possible SSL state corruption in threaded libpq applications (Nick Phillips, Stephen Frost)

Properly compute row estimates for boolean columns containing many NULL values (Andrew Gierth)
Previously tests like col IS NOT TRUE and col IS NOT FALSE did not properly factor in NULL values when estimating plan costs.

Prevent pushing down WHERE clauses into unsafe UNION/INTERSECT subqueries (Tom Lane)
Subqueries of a UNION or INTERSECT that contain set-returning functions or volatile functions in their SELECT lists could
be improperly optimized, leading to run-time errors or incorrect query results.

Fix rare case of failed to locate grouping columns planner failure (Tom Lane)

Improve view dumping code's handling of dropped columns in referenced tables (Tom Lane)

Properly record index comments created using UNIQUE and PRIMARY KEY syntax (Andres Freund)
This fixes a parallel pg_restore failure.

Fix REINDEX TABLE and REINDEX DATABASE to properly revalidate constraints and mark invalidated indexes as valid
(Noah Misch)
REINDEX INDEX has always worked properly.

Fix possible deadlock during concurrent CREATE INDEX CONCURRENTLY operations (Tom Lane)

Fix regexp_matches() handling of zero-length matches (Jeevan Chalke)


Previously, zero-length matches like '^' could return too many matches.

Fix crash for overly-complex regular expressions (Heikki Linnakangas)

Fix regular expression match failures for back references combined with non-greedy quantifiers (Jeevan Chalke)

Prevent CREATE FUNCTION from checking SET variables unless function body checking is enabled (Tom Lane)

Allow ALTER DEFAULT PRIVILEGES to operate on schemas without requiring CREATE permission (Tom Lane)

Loosen restriction on keywords used in queries (Tom Lane)


Specifically, lessen keyword restrictions for role names, language names, EXPLAIN and COPY options, and SET values.
This allows COPY ... (FORMAT BINARY) to work as expected; previously BINARY needed to be quoted.

Fix pgp_pub_decrypt() so it works for secret keys with passwords (Marko Kreen)

Remove rare inaccurate warning during vacuum of index-less tables (Heikki Linnakangas)

Ensure that VACUUM ANALYZE still runs the ANALYZE phase if its attempt to truncate the file is cancelled due to lock
conflicts (Kevin Grittner)

Avoid possible failure when performing transaction control commands (e.g ROLLBACK) in prepared queries (Tom Lane)

Ensure that floating-point data input accepts standard spellings of infinity on all platforms (Tom Lane)
The C99 standard says that allowable spellings are inf, +inf, -inf, infinity, +infinity, and -infinity. Make
sure we recognize these even if the platform's strtod function doesn't.

Expand ability to compare rows to records and arrays (Rafal Rzepecki, Tom Lane)

Update time zone data files to tzdata release 2013d for DST law changes in Israel, Morocco, Palestine, and Paraguay. Also,
historical zone data corrections for Macquarie Island.

E.21. Release 9.0.13


1447

Notes de version

Release Date
2013-04-04
This release contains a variety of fixes from 9.0.12. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.21.1. Migration to Version 9.0.13


A dump/restore is not required for those running 9.0.X.
However, this release corrects several errors in management of GiST indexes. After installing this update, it is advisable to REINDEX any GiST indexes that meet one or more of the conditions described below.
Also, if you are upgrading from a version earlier than 9.0.6, see Section E.28, Release 9.0.6 .

E.21.2. Changes

Fix insecure parsing of server command-line switches (Mitsumasa Kondo, Kyotaro Horiguchi)
A connection request containing a database name that begins with - could be crafted to damage or destroy files within the
server's data directory, even if the request is eventually rejected. (CVE-2013-1899)

Reset OpenSSL randomness state in each postmaster child process (Marko Kreen)
This avoids a scenario wherein random numbers generated by contrib/pgcrypto functions might be relatively easy for
another database user to guess. The risk is only significant when the postmaster is configured with ssl = on but most connections don't use SSL encryption. (CVE-2013-1900)

Fix GiST indexes to not use fuzzy geometric comparisons when it's not appropriate to do so (Alexander Korotkov)
The core geometric types perform comparisons using fuzzy equality, but gist_box_same must do exact comparisons,
else GiST indexes using it might become inconsistent. After installing this update, users should REINDEX any GiST indexes
on box, polygon, circle, or point columns, since all of these use gist_box_same.

Fix erroneous range-union and penalty logic in GiST indexes that use contrib/btree_gist for variable-width data
types, that is text, bytea, bit, and numeric columns (Tom Lane)
These errors could result in inconsistent indexes in which some keys that are present would not be found by searches, and also
in useless index bloat. Users are advised to REINDEX such indexes after installing this update.

Fix bugs in GiST page splitting code for multi-column indexes (Tom Lane)
These errors could result in inconsistent indexes in which some keys that are present would not be found by searches, and also
in indexes that are unnecessarily inefficient to search. Users are advised to REINDEX multi-column GiST indexes after installing this update.

Fix gist_point_consistent to handle fuzziness consistently (Alexander Korotkov)


Index scans on GiST indexes on point columns would sometimes yield results different from a sequential scan, because
gist_point_consistent disagreed with the underlying operator code about whether to do comparisons exactly or fuzzily.

Fix buffer leak in WAL replay (Heikki Linnakangas)


This bug could result in incorrect local pin count errors during replay, making recovery impossible.

Fix race condition in DELETE RETURNING (Tom Lane)


Under the right circumstances, DELETE RETURNING could attempt to fetch data from a shared buffer that the current process no longer has any pin on. If some other process changed the buffer meanwhile, this would lead to garbage RETURNING
output, or even a crash.

Fix infinite-loop risk in regular expression compilation (Tom Lane, Don Porter)

Fix potential null-pointer dereference in regular expression compilation (Tom Lane)

Fix to_char() to use ASCII-only case-folding rules where appropriate (Tom Lane)
This fixes misbehavior of some template patterns that should be locale-independent, but mishandled I and i in Turkish
locales.
1448

Notes de version

Fix unwanted rejection of timestamp 1999-12-31 24:00:00 (Tom Lane)

Fix logic error when a single transaction does UNLISTEN then LISTEN (Tom Lane)
The session wound up not listening for notify events at all, though it surely should listen in this case.

Remove useless picksplit doesn't support secondary split log messages (Josh Hansen, Tom Lane)
This message seems to have been added in expectation of code that was never written, and probably never will be, since
GiST's default handling of secondary splits is actually pretty good. So stop nagging end users about it.

Fix possible failure to send a session's last few transaction commit/abort counts to the statistics collector (Tom Lane)

Eliminate memory leaks in PL/Perl's spi_prepare() function (Alex Hunsaker, Tom Lane)

Fix pg_dumpall to handle database names containing = correctly (Heikki Linnakangas)

Avoid crash in pg_dump when an incorrect connection string is given (Heikki Linnakangas)

Ignore invalid indexes in pg_dump and pg_upgrade (Michael Paquier, Bruce Momjian)
Dumping invalid indexes can cause problems at restore time, for example if the reason the index creation failed was because it
tried to enforce a uniqueness condition not satisfied by the table's data. Also, if the index creation is in fact still in progress, it
seems reasonable to consider it to be an uncommitted DDL change, which pg_dump wouldn't be expected to dump anyway.
pg_upgrade now also skips invalid indexes rather than failing.

Fix contrib/pg_trgm's similarity() function to return zero for trigram-less strings (Tom Lane)
Previously it returned NaN due to internal division by zero.

Update time zone data files to tzdata release 2013b for DST law changes in Chile, Haiti, Morocco, Paraguay, and some Russian areas. Also, historical zone data corrections for numerous places.
Also, update the time zone abbreviation files for recent changes in Russia and elsewhere: CHOT, GET, IRKT, KGT, KRAT,
MAGT, MAWT, MSK, NOVT, OMST, TKT, VLAT, WST, YAKT, YEKT now follow their current meanings, and VOLT
(Europe/Volgograd) and MIST (Antarctica/Macquarie) are added to the default abbreviations list.

E.22. Release 9.0.12


Release Date
2013-02-07
This release contains a variety of fixes from 9.0.11. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.22.1. Migration to Version 9.0.12


A dump/restore is not required for those running 9.0.X.
However, if you are upgrading from a version earlier than 9.0.6, see Section E.28, Release 9.0.6 .

E.22.2. Changes

Prevent execution of enum_recv from SQL (Tom Lane)


The function was misdeclared, allowing a simple SQL command to crash the server. In principle an attacker might be able to
use it to examine the contents of server memory. Our thanks to Sumit Soni (via Secunia SVCRP) for reporting this issue.
(CVE-2013-0255)

Fix multiple problems in detection of when a consistent database state has been reached during WAL replay (Fujii Masao,
Heikki Linnakangas, Simon Riggs, Andres Freund)

Update minimum recovery point when truncating a relation file (Heikki Linnakangas)
Once data has been discarded, it's no longer safe to stop recovery at an earlier point in the timeline.

Fix missing cancellations in hot standby mode (Noah Misch, Simon Riggs)
The need to cancel conflicting hot-standby queries would sometimes be missed, allowing those queries to see inconsistent da1449

Notes de version

ta.

Fix SQL grammar to allow subscripting or field selection from a sub-SELECT result (Tom Lane)

Fix performance problems with autovacuum truncation in busy workloads (Jan Wieck)
Truncation of empty pages at the end of a table requires exclusive lock, but autovacuum was coded to fail (and release the
table lock) when there are conflicting lock requests. Under load, it is easily possible that truncation would never occur, resulting in table bloat. Fix by performing a partial truncation, releasing the lock, then attempting to re-acquire the lock and continue. This fix also greatly reduces the average time before autovacuum releases the lock after a conflicting request arrives.

Protect against race conditions when scanning pg_tablespace (Stephen Frost, Tom Lane)
CREATE DATABASE and DROP DATABASE could misbehave if there were concurrent updates of pg_tablespace entries.

Prevent DROP OWNED from trying to drop whole databases or tablespaces (lvaro Herrera)
For safety, ownership of these objects must be reassigned, not dropped.

Fix error in vacuum_freeze_table_age implementation (Andres Freund)


In installations that have existed for more than vacuum_freeze_min_age transactions, this mistake prevented autovacuum from using partial-table scans, so that a full-table scan would always happen instead.

Prevent misbehavior when a RowExpr or XmlExpr is parse-analyzed twice (Andres Freund, Tom Lane)
This mistake could be user-visible in contexts such as CREATE TABLE LIKE INCLUDING INDEXES.

Improve defenses against integer overflow in hashtable sizing calculations (Jeff Davis)

Reject out-of-range dates in to_date() (Hitoshi Harada)

Ensure that non-ASCII prompt strings are translated to the correct code page on Windows (Alexander Law, Noah Misch)
This bug affected psql and some other client programs.

Fix possible crash in psql's \? command when not connected to a database (Meng Qingzhong)

Fix pg_upgrade to deal with invalid indexes safely (Bruce Momjian)

Fix one-byte buffer overrun in libpq's PQprintTuples (Xi Wang)


This ancient function is not used anywhere by PostgreSQL itself, but it might still be used by some client code.

Make ecpglib use translated messages properly (Chen Huajun)

Properly install ecpg_compat and pgtypes libraries on MSVC (Jiang Guiqing)

Include our version of isinf() in libecpg if it's not provided by the system (Jiang Guiqing)

Rearrange configure's tests for supplied functions so it is not fooled by bogus exports from libedit/libreadline (Christoph Berg)

Ensure Windows build number increases over time (Magnus Hagander)

Make pgxs build executables with the right .exe suffix when cross-compiling for Windows (Zoltan Boszormenyi)

Add new timezone abbreviation FET (Tom Lane)


This is now used in some eastern-European time zones.

E.23. Release 9.0.11


Release Date
2012-12-06
This release contains a variety of fixes from 9.0.10. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.23.1. Migration to Version 9.0.11


A dump/restore is not required for those running 9.0.X.
1450

Notes de version

However, if you are upgrading from a version earlier than 9.0.6, see Section E.28, Release 9.0.6 .

E.23.2. Changes

Fix multiple bugs associated with CREATE INDEX CONCURRENTLY (Andres Freund, Tom Lane)
Fix CREATE INDEX CONCURRENTLY to use in-place updates when changing the state of an index's pg_index row. This
prevents race conditions that could cause concurrent sessions to miss updating the target index, thus resulting in corrupt
concurrently-created indexes.
Also, fix various other operations to ensure that they ignore invalid indexes resulting from a failed CREATE INDEX
CONCURRENTLY command. The most important of these is VACUUM, because an auto-vacuum could easily be launched
on the table before corrective action can be taken to fix or remove the invalid index.

Fix buffer locking during WAL replay (Tom Lane)


The WAL replay code was insufficiently careful about locking buffers when replaying WAL records that affect more than one
page. This could result in hot standby queries transiently seeing inconsistent states, resulting in wrong answers or unexpected
failures.

Fix an error in WAL generation logic for GIN indexes (Tom Lane)
This could result in index corruption, if a torn-page failure occurred.

Properly remove startup process's virtual XID lock when promoting a hot standby server to normal running (Simon Riggs)
This oversight could prevent subsequent execution of certain operations such as CREATE INDEX CONCURRENTLY.

Avoid bogus out-of-sequence timeline ID errors in standby mode (Heikki Linnakangas)

Prevent the postmaster from launching new child processes after it's received a shutdown signal (Tom Lane)
This mistake could result in shutdown taking longer than it should, or even never completing at all without additional user action.

Avoid corruption of internal hash tables when out of memory (Hitoshi Harada)

Fix planning of non-strict equivalence clauses above outer joins (Tom Lane)
The planner could derive incorrect constraints from a clause equating a non-strict construct to something else, for example
WHERE COALESCE(foo, 0) = 0 when foo is coming from the nullable side of an outer join.

Improve planner's ability to prove exclusion constraints from equivalence classes (Tom Lane)

Fix partial-row matching in hashed subplans to handle cross-type cases correctly (Tom Lane)
This affects multicolumn NOT IN subplans, such as WHERE (a, b) NOT IN (SELECT x, y FROM ...) when for
instance b and y are int4 and int8 respectively. This mistake led to wrong answers or crashes depending on the specific datatypes involved.

Acquire buffer lock when re-fetching the old tuple for an AFTER ROW UPDATE/DELETE trigger (Andres Freund)
In very unusual circumstances, this oversight could result in passing incorrect data to the precheck logic for a foreign-key enforcement trigger. That could result in a crash, or in an incorrect decision about whether to fire the trigger.

Fix ALTER COLUMN TYPE to handle alled check constraints properly (Pavan Deolasee)
This worked correctly in pre-8.4 releases, and now works correctly in 8.4 and later.

Fix REASSIGN OWNED to handle grants on tablespaces (lvaro Herrera)

Ignore incorrect pg_attribute entries for system columns for views (Tom Lane)
Views do not have any system columns. However, we forgot to remove such entries when converting a table to a view. That's
fixed properly for 9.3 and later, but in previous branches we need to defend against existing mis-converted views.

Fix rule printing to dump INSERT INTO table DEFAULT VALUES correctly (Tom Lane)

Guard against stack overflow when there are too many UNION/INTERSECT/EXCEPT clauses in a query (Tom Lane)

Prevent platform-dependent failures when dividing the minimum possible integer value by -1 (Xi Wang, Tom Lane)

Fix possible access past end of string in date parsing (Hitoshi Harada)

Fix failure to advance XID epoch if XID wraparound happens during a checkpoint and wal_level is hot_standby (Tom
1451

Notes de version

Lane, Andres Freund)


While this mistake had no particular impact on PostgreSQL itself, it was bad for applications that rely on
txid_current() and related functions: the TXID value would appear to go backwards.

Produce an understandable error message if the length of the path name for a Unix-domain socket exceeds the platform-specific limit (Tom Lane, Andrew Dunstan)
Formerly, this would result in something quite unhelpful, such as Non-recoverable failure in name resolution .

Fix memory leaks when sending composite column values to the client (Tom Lane)

Make pg_ctl more robust about reading the postmaster.pid file (Heikki Linnakangas)
Fix race conditions and possible file descriptor leakage.

Fix possible crash in psql if incorrectly-encoded data is presented and the client_encoding setting is a client-only encoding, such as SJIS (Jiang Guiqing)

Fix bugs in the restore.sql script emitted by pg_dump in tar output format (Tom Lane)
The script would fail outright on tables whose names include upper-case characters. Also, make the script capable of restoring
data in --inserts mode as well as the regular COPY mode.

Fix pg_restore to accept POSIX-conformant tar files (Brian Weaver, Tom Lane)
The original coding of pg_dump's tar output mode produced files that are not fully conformant with the POSIX standard.
This has been corrected for version 9.3. This patch updates previous branches so that they will accept both the incorrect and
the corrected formats, in hopes of avoiding compatibility problems when 9.3 comes out.

Fix pg_resetxlog to locate postmaster.pid correctly when given a relative path to the data directory (Tom Lane)
This mistake could lead to pg_resetxlog not noticing that there is an active postmaster using the data directory.

Fix libpq's lo_import() and lo_export() functions to report file I/O errors properly (Tom Lane)

Fix ecpg's processing of nested structure pointer variables (Muhammad Usama)

Fix ecpg's ecpg_get_data function to handle arrays properly (Michael Meskes)

Make contrib/pageinspect's btree page inspection functions take buffer locks while examining pages (Tom Lane)

Fix pgxs support for building loadable modules on AIX (Tom Lane)
Building modules outside the original source tree didn't work on AIX.

Update time zone data files to tzdata release 2012j for DST law changes in Cuba, Israel, Jordan, Libya, Palestine, Western Samoa, and portions of Brazil.

E.24. Release 9.0.10


Release Date
2012-09-24
This release contains a variety of fixes from 9.0.9. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.24.1. Migration to Version 9.0.10


A dump/restore is not required for those running 9.0.X.
However, if you are upgrading from a version earlier than 9.0.6, see Section E.28, Release 9.0.6 .

E.24.2. Changes

Fix planner's assignment of executor parameters, and fix executor's rescan logic for CTE plan nodes (Tom Lane)
These errors could result in wrong answers from queries that scan the same WITH subquery multiple times.

Improve page-splitting decisions in GiST indexes (Alexander Korotkov, Robert Haas, Tom Lane)
1452

Notes de version

Multi-column GiST indexes might suffer unexpected bloat due to this error.

Fix cascading privilege revoke to stop if privileges are still held (Tom Lane)
If we revoke a grant option from some role X, but X still holds that option via a grant from someone else, we should not recursively revoke the corresponding privilege from role(s) Y that X had granted it to.

Improve error messages for Hot Standby misconfiguration errors (Gurjeet Singh)

Fix handling of SIGFPE when PL/Perl is in use (Andres Freund)


Perl resets the process's SIGFPE handler to SIG_IGN, which could result in crashes later on. Restore the normal Postgres signal handler after initializing PL/Perl.

Prevent PL/Perl from crashing if a recursive PL/Perl function is redefined while being executed (Tom Lane)

Work around possible misoptimization in PL/Perl (Tom Lane)


Some Linux distributions contain an incorrect version of pthread.h that results in incorrect compiled code in PL/Perl, leading to crashes if a PL/Perl function calls another one that throws an error.

Fix pg_upgrade's handling of line endings on Windows (Andrew Dunstan)


Previously, pg_upgrade might add or remove carriage returns in places such as function bodies.

On Windows, make pg_upgrade use backslash path separators in the scripts it emits (Andrew Dunstan)

Update time zone data files to tzdata release 2012f for DST law changes in Fiji

E.25. Release 9.0.9


Release Date
2012-08-17
This release contains a variety of fixes from 9.0.8. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.25.1. Migration to Version 9.0.9


A dump/restore is not required for those running 9.0.X.
However, if you are upgrading from a version earlier than 9.0.6, see Section E.28, Release 9.0.6 .

E.25.2. Changes

Prevent access to external files/URLs via XML entity references (Noah Misch, Tom Lane)
xml_parse() would attempt to fetch external files or URLs as needed to resolve DTD and entity references in an XML value, thus allowing unprivileged database users to attempt to fetch data with the privileges of the database server. While the external data wouldn't get returned directly to the user, portions of it could be exposed in error messages if the data didn't parse
as valid XML; and in any case the mere ability to check existence of a file might be useful to an attacker. (CVE-2012-3489)

Prevent access to external files/URLs via contrib/xml2's xslt_process() (Peter Eisentraut)


libxslt offers the ability to read and write both files and URLs through stylesheet commands, thus allowing unprivileged database users to both read and write data with the privileges of the database server. Disable that through proper use of libxslt's security options. (CVE-2012-3488)
Also, remove xslt_process()'s ability to fetch documents and stylesheets from external files/URLs. While this was a documented feature , it was long regarded as a bad idea. The fix for CVE-2012-3489 broke that capability, and rather than expend effort on trying to fix it, we're just going to summarily remove it.

Prevent too-early recycling of btree index pages (Noah Misch)


When we allowed read-only transactions to skip assigning XIDs, we introduced the possibility that a deleted btree page could
be recycled while a read-only transaction was still in flight to it. This would result in incorrect index search results. The probability of such an error occurring in the field seems very low because of the timing requirements, but nonetheless it should be
fixed.
1453

Notes de version

Fix crash-safety bug with newly-created-or-reset sequences (Tom Lane)


If ALTER SEQUENCE was executed on a freshly created or reset sequence, and then precisely one nextval() call was
made on it, and then the server crashed, WAL replay would restore the sequence to a state in which it appeared that no nextval() had been done, thus allowing the first sequence value to be returned again by the next nextval() call. In particular
this could manifest for serial columns, since creation of a serial column's sequence includes an ALTER SEQUENCE OWNED BY step.

Fix txid_current() to report the correct epoch when not in hot standby (Heikki Linnakangas)
This fixes a regression introduced in the previous minor release.

Fix bug in startup of Hot Standby when a master transaction has many subtransactions (Andres Freund)
This mistake led to failures reported as out-of-order XID insertion in KnownAssignedXids .

Ensure the backup_label file is fsync'd after pg_start_backup() (Dave Kerr)

Fix timeout handling in walsender processes (Tom Lane)


WAL sender background processes neglected to establish a SIGALRM handler, meaning they would wait forever in some corner cases where a timeout ought to happen.

Back-patch 9.1 improvement to compress the fsync request queue (Robert Haas)
This improves performance during checkpoints. The 9.1 change has now seen enough field testing to seem safe to back-patch.

Fix LISTEN/NOTIFY to cope better with I/O problems, such as out of disk space (Tom Lane)
After a write failure, all subsequent attempts to send more NOTIFY messages would fail with messages like Could not read
from file "pg_notify/nnnn" at offset nnnnn: Success .

Only allow autovacuum to be auto-canceled by a directly blocked process (Tom Lane)


The original coding could allow inconsistent behavior in some cases; in particular, an autovacuum could get canceled after less
than deadlock_timeout grace period.

Improve logging of autovacuum cancels (Robert Haas)

Fix log collector so that log_truncate_on_rotation works during the very first log rotation after server start (Tom
Lane)

Fix WITH attached to a nested set operation (UNION/INTERSECT/EXCEPT) (Tom Lane)

Ensure that a whole-row reference to a subquery doesn't include any extra GROUP BY or ORDER BY columns (Tom Lane)

Disallow copying whole-row references in CHECK constraints and index definitions during CREATE TABLE (Tom Lane)
This situation can arise in CREATE TABLE with LIKE or INHERITS. The copied whole-row variable was incorrectly labeled with the row type of the original table not the new one. Rejecting the case seems reasonable for LIKE, since the row types
might well diverge later. For INHERITS we should ideally allow it, with an implicit coercion to the parent table's row type;
but that will require more work than seems safe to back-patch.

Fix memory leak in ARRAY(SELECT ...) subqueries (Heikki Linnakangas, Tom Lane)

Fix extraction of common prefixes from regular expressions (Tom Lane)


The code could get confused by quantified parenthesized subexpressions, such as ^(foo)?bar. This would lead to incorrect
index optimization of searches for such patterns.

Fix bugs with parsing signed hh:mm and hh:mm:ss fields in interval constants (Amit Kapila, Tom Lane)

Use Postgres' encoding conversion functions, not Python's, when converting a Python Unicode string to the server encoding in
PL/Python (Jan Urbanski)
This avoids some corner-case problems, notably that Python doesn't support all the encodings Postgres does. A notable functional change is that if the server encoding is SQL_ASCII, you will get the UTF-8 representation of the string; formerly, any
non-ASCII characters in the string would result in an error.

Fix mapping of PostgreSQL encodings to Python encodings in PL/Python (Jan Urbanski)

Report errors properly in contrib/xml2's xslt_process() (Tom Lane)

Update time zone data files to tzdata release 2012e for DST law changes in Morocco and Tokelau

1454

Notes de version

E.26. Release 9.0.8


Release Date
2012-06-04
This release contains a variety of fixes from 9.0.7. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.26.1. Migration to Version 9.0.8


A dump/restore is not required for those running 9.0.X.
However, if you are upgrading from a version earlier than 9.0.6, see Section E.28, Release 9.0.6 .

E.26.2. Changes

Fix incorrect password transformation in contrib/pgcrypto's DES crypt() function (Solar Designer)
If a password string contained the byte value 0x80, the remainder of the password was ignored, causing the password to be
much weaker than it appeared. With this fix, the rest of the string is properly included in the DES hash. Any stored password
values that are affected by this bug will thus no longer match, so the stored values may need to be updated. (CVE-2012-2143)

Ignore SECURITY DEFINER and SET attributes for a procedural language's call handler (Tom Lane)
Applying such attributes to a call handler could crash the server. (CVE-2012-2655)

Allow numeric timezone offsets in timestamp input to be up to 16 hours away from UTC (Tom Lane)
Some historical time zones have offsets larger than 15 hours, the previous limit. This could result in dumped data values being
rejected during reload.

Fix timestamp conversion to cope when the given time is exactly the last DST transition time for the current timezone (Tom
Lane)
This oversight has been there a long time, but was not noticed previously because most DST-using zones are presumed to have
an indefinite sequence of future DST transitions.

Fix text to name and char to name casts to perform string truncation correctly in multibyte encodings (Karl Schnaitter)

Fix memory copying bug in to_tsquery() (Heikki Linnakangas)

Ensure txid_current() reports the correct epoch when executed in hot standby (Simon Riggs)

Fix planner's handling of outer PlaceHolderVars within subqueries (Tom Lane)


This bug concerns sub-SELECTs that reference variables coming from the nullable side of an outer join of the surrounding
query. In 9.1, queries affected by this bug would fail with ERROR: Upper-level PlaceHolderVar found where not
expected . But in 9.0 and 8.4, you'd silently get possibly-wrong answers, since the value transmitted into the subquery
wouldn't go to null when it should.

Fix slow session startup when pg_attribute is very large (Tom Lane)
If pg_attribute exceeds one-fourth of shared_buffers, cache rebuilding code that is sometimes needed during session
start would trigger the synchronized-scan logic, causing it to take many times longer than normal. The problem was particularly acute if many new sessions were starting at once.

Ensure sequential scans check for query cancel reasonably often (Merlin Moncure)
A scan encountering many consecutive pages that contain no live tuples would not respond to interrupts meanwhile.

Ensure the Windows implementation of PGSemaphoreLock() clears ImmediateInterruptOK before returning (Tom
Lane)
This oversight meant that a query-cancel interrupt received later in the same query could be accepted at an unsafe time, with
unpredictable but not good consequences.

Show whole-row variables safely when printing views or rules (Abbas Butt, Tom Lane)
Corner cases involving ambiguous names (that is, the name could be either a table or column name of the query) were printed
in an ambiguous way, risking that the view or rule would be interpreted differently after dump and reload. Avoid the ambi1455

Notes de version

guous case by attaching a no-op cast.

Fix COPY FROM to properly handle null marker strings that correspond to invalid encoding (Tom Lane)
A null marker string such as E'\\0' should work, and did work in the past, but the case got broken in 8.4.

Ensure autovacuum worker processes perform stack depth checking properly (Heikki Linnakangas)
Previously, infinite recursion in a function invoked by auto-ANALYZE could crash worker processes.

Fix logging collector to not lose log coherency under high load (Andrew Dunstan)
The collector previously could fail to reassemble large messages if it got too busy.

Fix logging collector to ensure it will restart file rotation after receiving SIGHUP (Tom Lane)

Fix WAL replay logic for GIN indexes to not fail if the index was subsequently dropped (Tom Lane)

Fix memory leak in PL/pgSQL's RETURN NEXT command (Joe Conway)

Fix PL/pgSQL's GET DIAGNOSTICS command when the target is the function's first variable (Tom Lane)

Fix potential access off the end of memory in psql's expanded display (\x) mode (Peter Eisentraut)

Fix several performance problems in pg_dump when the database contains many objects (Jeff Janes, Tom Lane)
pg_dump could get very slow if the database contained many schemas, or if many objects are in dependency loops, or if there
are many owned sequences.

Fix pg_upgrade for the case that a database stored in a non-default tablespace contains a table in the cluster's default tablespace (Bruce Momjian)

In ecpg, fix rare memory leaks and possible overwrite of one byte after the sqlca_t structure (Peter Eisentraut)

Fix contrib/dblink's dblink_exec() to not leak temporary database connections upon error (Tom Lane)

Fix contrib/dblink to report the correct connection name in error messages (Kyotaro Horiguchi)

Fix contrib/vacuumlo to use multiple transactions when dropping many large objects (Tim Lewis, Robert Haas, Tom
Lane)
This change avoids exceeding max_locks_per_transaction when many objects need to be dropped. The behavior can
be adjusted with the new -l (limit) option.

Update time zone data files to tzdata release 2012c for DST law changes in Antarctica, Armenia, Chile, Cuba, Falkland Islands, Gaza, Haiti, Hebron, Morocco, Syria, and Tokelau Islands; also historical corrections for Canada.

E.27. Release 9.0.7


Release Date
2012-02-27
This release contains a variety of fixes from 9.0.6. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.27.1. Migration to Version 9.0.7


A dump/restore is not required for those running 9.0.X.
However, if you are upgrading from a version earlier than 9.0.6, see Section E.28, Release 9.0.6 .

E.27.2. Changes

Require execute permission on the trigger function for CREATE TRIGGER (Robert Haas)
This missing check could allow another user to execute a trigger function with forged input data, by installing it on a table he
owns. This is only of significance for trigger functions marked SECURITY DEFINER, since otherwise trigger functions run
as the table owner anyway. (CVE-2012-0866)

1456

Notes de version

Remove arbitrary limitation on length of common name in SSL certificates (Heikki Linnakangas)
Both libpq and the server truncated the common name extracted from an SSL certificate at 32 bytes. Normally this would
cause nothing worse than an unexpected verification failure, but there are some rather-implausible scenarios in which it might
allow one certificate holder to impersonate another. The victim would have to have a common name exactly 32 bytes long, and
the attacker would have to persuade a trusted CA to issue a certificate in which the common name has that string as a prefix.
Impersonating a server would also require some additional exploit to redirect client connections. (CVE-2012-0867)

Convert newlines to spaces in names written in pg_dump comments (Robert Haas)


pg_dump was incautious about sanitizing object names that are emitted within SQL comments in its output script. A name
containing a newline would at least render the script syntactically incorrect. Maliciously crafted object names could present a
SQL injection risk when the script is reloaded. (CVE-2012-0868)

Fix btree index corruption from insertions concurrent with vacuuming (Tom Lane)
An index page split caused by an insertion could sometimes cause a concurrently-running VACUUM to miss removing index
entries that it should remove. After the corresponding table rows are removed, the dangling index entries would cause errors
(such as could not read block N in file ... ) or worse, silently wrong query results after unrelated rows are re-inserted at the
now-free table locations. This bug has been present since release 8.2, but occurs so infrequently that it was not diagnosed until
now. If you have reason to suspect that it has happened in your database, reindexing the affected index will fix things.

Fix transient zeroing of shared buffers during WAL replay (Tom Lane)
The replay logic would sometimes zero and refill a shared buffer, so that the contents were transiently invalid. In hot standby
mode this can result in a query that's executing in parallel seeing garbage data. Various symptoms could result from that, but
the most common one seems to be invalid memory alloc request size .

Fix postmaster to attempt restart after a hot-standby crash (Tom Lane)


A logic error caused the postmaster to terminate, rather than attempt to restart the cluster, if any backend process crashed while
operating in hot standby mode.

Fix CLUSTER/VACUUM FULL handling of toast values owned by recently-updated rows (Tom Lane)
This oversight could lead to duplicate key value violates unique constraint errors being reported against the toast table's index during one of these commands.

Update per-column permissions, not only per-table permissions, when changing table owner (Tom Lane)
Failure to do this meant that any previously granted column permissions were still shown as having been granted by the old
owner. This meant that neither the new owner nor a superuser could revoke the now-untraceable-to-table-owner permissions.

Support foreign data wrappers and foreign servers in REASSIGN OWNED (Alvaro Herrera)
This command failed with unexpected classid errors if it needed to change the ownership of any such objects.

Allow non-existent values for some settings in ALTER USER/DATABASE SET (Heikki Linnakangas)
Allow default_text_search_config, default_tablespace, and temp_tablespaces to be set to names that
are not known. This is because they might be known in another database where the setting is intended to be used, or for the tablespace cases because the tablespace might not be created yet. The same issue was previously recognized for
search_path, and these settings now act like that one.

Avoid crashing when we have problems deleting table files post-commit (Tom Lane)
Dropping a table should lead to deleting the underlying disk files only after the transaction commits. In event of failure then
(for instance, because of wrong file permissions) the code is supposed to just emit a warning message and go on, since it's too
late to abort the transaction. This logic got broken as of release 8.4, causing such situations to result in a PANIC and an unrestartable database.

Recover from errors occurring during WAL replay of DROP TABLESPACE (Tom Lane)
Replay will attempt to remove the tablespace's directories, but there are various reasons why this might fail (for example, incorrect ownership or permissions on those directories). Formerly the replay code would panic, rendering the database unrestartable without manual intervention. It seems better to log the problem and continue, since the only consequence of failure to remove the directories is some wasted disk space.

Fix race condition in logging AccessExclusiveLocks for hot standby (Simon Riggs)
Sometimes a lock would be logged as being held by transaction zero . This is at least known to produce assertion failures
on slave servers, and might be the cause of more serious problems.
1457

Notes de version

Track the OID counter correctly during WAL replay, even when it wraps around (Tom Lane)
Previously the OID counter would remain stuck at a high value until the system exited replay mode. The practical consequences of that are usually nil, but there are scenarios wherein a standby server that's been promoted to master might take a
long time to advance the OID counter to a reasonable value once values are needed.

Prevent emitting misleading consistent recovery state reached log message at the beginning of crash recovery (Heikki Linnakangas)

Fix initial value of pg_stat_replication.replay_location (Fujii Masao)


Previously, the value shown would be wrong until at least one WAL record had been replayed.

Fix regular expression back-references with * attached (Tom Lane)


Rather than enforcing an exact string match, the code would effectively accept any string that satisfies the pattern subexpression referenced by the back-reference symbol.
A similar problem still afflicts back-references that are embedded in a larger quantified expression, rather than being the immediate subject of the quantifier. This will be addressed in a future PostgreSQL release.

Fix recently-introduced memory leak in processing of inet/cidr values (Heikki Linnakangas)


A patch in the December 2011 releases of PostgreSQL caused memory leakage in these operations, which could be significant in scenarios such as building a btree index on such a column.

Fix dangling pointer after CREATE TABLE AS/SELECT INTO in a SQL-language function (Tom Lane)
In most cases this only led to an assertion failure in assert-enabled builds, but worse consequences seem possible.

Avoid double close of file handle in syslogger on Windows (MauMau)


Ordinarily this error was invisible, but it would cause an exception when running on a debug version of Windows.

Fix I/O-conversion-related memory leaks in plpgsql (Andres Freund, Jan Urbanski, Tom Lane)
Certain operations would leak memory until the end of the current function.

Improve pg_dump's handling of alled table columns (Tom Lane)


pg_dump mishandled situations where a child column has a different default expression than its parent column. If the default is
textually identical to the parent's default, but not actually the same (for instance, because of schema search path differences) it
would not be recognized as different, so that after dump and restore the child would be allowed to all the parent's default.
Child columns that are NOT NULL where their parent is not could also be restored subtly incorrectly.

Fix pg_restore's direct-to-database mode for INSERT-style table data (Tom Lane)
Direct-to-database restores from archive files made with --inserts or --column-inserts options fail when using
pg_restore from a release dated September or December 2011, as a result of an oversight in a fix for another problem. The archive file itself is not at fault, and text-mode output is okay.

Allow pg_upgrade to process tables containing regclass columns (Bruce Momjian)


Since pg_upgrade now takes care to preserve pg_class OIDs, there was no longer any reason for this restriction.

Make libpq ignore ENOTDIR errors when looking for an SSL client certificate file (Magnus Hagander)
This allows SSL connections to be established, though without a certificate, even when the user's home directory is set to something like /dev/null.

Fix some more field alignment issues in ecpg's SQLDA area (Zoltan Boszormenyi)

Allow AT option in ecpg DEALLOCATE statements (Michael Meskes)


The infrastructure to support this has been there for awhile, but through an oversight there was still an error check rejecting the
case.

Do not use the variable name when defining a varchar structure in ecpg (Michael Meskes)

Fix contrib/auto_explain's JSON output mode to produce valid JSON (Andrew Dunstan)
The output used brackets at the top level, when it should have used braces.

Fix error in contrib/intarray's int[] & int[] operator (Guillaume Lelarge)


If the smallest integer the two input arrays have in common is 1, and there are smaller values in either array, then 1 would be
1458

Notes de version

incorrectly omitted from the result.

Fix error detection in contrib/pgcrypto's encrypt_iv() and decrypt_iv() (Marko Kreen)


These functions failed to report certain types of invalid-input errors, and would instead return random garbage values for incorrect input.

Fix one-byte buffer overrun in contrib/test_parser (Paul Guyot)


The code would try to read one more byte than it should, which would crash in corner cases. Since contrib/
test_parser is only example code, this is not a security issue in itself, but bad example code is still bad.

Use __sync_lock_test_and_set() for spinlocks on ARM, if available (Martin Pitt)


This function replaces our previous use of the SWPB instruction, which is deprecated and not available on ARMv6 and later.
Reports suggest that the old code doesn't fail in an obvious way on recent ARM boards, but simply doesn't interlock concurrent accesses, leading to bizarre failures in multiprocess operation.

Use -fexcess-precision=standard option when building with gcc versions that accept it (Andrew Dunstan)
This prevents assorted scenarios wherein recent versions of gcc will produce creative results.

Allow use of threaded Python on FreeBSD (Chris Rees)


Our configure script previously believed that this combination wouldn't work; but FreeBSD fixed the problem, so remove that
error check.

E.28. Release 9.0.6


Release Date
2011-12-05
This release contains a variety of fixes from 9.0.5. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.28.1. Migration to Version 9.0.6


A dump/restore is not required for those running 9.0.X.
However,
a
longstanding
error
was
discovered
in
the
definition
of
the
information_schema.referential_constraints view. If you rely on correct results from that view, you should replace its definition as explained in the first changelog item below.
Also, if you are upgrading from a version earlier than 9.0.4, see Section E.30, Release 9.0.4 .

E.28.2. Changes

Fix bugs in information_schema.referential_constraints view (Tom Lane)


This view was being insufficiently careful about matching the foreign-key constraint to the depended-on primary or unique
key constraint. That could result in failure to show a foreign key constraint at all, or showing it multiple times, or claiming that
it depends on a different constraint than the one it really does.
Since the view definition is installed by initdb, merely upgrading will not fix the problem. If you need to fix this in an existing
installation, you can (as a superuser) drop the information_schema schema then re-create it by sourcing SHAREDIR/
information_schema.sql. (Run pg_config --sharedir if you're uncertain where SHAREDIR is.) This must be
repeated in each database to be fixed.

Fix possible crash during UPDATE or DELETE that joins to the output of a scalar-returning function (Tom Lane)
A crash could only occur if the target row had been concurrently updated, so this problem surfaced only intermittently.

Fix incorrect replay of WAL records for GIN index updates (Tom Lane)
This could result in transiently failing to find index entries after a crash, or on a hot-standby server. The problem would be repaired by the next VACUUM of the index, however.

Fix TOAST-related data corruption during CREATE TABLE dest AS SELECT * FROM src or INSERT INTO
1459

Notes de version

dest SELECT * FROM src (Tom Lane)


If a table has been modified by ALTER TABLE ADD COLUMN, attempts to copy its data verbatim to another table could
produce corrupt results in certain corner cases. The problem can only manifest in this precise form in 8.4 and later, but we patched earlier versions as well in case there are other code paths that could trigger the same bug.

Fix possible failures during hot standby startup (Simon Riggs)

Start hot standby faster when initial snapshot is incomplete (Simon Riggs)

Fix race condition during toast table access from stale syscache entries (Tom Lane)
The typical symptom was transient errors like missing chunk number 0 for toast value NNNNN in pg_toast_2619 , where
the cited toast table would always belong to a system catalog.

Track dependencies of functions on items used in parameter default expressions (Tom Lane)
Previously, a referenced object could be dropped without having dropped or modified the function, leading to misbehavior
when the function was used. Note that merely installing this update will not fix the missing dependency entries; to do that,
you'd need to CREATE OR REPLACE each such function afterwards. If you have functions whose defaults depend on nonbuilt-in objects, doing so is recommended.

Allow inlining of set-returning SQL functions with multiple OUT parameters (Tom Lane)

Don't trust deferred-unique indexes for join removal (Tom Lane and Marti Raudsepp)
A deferred uniqueness constraint might not hold intra-transaction, so assuming that it does could give incorrect query results.

Make DatumGetInetP() unpack inet datums that have a 1-byte header, and add a new macro, DatumGetInetPP(),
that does not (Heikki Linnakangas)
This change affects no core code, but might prevent crashes in add-on code that expects DatumGetInetP() to produce an
unpacked datum as per usual convention.

Improve locale support in money type's input and output (Tom Lane)
Aside from not supporting all standard lc_monetary formatting options, the input and output functions were inconsistent,
meaning there were locales in which dumped money values could not be re-read.

Don't let transform_null_equals affect CASE foo WHEN NULL ... constructs (Heikki Linnakangas)
transform_null_equals is only supposed to affect foo = NULL expressions written directly by the user, not equality
checks generated internally by this form of CASE.

Change foreign-key trigger creation order to better support self-referential foreign keys (Tom Lane)
For a cascading foreign key that references its own table, a row update will fire both the ON UPDATE trigger and the CHECK
trigger as one event. The ON UPDATE trigger must execute first, else the CHECK will check a non-final state of the row and
possibly throw an inappropriate error. However, the firing order of these triggers is determined by their names, which generally sort in creation order since the triggers have auto-generated names following the convention
RI_ConstraintTrigger_NNNN . A proper fix would require modifying that convention, which we will do in 9.2, but it
seems risky to change it in existing releases. So this patch just changes the creation order of the triggers. Users encountering
this type of error should drop and re-create the foreign key constraint to get its triggers into the right order.

Avoid floating-point underflow while tracking buffer allocation rate (Greg Matthews)
While harmless in itself, on certain platforms this would result in annoying kernel log messages.

Preserve configuration file name and line number values when starting child processes under Windows (Tom Lane)
Formerly, these would not be displayed correctly in the pg_settings view.

Fix incorrect field alignment in ecpg's SQLDA area (Zoltan Boszormenyi)

Preserve blank lines within commands in psql's command history (Robert Haas)
The former behavior could cause problems if an empty line was removed from within a string literal, for example.

Fix pg_dump to dump user-defined casts between auto-generated types, such as table rowtypes (Tom Lane)

Assorted fixes for pg_upgrade (Bruce Momjian)


Handle exclusion constraints correctly, avoid failures on Windows, don't complain about mismatched toast table names in 8.4
databases.

1460

Notes de version

Use the preferred version of xsubpp to build PL/Perl, not necessarily the operating system's main copy (David Wheeler and
Alex Hunsaker)

Fix incorrect coding in contrib/dict_int and contrib/dict_xsyn (Tom Lane)


Some functions incorrectly assumed that memory returned by palloc() is guaranteed zeroed.

Fix assorted errors in contrib/unaccent's configuration file parsing (Tom Lane)

Honor query cancel interrupts promptly in pgstatindex() (Robert Haas)

Fix incorrect quoting of log file name in Mac OS X start script (Sidar Lopez)

Ensure VPATH builds properly install all server header files (Peter Eisentraut)

Shorten file names reported in verbose error messages (Peter Eisentraut)


Regular builds have always reported just the name of the C file containing the error message call, but VPATH builds formerly
reported an absolute path name.

Fix interpretation of Windows timezone names for Central America (Tom Lane)
Map Central America Standard Time to CST6, not CST6CDT, because DST is generally not observed anywhere in Central
America.

Update time zone data files to tzdata release 2011n for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa;
also historical corrections for Alaska and British East Africa.

E.29. Release 9.0.5


Release Date
2011-09-26
This release contains a variety of fixes from 9.0.4. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.29.1. Migration to Version 9.0.5


A dump/restore is not required for those running 9.0.X.
However, if you are upgrading from a version earlier than 9.0.4, see Section E.30, Release 9.0.4 .

E.29.2. Changes

Fix catalog cache invalidation after a VACUUM FULL or CLUSTER on a system catalog (Tom Lane)
In some cases the relocation of a system catalog row to another place would not be recognized by concurrent server processes,
allowing catalog corruption to occur if they then tried to update that row. The worst-case outcome could be as bad as complete
loss of a table.

Fix incorrect order of operations during sinval reset processing, and ensure that TOAST OIDs are preserved in system catalogs
(Tom Lane)
These mistakes could lead to transient failures after a VACUUM FULL or CLUSTER on a system catalog.

Fix bugs in indexing of in-doubt HOT-updated tuples (Tom Lane)


These bugs could result in index corruption after reindexing a system catalog. They are not believed to affect user indexes.

Fix multiple bugs in GiST index page split processing (Heikki Linnakangas)
The probability of occurrence was low, but these could lead to index corruption.

Fix possible buffer overrun in tsvector_concat() (Tom Lane)


The function could underestimate the amount of memory needed for its result, leading to server crashes.

Fix crash in xml_recv when processing a standalone parameter (Tom Lane)

Make pg_options_to_table return NULL for an option with no value (Tom Lane)
1461

Notes de version

Previously such cases would result in a server crash.

Avoid possibly accessing off the end of memory in ANALYZE and in SJIS-2004 encoding conversion (Noah Misch)
This fixes some very-low-probability server crash scenarios.

Protect pg_stat_reset_shared() against NULL input (Magnus Hagander)

Fix possible failure when a recovery conflict deadlock is detected within a sub-transaction (Tom Lane)

Avoid spurious conflicts while recycling btree index pages during hot standby (Noah Misch, Simon Riggs)

Shut down WAL receiver if it's still running at end of recovery (Heikki Linnakangas)
The postmaster formerly panicked in this situation, but it's actually a legitimate case.

Fix race condition in relcache init file invalidation (Tom Lane)


There was a window wherein a new backend process could read a stale init file but miss the inval messages that would tell it
the data is stale. The result would be bizarre failures in catalog accesses, typically could not read block 0 in file ... later during startup.

Fix memory leak at end of a GiST index scan (Tom Lane)


Commands that perform many separate GiST index scans, such as verification of a new GiST-based exclusion constraint on a
table already containing many rows, could transiently require large amounts of memory due to this leak.

Fix memory leak when encoding conversion has to be done on incoming command strings and LISTEN is active (Tom Lane)

Fix incorrect memory accounting (leading to possible memory bloat) in tuplestores supporting holdable cursors and plpgsql's
RETURN NEXT command (Tom Lane)

Fix trigger WHEN conditions when both BEFORE and AFTER triggers exist (Tom Lane)
Evaluation of WHEN conditions for AFTER ROW UPDATE triggers could crash if there had been a BEFORE ROW trigger fired
for the same update.

Fix performance problem when constructing a large, lossy bitmap (Tom Lane)

Fix join selectivity estimation for unique columns (Tom Lane)


This fixes an erroneous planner heuristic that could lead to poor estimates of the result size of a join.

Fix nested PlaceHolderVar expressions that appear only in sub-select target lists (Tom Lane)
This mistake could result in outputs of an outer join incorrectly appearing as NULL.

Allow the planner to assume that empty parent tables really are empty (Tom Lane)
Normally an empty table is assumed to have a certain minimum size for planning purposes; but this heuristic seems to do more
harm than good for the parent table of an allance hierarchy, which often is permanently empty.

Allow nested EXISTS queries to be optimized properly (Tom Lane)

Fix array- and path-creating functions to ensure padding bytes are zeroes (Tom Lane)
This avoids some situations where the planner will think that semantically-equal constants are not equal, resulting in poor optimization.

Fix EXPLAIN to handle gating Result nodes within inner-indexscan subplans (Tom Lane)
The usual symptom of this oversight was bogus varno errors.

Fix btree preprocessing of indexedcol IS NULL conditions (Dean Rasheed)


Such a condition is unsatisfiable if combined with any other type of btree-indexable condition on the same index column. The
case was handled incorrectly in 9.0.0 and later, leading to query output where there should be none.

Work around gcc 4.6.0 bug that breaks WAL replay (Tom Lane)
This could lead to loss of committed transactions after a server crash.

Fix dump bug for VALUES in a view (Tom Lane)

Disallow SELECT FOR UPDATE/SHARE on sequences (Tom Lane)


This operation doesn't work as expected and can lead to failures.
1462

Notes de version

Fix VACUUM so that it always updates pg_class.reltuples/relpages (Tom Lane)


This fixes some scenarios where autovacuum could make increasingly poor decisions about when to vacuum tables.

Defend against integer overflow when computing size of a hash table (Tom Lane)

Fix cases where CLUSTER might attempt to access already-removed TOAST data (Tom Lane)

Fix premature timeout failures during initial authentication transaction (Tom Lane)

Fix portability bugs in use of credentials control messages for peer authentication (Tom Lane)

Fix SSPI login when multiple roundtrips are required (Ahmed Shinwari, Magnus Hagander)
The typical symptom of this problem was The function requested is not supported errors during SSPI login.

Fix failure when adding a new variable of a custom variable class to postgresql.conf (Tom Lane)

Throw an error if pg_hba.conf contains hostssl but SSL is disabled (Tom Lane)
This was concluded to be more user-friendly than the previous behavior of silently ignoring such lines.

Fix failure when DROP OWNED BY attempts to remove default privileges on sequences (Shigeru Hanada)

Fix typo in pg_srand48 seed initialization (Andres Freund)


This led to failure to use all bits of the provided seed. This function is not used on most platforms (only those without srandom), and the potential security exposure from a less-random-than-expected seed seems minimal in any case.

Avoid integer overflow when the sum of LIMIT and OFFSET values exceeds 2^63 (Heikki Linnakangas)

Add overflow checks to int4 and int8 versions of generate_series() (Robert Haas)

Fix trailing-zero removal in to_char() (Marti Raudsepp)


In a format with FM and no digit positions after the decimal point, zeroes to the left of the decimal point could be removed incorrectly.

Fix pg_size_pretty() to avoid overflow for inputs close to 2^63 (Tom Lane)

Weaken plpgsql's check for typmod matching in record values (Tom Lane)
An overly enthusiastic check could lead to discarding length modifiers that should have been kept.

Correctly handle quotes in locale names during initdb (Heikki Linnakangas)


The case can arise with some Windows locales, such as People's Republic of China .

In pg_upgrade, avoid dumping orphaned temporary tables (Bruce Momjian)


This prevents situations wherein table OID assignments could get out of sync between old and new installations.

Fix pg_upgrade to preserve toast tables' relfrozenxids during an upgrade from 8.3 (Bruce Momjian)
Failure to do this could lead to pg_clog files being removed too soon after the upgrade.

In pg_upgrade, fix the -l (log) option to work on Windows (Bruce Momjian)

In pg_ctl, support silent mode for service registrations on Windows (MauMau)

Fix psql's counting of script file line numbers during COPY from a different file (Tom Lane)

Fix pg_restore's direct-to-database mode for standard_conforming_strings (Tom Lane)


pg_restore could emit incorrect commands when restoring directly to a database server from an archive file that had been
made with standard_conforming_strings set to on.

Be more user-friendly about unsupported cases for parallel pg_restore (Tom Lane)
This change ensures that such cases are detected and reported before any restore actions have been taken.

Fix write-past-buffer-end and memory leak in libpq's LDAP service lookup code (Albe Laurenz)

In libpq, avoid failures when using nonblocking I/O and an SSL connection (Martin Pihlak, Tom Lane)

Improve libpq's handling of failures during connection startup (Tom Lane)


In particular, the response to a server report of fork() failure during SSL connection startup is now saner.

Improve libpq's error reporting for SSL failures (Tom Lane)


1463

Notes de version

Fix PQsetvalue() to avoid possible crash when adding a new tuple to a PGresult originally obtained from a server query
(Andrew Chernow)

Make ecpglib write double values with 15 digits precision (Akira Kurosawa)

In ecpglib, be sure LC_NUMERIC setting is restored after an error (Michael Meskes)

Apply upstream fix for blowfish signed-character bug (CVE-2011-2483) (Tom Lane)
contrib/pg_crypto's blowfish encryption code could give wrong results on platforms where char is signed (which is
most), leading to encrypted passwords being weaker than they should be.

Fix memory leak in contrib/seg (Heikki Linnakangas)

Fix pgstatindex() to give consistent results for empty indexes (Tom Lane)

Allow building with perl 5.14 (Alex Hunsaker)

Fix assorted issues with build and install file paths containing spaces (Tom Lane)

Update time zone data files to tzdata release 2011i for DST law changes in Canada, Egypt, Russia, Samoa, and South Sudan.

E.30. Release 9.0.4


Release Date
2011-04-18
This release contains a variety of fixes from 9.0.3. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.30.1. Migration to Version 9.0.4


A dump/restore is not required for those running 9.0.X.
However, if your installation was upgraded from a previous major release by running pg_upgrade, you should take action to
prevent possible data loss due to a now-fixed bug in pg_upgrade. The recommended solution is to run VACUUM FREEZE on all
TOAST tables. More information is available at http://wiki.postgresql.org/wiki/20110408pg_upgrade_fix.

E.30.2. Changes

Fix pg_upgrade's handling of TOAST tables (Bruce Momjian)


The pg_class.relfrozenxid value for TOAST tables was not correctly copied into the new installation during pg_upgrade.
This could later result in pg_clog files being discarded while they were still needed to validate tuples in the TOAST tables,
leading to could not access status of transaction failures.
This error poses a significant risk of data loss for installations that have been upgraded with pg_upgrade. This patch corrects
the problem for future uses of pg_upgrade, but does not in itself cure the issue in installations that have been processed with a
buggy version of pg_upgrade.

Suppress incorrect PD_ALL_VISIBLE flag was incorrectly set warning (Heikki Linnakangas)
VACUUM would sometimes issue this warning in cases that are actually valid.

Use better SQLSTATE error codes for hot standby conflict cases (Tatsuo Ishii and Simon Riggs)
All retryable conflict errors now have an error code that indicates that a retry is possible. Also, session closure due to the database being dropped on the master is now reported as ERRCODE_DATABASE_DROPPED, rather than ERRCODE_ADMIN_SHUTDOWN, so that connection poolers can handle the situation correctly.

Prevent intermittent hang in interactions of startup process with bgwriter process (Simon Riggs)
This affected recovery in non-hot-standby cases.

Disallow including a composite type in itself (Tom Lane)


This prevents scenarios wherein the server could recurse infinitely while processing the composite type. While there are some
possible uses for such a structure, they don't seem compelling enough to justify the effort required to make sure it always
works safely.
1464

Notes de version

Avoid potential deadlock during catalog cache initialization (Nikhil Sontakke)


In some cases the cache loading code would acquire share lock on a system index before locking the index's catalog. This
could deadlock against processes trying to acquire exclusive locks in the other, more standard order.

Fix dangling-pointer problem in BEFORE ROW UPDATE trigger handling when there was a concurrent update to the target
tuple (Tom Lane)
This bug has been observed to result in intermittent cannot extract system attribute from virtual tuple failures while trying
to do UPDATE RETURNING ctid. There is a very small probability of more serious errors, such as generating incorrect index entries for the updated tuple.

Disallow DROP TABLE when there are pending deferred trigger events for the table (Tom Lane)
Formerly the DROP would go through, leading to could not open relation with OID nnn errors when the triggers were
eventually fired.

Allow replication as a user name in pg_hba.conf (Andrew Dunstan)


replication is special in the database name column, but it was mistakenly also treated as special in the user name column.

Prevent crash triggered by constant-false WHERE conditions during GEQO optimization (Tom Lane)

Improve planner's handling of semi-join and anti-join cases (Tom Lane)

Fix handling of SELECT FOR UPDATE in a sub-SELECT (Tom Lane)


This bug typically led to cannot extract system attribute from virtual tuple errors.

Fix selectivity estimation for text search to account for NULLs (Jesper Krogh)

Fix get_actual_variable_range() to support hypothetical indexes injected by an index adviser plugin (Gurjeet Singh)

Fix PL/Python memory leak involving array slices (Daniel Popowich)

Allow libpq's SSL initialization to succeed when user's home directory is unavailable (Tom Lane)
If the SSL mode is such that a root certificate file is not required, there is no need to fail. This change restores the behavior to
what it was in pre-9.0 releases.

Fix libpq to return a useful error message for errors detected in conninfo_array_parse (Joseph Adams)
A typo caused the library to return NULL, rather than the PGconn structure containing the error message, to the application.

Fix ecpg preprocessor's handling of float constants (Heikki Linnakangas)

Fix parallel pg_restore to handle comments on POST_DATA items correctly (Arnd Hannemann)

Fix pg_restore to cope with long lines (over 1KB) in TOC files (Tom Lane)

Put in more safeguards against crashing due to division-by-zero with overly enthusiastic compiler optimization (Aurelien Jarno)

Support use of dlopen() in FreeBSD and OpenBSD on MIPS (Tom Lane)


There was a hard-wired assumption that this system function was not available on MIPS hardware on these systems. Use a
compile-time test instead, since more recent versions have it.

Fix compilation failures on HP-UX (Heikki Linnakangas)

Avoid crash when trying to write to the Windows console very early in process startup (Rushabh Lathia)

Support building with MinGW 64 bit compiler for Windows (Andrew Dunstan)

Fix version-incompatibility problem with libintl on Windows (Hiroshi Inoue)

Fix usage of xcopy in Windows build scripts to work correctly under Windows 7 (Andrew Dunstan)
This affects the build scripts only, not installation or usage.

Fix path separator used by pg_regress on Cygwin (Andrew Dunstan)

Update time zone data files to tzdata release 2011f for DST law changes in Chile, Cuba, Falkland Islands, Morocco, Samoa,
and Turkey; also historical corrections for South Australia, Alaska, and Hawaii.

1465

Notes de version

E.31. Release 9.0.3


Release Date
2011-01-31
This release contains a variety of fixes from 9.0.2. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.31.1. Migration to Version 9.0.3


A dump/restore is not required for those running 9.0.X.

E.31.2. Changes

Before exiting walreceiver, ensure all the received WAL is fsync'd to disk (Heikki Linnakangas)
Otherwise the standby server could replay some un-synced WAL, conceivably leading to data corruption if the system crashes
just at that point.

Avoid excess fsync activity in walreceiver (Heikki Linnakangas)

Make ALTER TABLE revalidate uniqueness and exclusion constraints when needed (Noah Misch)
This was broken in 9.0 by a change that was intended to suppress revalidation during VACUUM FULL and CLUSTER, but
unintentionally affected ALTER TABLE as well.

Fix EvalPlanQual for UPDATE of an allance tree in which the tables are not all alike (Tom Lane)
Any variation in the table row types (including dropped columns present in only some child tables) would confuse the EvalPlanQual code, leading to misbehavior or even crashes. Since EvalPlanQual is only executed during concurrent updates to the
same row, the problem was only seen intermittently.

Avoid failures when EXPLAIN tries to display a simple-form CASE expression (Tom Lane)
If the CASE's test expression was a constant, the planner could simplify the CASE into a form that confused the expression-display code, resulting in unexpected CASE WHEN clause errors.

Fix assignment to an array slice that is before the existing range of subscripts (Tom Lane)
If there was a gap between the newly added subscripts and the first pre-existing subscript, the code miscalculated how many
entries needed to be copied from the old array's null bitmap, potentially leading to data corruption or crash.

Avoid unexpected conversion overflow in planner for very distant date values (Tom Lane)
The date type supports a wider range of dates than can be represented by the timestamp types, but the planner assumed it could
always convert a date to timestamp with impunity.

Fix PL/Python crash when an array contains null entries (Alex Hunsaker)

Remove ecpg's fixed length limit for constants defining an array dimension (Michael Meskes)

Fix erroneous parsing of tsquery values containing ... & !(subexpression) | ... (Tom Lane)
Queries containing this combination of operators were not executed correctly. The same error existed in contrib/intarray's query_int type and contrib/ltree's ltxtquery type.

Fix buffer overrun in contrib/intarray's input function for the query_int type (Apple)
This bug is a security risk since the function's return address could be overwritten. Thanks to Apple Inc's security team for reporting this issue and supplying the fix. (CVE-2010-4015)

Fix bug in contrib/seg's GiST picksplit algorithm (Alexander Korotkov)


This could result in considerable inefficiency, though not actually incorrect answers, in a GiST index on a seg column. If you
have such an index, consider REINDEXing it after installing this update. (This is identical to the bug that was fixed in
contrib/cube in the previous update.)

E.32. Release 9.0.2


1466

Notes de version

Release Date
2010-12-16
This release contains a variety of fixes from 9.0.1. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.32.1. Migration to Version 9.0.2


A dump/restore is not required for those running 9.0.X.

E.32.2. Changes

Force the default wal_sync_method to be fdatasync on Linux (Tom Lane, Marti Raudsepp)
The default on Linux has actually been fdatasync for many years, but recent kernel changes caused PostgreSQL to
choose open_datasync instead. This choice did not result in any performance improvement, and caused outright failures
on certain filesystems, notably ext4 with the data=journal mount option.

Fix too many KnownAssignedXids error during Hot Standby replay (Heikki Linnakangas)

Fix race condition in lock acquisition during Hot Standby (Simon Riggs)

Avoid unnecessary conflicts during Hot Standby (Simon Riggs)


This fixes some cases where replay was considered to conflict with standby queries (causing delay of replay or possibly cancellation of the queries), but there was no real conflict.

Fix assorted bugs in WAL replay logic for GIN indexes (Tom Lane)
This could result in bad buffer id: 0 failures or corruption of index contents during replication.

Fix recovery from base backup when the starting checkpoint WAL record is not in the same WAL segment as its redo point
(Jeff Davis)

Fix corner-case bug when streaming replication is enabled immediately after creating the master database cluster (Heikki Linnakangas)

Fix persistent slowdown of autovacuum workers when multiple workers remain active for a long time (Tom Lane)
The effective vacuum_cost_limit for an autovacuum worker could drop to nearly zero if it processed enough tables, causing it to run extremely slowly.

Fix long-term memory leak in autovacuum launcher (Alvaro Herrera)

Avoid failure when trying to report an impending transaction wraparound condition from outside a transaction (Tom Lane)
This oversight prevented recovery after transaction wraparound got too close, because database startup processing would fail.

Add support for detecting register-stack overrun on IA64 (Tom Lane)


The IA64 architecture has two hardware stacks. Full prevention of stack-overrun failures requires checking both.

Add a check for stack overflow in copyObject() (Tom Lane)


Certain code paths could crash due to stack overflow given a sufficiently complex query.

Fix detection of page splits in temporary GiST indexes (Heikki Linnakangas)


It is possible to have a concurrent page split in a temporary index, if for example there is an open cursor scanning the index
when an insertion is done. GiST failed to detect this case and hence could deliver wrong results when execution of the cursor
continued.

Fix error checking during early connection processing (Tom Lane)


The check for too many child processes was skipped in some cases, possibly leading to postmaster crash when attempting to
add the new child process to fixed-size arrays.

Improve efficiency of window functions (Tom Lane)


Certain cases where a large number of tuples needed to be read in advance, but work_mem was large enough to allow them all
to be held in memory, were unexpectedly slow. percent_rank(), cume_dist() and ntile() in particular were subject to this problem.
1467

Notes de version

Avoid memory leakage while ANALYZE'ing complex index expressions (Tom Lane)

Ensure an index that uses a whole-row Var still depends on its table (Tom Lane)
An index declared like create index i on t (foo(t.*)) would not automatically get dropped when its table was
dropped.

Add missing support in DROP OWNED BY for removing foreign data wrapper/server privileges belonging to a user (Heikki
Linnakangas)

Do not inline a SQL function with multiple OUT parameters (Tom Lane)
This avoids a possible crash due to loss of information about the expected result rowtype.

Fix crash when inline-ing a set-returning function whose argument list contains a reference to an inline-able user function
(Tom Lane)

Behave correctly if ORDER BY, LIMIT, FOR UPDATE, or WITH is attached to the VALUES part of INSERT ... VALUES
(Tom Lane)

Make the OFF keyword unreserved (Heikki Linnakangas)


This prevents problems with using off as a variable name in PL/pgSQL. That worked before 9.0, but was now broken because PL/pgSQL now treats all core reserved words as reserved.

Fix constant-folding of COALESCE() expressions (Tom Lane)


The planner would sometimes attempt to evaluate sub-expressions that in fact could never be reached, possibly leading to
unexpected errors.

Fix could not find pathkey item to sort planner failure with comparison of whole-row Vars (Tom Lane)

Fix postmaster crash when connection acceptance (accept() or one of the calls made immediately after it) fails, and the
postmaster was compiled with GSSAPI support (Alexander Chernikov)

Retry after receiving an invalid response packet from a RADIUS authentication server (Magnus Hagander)
This fixes a low-risk potential denial of service condition.

Fix missed unlink of temporary files when log_temp_files is active (Tom Lane)
If an error occurred while attempting to emit the log message, the unlink was not done, resulting in accumulation of temp files.

Add print functionality for InhRelation nodes (Tom Lane)


This avoids a failure when debug_print_parse is enabled and certain types of query are executed.

Fix incorrect calculation of distance from a point to a horizontal line segment (Tom Lane)
This bug affected several different geometric distance-measurement operators.

Fix incorrect calculation of transaction status in ecpg (Itagaki Takahiro)

Fix errors in psql's Unicode-escape support (Tom Lane)

Speed up parallel pg_restore when the archive contains many large objects (blobs) (Tom Lane)

Fix PL/pgSQL's handling of simple expressions to not fail in recursion or error-recovery cases (Tom Lane)

Fix PL/pgSQL's error reporting for no-such-column cases (Tom Lane)


As of 9.0, it would sometimes report missing FROM-clause entry for table foo when record foo has no field bar would
be more appropriate.

Fix PL/Python to honor typmod (i.e., length or precision restrictions) when assigning to tuple fields (Tom Lane)
This fixes a regression from 8.4.

Fix PL/Python's handling of set-returning functions (Jan Urbanski)


Attempts to call SPI functions within the iterator generating a set result would fail.

Fix bug in contrib/cube's GiST picksplit algorithm (Alexander Korotkov)


This could result in considerable inefficiency, though not actually incorrect answers, in a GiST index on a cube column. If you
have such an index, consider REINDEXing it after installing this update.

Don't emit identifier will be truncated notices in contrib/dblink except when creating new connections (Itagaki Ta1468

Notes de version

kahiro)

Fix potential coredump on missing public key in contrib/pgcrypto (Marti Raudsepp)

Fix buffer overrun in contrib/pg_upgrade (Hernan Gonzalez)

Fix memory leak in contrib/xml2's XPath query functions (Tom Lane)

Update time zone data files to tzdata release 2010o for DST law changes in Fiji and Samoa; also historical corrections for
Hong Kong.

E.33. Release 9.0.1


Release Date
2010-10-04
This release contains a variety of fixes from 9.0.0. For information about new features in the 9.0 major release, see Section E.34,
Release 9.0 .

E.33.1. Migration to Version 9.0.1


A dump/restore is not required for those running 9.0.X.

E.33.2. Changes

Use a separate interpreter for each calling SQL userid in PL/Perl and PL/Tcl (Tom Lane)
This change prevents security problems that can be caused by subverting Perl or Tcl code that will be executed later in the
same session under another SQL user identity (for example, within a SECURITY DEFINER function). Most scripting languages offer numerous ways that that might be done, such as redefining standard functions or operators called by the target
function. Without this change, any SQL user with Perl or Tcl language usage rights can do essentially anything with the SQL
privileges of the target function's owner.
The cost of this change is that intentional communication among Perl and Tcl functions becomes more difficult. To provide an
escape hatch, PL/PerlU and PL/TclU functions continue to use only one interpreter per session. This is not considered a security issue since all such functions execute at the trust level of a database superuser already.
It is likely that third-party procedural languages that claim to offer trusted execution have similar security issues. We advise
contacting the authors of any PL you are depending on for security-critical purposes.
Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433).

Improve pg_get_expr() security fix so that the function can still be used on the output of a sub-select (Tom Lane)

Fix incorrect placement of placeholder evaluation (Tom Lane)


This bug could result in query outputs being non-null when they should be null, in cases where the inner side of an outer join
is a sub-select with non-strict expressions in its output list.

Fix join removal's handling of placeholder expressions (Tom Lane)

Fix possible duplicate scans of UNION ALL member relations (Tom Lane)

Prevent infinite loop in ProcessIncomingNotify() after unlistening (Jeff Davis)

Prevent show_session_authorization() from crashing within autovacuum processes (Tom Lane)

Re-allow input of Julian dates prior to 0001-01-01 AD (Tom Lane)


Input such as 'J100000'::date worked before 8.4, but was unintentionally broken by added error-checking.

Make psql recognize DISCARD ALL as a command that should not be encased in a transaction block in autocommit-off
mode (Itagaki Takahiro)

Update build infrastructure and documentation to reflect the source code repository's move from CVS to Git (Magnus Hagander and others)

1469

Notes de version

E.34. Release 9.0


Release Date
2010-09-20

E.34.1. Overview
This release of PostgreSQL adds features that have been requested for years, such as easy-to-use replication, a mass permissionchanging facility, and anonymous code blocks. While past major releases have been conservative in their scope, this release shows
a bold new desire to provide facilities that new and existing users of PostgreSQL will embrace. This has all been done with few
incompatibilities. Major enhancements include:

Built-in replication based on log shipping. This advance consists of two features: Streaming Replication, allowing continuous
archive (WAL) files to be streamed over a network connection to a standby server, and Hot Standby, allowing continuous archive standby servers to execute read-only queries. The net effect is to support a single master with multiple read-only slave
servers.

Easier database object permissions management. GRANT/REVOKE IN SCHEMA supports mass permissions changes on
existing objects, while ALTER DEFAULT PRIVILEGES allows control of privileges for objects created in the future.
Large objects (BLOBs) now support permissions management as well.

Broadly enhanced stored procedure support. The DO statement supports ad-hoc or anonymous code blocks. Functions can
now be called using named parameters. PL/pgSQL is now installed by default, and PL/Perl and PL/Python have been enhanced in several ways, including support for Python3.

Full support for 64-bit Windows.

More advanced reporting queries, including additional windowing options (PRECEDING and FOLLOWING) and the ability to
control the order in which values are fed to aggregate functions.

New trigger features, including SQL-standard-compliant per-column triggers and conditional trigger execution.

Deferrable unique constraints. Mass updates to unique keys are now possible without trickery.

Exclusion constraints. These provide a generalized version of unique constraints, allowing enforcement of complex conditions.

New and enhanced security features, including RADIUS authentication, LDAP authentication improvements, and a new
contrib module passwordcheck for testing password strength.

New high-performance implementation of the LISTEN/NOTIFY feature. Pending events are now stored in a memory-based
queue rather than a table. Also, a payload string can be sent with each event, rather than transmitting just an event name as
before.

New implementation of VACUUM FULL. This command now rewrites the entire table and indexes, rather than moving individual rows to compact space. It is substantially faster in most cases, and no longer results in index bloat.

New contrib module pg_upgrade to support in-place upgrades from 8.3 or 8.4 to 9.0.

Multiple performance enhancements for specific types of queries, including elimination of unnecessary joins. This helps optimize some automatically-generated queries, such as those produced by object-relational mappers (ORMs).

EXPLAIN enhancements. The output is now available in JSON, XML, or YAML format, and includes buffer utilization and
other data not previously available.

hstore improvements, including new functions and greater data capacity.

The above items are explained in more detail in the sections below.

E.34.2. Migration to Version 9.0


A dump/restore using pg_dump, or use of pg_upgrade, is required for those wishing to migrate data from any previous release.
Version 9.0 contains a number of changes that selectively break backwards compatibility in order to support new features and
code quality improvements. In particular, users who make extensive use of PL/pgSQL, Point-In-Time Recovery (PITR), or Warm
Standby should test their applications because of slight user-visible changes in those areas. Observe the following incompatibilities:

1470

Notes de version

E.34.2.1. Server Settings

Remove server parameter add_missing_from, which was defaulted to off for many years (Tom Lane)

Remove server parameter regex_flavor, which was defaulted to advanced for many years (Tom Lane)

archive_mode now only affects archive_command; a new setting, wal_level, affects the contents of the write-ahead
log (Heikki Linnakangas)

log_temp_files now uses default file size units of kilobytes (Robert Haas)

E.34.2.2. Queries

When querying a parent table, do not do any separate permission checks on child tables scanned as part of the query (Peter Eisentraut)
The SQL standard specifies this behavior, and it is also much more convenient in practice than the former behavior of checking permissions on each child as well as the parent.

E.34.2.3. Data Types

bytea output now appears in hex format by default (Peter Eisentraut)


The server parameter bytea_output can be used to select the traditional output format if needed for compatibility.

Array input now considers only plain ASCII whitespace characters to be potentially ignorable; it will never ignore non-ASCII
characters, even if they are whitespace according to some locales (Tom Lane)
This avoids some corner cases where array values could be interpreted differently depending on the server's locale settings.

Improve standards compliance of SIMILAR TO patterns and SQL-style substring() patterns (Tom Lane)
This includes treating ? and {...} as pattern metacharacters, while they were simple literal characters before; that corresponds to new features added in SQL:2008. Also, ^ and $ are now treated as simple literal characters; formerly they were treated as metacharacters, as if the pattern were following POSIX rather than SQL rules. Also, in SQL-standard substring(),
use of parentheses for nesting no longer interferes with capturing of a substring. Also, processing of bracket expressions
(character classes) is now more standards-compliant.

Reject negative length values in 3-parameter substring() for bit strings, per the SQL standard (Tom Lane)

Make date_trunc truncate rather than round when reducing precision of fractional seconds (Tom Lane)
The code always acted this way for integer-based dates/times. Now float-based dates/times behave similarly.

E.34.2.4. Object Renaming

Tighten enforcement of column name consistency during RENAME when a child table alls the same column from multiple
unrelated parents (KaiGai Kohei)

No longer automatically rename indexes and index columns when the underlying table columns are renamed (Tom Lane)
Administrators can still rename such indexes and columns manually. This change will require an update of the JDBC driver,
and possibly other drivers, so that unique indexes are correctly recognized after a rename.

CREATE OR REPLACE FUNCTION can no longer change the declared names of function parameters (Pavel Stehule)
In order to avoid creating ambiguity in named-parameter calls, it is no longer allowed to change the aliases for input parameters in the declaration of an existing function (although names can still be assigned to previously unnamed parameters). You
now have to DROP and recreate the function to do that.

E.34.2.5. PL/pgSQL

PL/pgSQL now throws an error if a variable name conflicts with a column name used in a query (Tom Lane)
The former behavior was to bind ambiguous names to PL/pgSQL variables in preference to query columns, which often resulted in surprising misbehavior. Throwing an error allows easy detection of ambiguous situations. Although it's recommended
that functions encountering this type of error be modified to remove the conflict, the old behavior can be restored if necessary
1471

Notes de version

via the configuration parameter plpgsql.variable_conflict, or via the per-function option


#variable_conflict.

PL/pgSQL no longer allows variable names that match certain SQL reserved words (Tom Lane)
This is a consequence of aligning the PL/pgSQL parser to match the core SQL parser more closely. If necessary, variable
names can be double-quoted to avoid this restriction.

PL/pgSQL now requires columns of composite results to match the expected type modifier as well as base type (Pavel Stehule,
Tom Lane)
For example, if a column of the result type is declared as NUMERIC(30,2), it is no longer acceptable to return a NUMERIC
of some other precision in that column. Previous versions neglected to check the type modifier and would thus allow result
rows that didn't actually conform to the declared restrictions.

PL/pgSQL now treats selection into composite fields more consistently (Tom Lane)
Formerly, a statement like SELECT ... INTO rec.fld FROM ... was treated as a scalar assignment even if the record field fld was of composite type. Now it is treated as a record assignment, the same as when the INTO target is a regular
variable of composite type. So the values to be assigned to the field's subfields should be written as separate columns of the
SELECT list, not as a ROW(...) construct as in previous versions.
If you need to do this in a way that will work in both 9.0 and previous releases, you can write something like rec.fld :=
ROW(...) FROM ....

Remove PL/pgSQL's RENAME declaration (Tom Lane)


Instead of RENAME, use ALIAS, which can now create an alias for any variable, not only dollar sign parameter names (such as
$1) as before.

E.34.2.6. Other Incompatibilities

Deprecate use of => as an operator name (Robert Haas)


Future versions of PostgreSQL will probably reject this operator name entirely, in order to support the SQL-standard notation for named function parameters. For the moment, it is still allowed, but a warning is emitted when such an operator is defined.

Remove support for platforms that don't have a working 64-bit integer data type (Tom Lane)
It is believed all still-supported platforms have working 64-bit integer data types.

E.34.3. Changes
Version 9.0 has an unprecedented number of new major features, and over 200 enhancements, improvements, new commands,
new functions, and other changes.

E.34.3.1. Server
E.34.3.1.1. Continuous Archiving and Streaming Replication

PostgreSQL's existing standby-server capability has been expanded both to support read-only queries on standby servers and to
greatly reduce the lag between master and standby servers. For many users, this will be a useful and low-administration form of
replication, either for high availability or for horizontal scalability.

Allow a standby server to accept read-only queries (Simon Riggs, Heikki Linnakangas)
This feature is called Hot Standby. There are new postgresql.conf and recovery.conf settings to control this feature, as well as extensive documentation.

Allow write-ahead log (WAL) data to be streamed to a standby server (Fujii Masao, Heikki Linnakangas)
This feature is called Streaming Replication. Previously WAL data could be sent to standby servers only in units of entire
WAL files (normally 16 megabytes each). Streaming Replication eliminates this inefficiency and allows updates on the master
to be propagated to standby servers with very little delay. There are new postgresql.conf and recovery.conf settings to control this feature, as well as extensive documentation.

Add pg_last_xlog_receive_location() and pg_last_xlog_replay_location(), which can be used to


1472

Notes de version

monitor standby server WAL activity (Simon Riggs, Fujii Masao, Heikki Linnakangas)
E.34.3.1.2. Performance

Allow per-tablespace values to be set for sequential and random page cost estimates (seq_page_cost/random_page_cost) via ALTER TABLESPACE ... SET/RESET (Robert Haas)

Improve performance and reliability of EvalPlanQual rechecks in join queries (Tom Lane)
UPDATE, DELETE, and SELECT FOR UPDATE/SHARE queries that involve joins will now behave much better when
encountering freshly-updated rows.

Improve performance of TRUNCATE when the table was created or truncated earlier in the same transaction (Tom Lane)

Improve performance of finding allance child tables (Tom Lane)

E.34.3.1.3. Optimizer

Remove unnecessary outer joins (Robert Haas)


Outer joins where the inner side is unique and not referenced above the join are unnecessary and are therefore now removed.
This will accelerate many automatically generated queries, such as those created by object-relational mappers (ORMs).

Allow IS NOT NULL restrictions to use indexes (Tom Lane)


This is particularly useful for finding MAX()/MIN() values in indexes that contain many null values.

Improve the optimizer's choices about when to use materialize nodes, and when to use sorting versus hashing for DISTINCT
(Tom Lane)

Improve the optimizer's equivalence detection for expressions involving boolean <> operators (Tom Lane)

E.34.3.1.4. GEQO

Use the same random seed every time GEQO plans a query (Andres Freund)
While the Genetic Query Optimizer (GEQO) still selects random plans, it now always selects the same random plans for identical queries, thus giving more consistent performance. You can modify geqo_seed to experiment with alternative plans.

Improve GEQO plan selection (Tom Lane)


This avoids the rare error failed to make a valid plan , and should also improve planning speed.

E.34.3.1.5. Optimizer Statistics

Improve ANALYZE to support allance-tree statistics (Tom Lane)


This is particularly useful for partitioned tables. However, autovacuum does not yet automatically re-analyze parent tables
when child tables change.

Improve autovacuum's detection of when re-analyze is necessary (Tom Lane)

Improve optimizer's estimation for greater/less-than comparisons (Tom Lane)


When looking up statistics for greater/less-than comparisons, if the comparison value is in the first or last histogram bucket,
use an index (if available) to fetch the current actual column minimum or maximum. This greatly improves the accuracy of estimates for comparison values near the ends of the data range, particularly if the range is constantly changing due to addition
of new data.

Allow setting of number-of-distinct-values statistics using ALTER TABLE (Robert Haas)


This allows users to override the estimated number or percentage of distinct values for a column. This statistic is normally
computed by ANALYZE, but the estimate can be poor, especially on tables with very large numbers of rows.

E.34.3.1.6. Authentication

Add support for RADIUS (Remote Authentication Dial In User Service) authentication (Magnus Hagander)

1473

Notes de version

Allow LDAP (Lightweight Directory Access Protocol) authentication to operate in search/bind mode (Robert Fleming,
Magnus Hagander)
This allows the user to be looked up first, then the system uses the DN (Distinguished Name) returned for that user.

Add samehost and samenet designations to pg_hba.conf (Stef Walter)


These match the server's IP address and subnet address respectively.

Pass trusted SSL root certificate names to the client so the client can return an appropriate client certificate (Craig Ringer)

E.34.3.1.7. Monitoring

Add the ability for clients to set an application name, which is displayed in pg_stat_activity (Dave Page)
This allows administrators to characterize database traffic and troubleshoot problems by source application.

Add a SQLSTATE option (%e) to log_line_prefix (Guillaume Smet)


This allows users to compile statistics on errors and messages by error code number.

Write to the Windows event log in UTF16 encoding (Itagaki Takahiro)


Now there is true multilingual support for PostgreSQL log messages on Windows.

E.34.3.1.8. Statistics Counters

Add pg_stat_reset_shared('bgwriter') to reset the cluster-wide shared statistics for the background writer (Greg
Smith)

Add pg_stat_reset_single_table_counters() and pg_stat_reset_single_function_counters()


to allow resetting the statistics counters for individual tables and functions (Magnus Hagander)

E.34.3.1.9. Server Settings

Allow setting of configuration parameters based on database/role combinations (Alvaro Herrera)


Previously only per-database and per-role settings were possible, not combinations. All role and database settings are now stored in the new pg_db_role_setting system catalog. A new psql command \drds shows these settings. The legacy system
views pg_roles, pg_shadow, and pg_user do not show combination settings, and therefore no longer completely represent the
configuration for a user or database.

Add server parameter bonjour, which controls whether a Bonjour-enabled server advertises itself via Bonjour (Tom
Lane)
The default is off, meaning it does not advertise. This allows packagers to distribute Bonjour-enabled builds without worrying
that individual users might not want the feature.

Add server parameter enable_material, which controls the use of materialize nodes in the optimizer (Robert Haas)
The default is on. When off, the optimizer will not add materialize nodes purely for performance reasons, though they will still
be used when necessary for correctness.

Change server parameter log_temp_files to use default file size units of kilobytes (Robert Haas)
Previously this setting was interpreted in bytes if no units were specified.

Log changes of parameter values when postgresql.conf is reloaded (Peter Eisentraut)


This lets administrators and security staff audit changes of database settings, and is also very convenient for checking the effects of postgresql.conf edits.

Properly enforce superuser permissions for custom server parameters (Tom Lane)
Non-superusers can no longer issue ALTER ROLE/DATABASE SET for parameters that are not currently known to the server. This allows the server to correctly check that superuser-only parameters are only set by superusers. Previously, the SET
would be allowed and then ignored at session start, making superuser-only custom parameters much less useful than they
should be.

E.34.3.2. Queries
1474

Notes de version

Perform SELECT FOR UPDATE/SHARE processing after applying LIMIT, so the number of rows returned is always predictable (Tom Lane)
Previously, changes made by concurrent transactions could cause a SELECT FOR UPDATE to unexpectedly return fewer
rows than specified by its LIMIT. FOR UPDATE in combination with ORDER BY can still produce surprising results, but that
can be corrected by placing FOR UPDATE in a subquery.

Allow mixing of traditional and SQL-standard LIMIT/OFFSET syntax (Tom Lane)

Extend the supported frame options in window functions (Hitoshi Harada)


Frames can now start with CURRENT ROW, and the ROWS n PRECEDING/FOLLOWING options are now supported.

Make SELECT INTO and CREATE TABLE AS return row counts to the client in their command tags (Boszormenyi Zoltan)
This can save an entire round-trip to the client, allowing result counts and pagination to be calculated without an additional
COUNT query.

E.34.3.2.1. Unicode Strings

Support Unicode surrogate pairs (dual 16-bit representation) in U& strings and identifiers (Peter Eisentraut)

Support Unicode escapes in E'...' strings (Marko Kreen)

E.34.3.3. Object Manipulation

Speed up CREATE DATABASE by deferring flushes to disk (Andres Freund, Greg Stark)

Allow comments on columns of tables, views, and composite types only, not other relation types such as indexes and TOAST
tables (Tom Lane)

Allow the creation of enumerated types containing no values (Bruce Momjian)

Let values of columns having storage type MAIN remain on the main heap page unless the row cannot fit on a page (Kevin
Grittner)
Previously MAIN values were forced out to TOAST tables until the row size was less than one-quarter of the page size.

E.34.3.3.1. ALTER TABLE

Implement IF EXISTS for ALTER TABLE DROP COLUMN and ALTER TABLE DROP CONSTRAINT (Andres Freund)

Allow ALTER TABLE commands that rewrite tables to skip WAL logging (Itagaki Takahiro)
Such operations either produce a new copy of the table or are rolled back, so WAL archiving can be skipped, unless running in
continuous archiving mode. This reduces I/O overhead and improves performance.

Fix failure of ALTER TABLE table ADD COLUMN col serial when done by non-owner of table (Tom Lane)

E.34.3.3.2. CREATE TABLE

Add support for copying COMMENTS and STORAGE settings in CREATE TABLE ... LIKE commands (Itagaki Takahiro)

Add a shortcut for copying all properties in CREATE TABLE ... LIKE commands (Itagaki Takahiro)

Add the SQL-standard CREATE TABLE ... OF type command (Peter Eisentraut)
This allows creation of a table that matches an existing composite type. Additional constraints and defaults can be specified in
the command.

E.34.3.3.3. Constraints

Add deferrable unique constraints (Dean Rasheed)


This allows mass updates, such as UPDATE tab SET col = col + 1, to work reliably on columns that have unique indexes or are marked as primary keys. If the constraint is specified as DEFERRABLE it will be checked at the end of the statement, rather than after each row is updated. The constraint check can also be deferred until the end of the current transaction,
1475

Notes de version

allowing such updates to be spread over multiple SQL commands.

Add exclusion constraints (Jeff Davis)


Exclusion constraints generalize uniqueness constraints by allowing arbitrary comparison operators, not just equality. They are
created with the CREATE TABLE CONSTRAINT ... EXCLUDE clause. The most common use of exclusion constraints is
to specify that column entries must not overlap, rather than simply not be equal. This is useful for time periods and other
ranges, as well as arrays. This feature enhances checking of data integrity for many calendaring, time-management, and scientific applications.

Improve uniqueness-constraint violation error messages to report the values causing the failure (Itagaki Takahiro)
For example, a uniqueness constraint violation might now report Key (x)=(2) already exists.

E.34.3.3.4. Object Permissions

Add the ability to make mass permission changes across a whole schema using the new GRANT/REVOKE IN SCHEMA
clause (Petr Jelinek)
This simplifies management of object permissions and makes it easier to utilize database roles for application data security.

Add ALTER DEFAULT PRIVILEGES command to control privileges of objects created later (Petr Jelinek)
This greatly simplifies the assignment of object privileges in a complex database application. Default privileges can be set for
tables, views, sequences, and functions. Defaults may be assigned on a per-schema basis, or database-wide.

Add the ability to control large object (BLOB) permissions with GRANT/REVOKE (KaiGai Kohei)
Formerly, any database user could read or modify any large object. Read and write permissions can now be granted and revoked per large object, and the ownership of large objects is tracked.

E.34.3.4. Utility Operations

Make LISTEN/NOTIFY store pending events in a memory queue, rather than in a system table (Joachim Wieland)
This substantially improves performance, while retaining the existing features of transactional support and guaranteed delivery.

Allow NOTIFY to pass an optional payload string to listeners (Joachim Wieland)


This greatly improves the usefulness of LISTEN/NOTIFY as a general-purpose event queue system.

Allow CLUSTER on all per-database system catalogs (Tom Lane)


Shared catalogs still cannot be clustered.

E.34.3.4.1. COPY

Accept COPY ... CSV FORCE QUOTE * (Itagaki Takahiro)


Now * can be used as shorthand for all columns in the FORCE QUOTE clause.

Add new COPY syntax that allows options to be specified inside parentheses (Robert Haas, Emmanuel Cecchet)
This allows greater flexibility for future COPY options. The old syntax is still supported, but only for pre-existing options.

E.34.3.4.2. EXPLAIN

Allow EXPLAIN to output in XML, JSON, or YAML format (Robert Haas, Greg Sabino Mullane)
The new output formats are easily machine-readable, supporting the development of new tools for analysis of EXPLAIN output.

Add new BUFFERS option to report query buffer usage during EXPLAIN ANALYZE (Itagaki Takahiro)
This allows better query profiling for individual queries. Buffer usage is no longer reported in the output for
log_statement_stats and related settings.

Add hash usage information to EXPLAIN output (Robert Haas)


1476

Notes de version

Add new EXPLAIN syntax that allows options to be specified inside parentheses (Robert Haas)
This allows greater flexibility for future EXPLAIN options. The old syntax is still supported, but only for pre-existing options.

E.34.3.4.3. VACUUM

Change VACUUM FULL to rewrite the entire table and rebuild its indexes, rather than moving individual rows around to
compact space (Itagaki Takahiro, Tom Lane)
The previous method was usually slower and caused index bloat. Note that the new method will use more disk space transiently during VACUUM FULL; potentially as much as twice the space normally occupied by the table and its indexes.

Add new VACUUM syntax that allows options to be specified inside parentheses (Itagaki Takahiro)
This allows greater flexibility for future VACUUM options. The old syntax is still supported, but only for pre-existing options.

E.34.3.4.4. Indexes

Allow an index to be named automatically by omitting the index name in CREATE INDEX (Tom Lane)

By default, multicolumn indexes are now named after all their columns; and index expression columns are now named based
on their expressions (Tom Lane)

Reindexing shared system catalogs is now fully transactional and crash-safe (Tom Lane)
Formerly, reindexing a shared index was only allowed in standalone mode, and a crash during the operation could leave the index in worse condition than it was before.

Add point_ops operator class for GiST (Teodor Sigaev)


This feature permits GiST indexing of point columns. The index can be used for several types of queries such as point <@
polygon (point is in polygon). This should make many PostGIS queries faster.

Use red-black binary trees for GIN index creation (Teodor Sigaev)
Red-black trees are self-balancing. This avoids slowdowns in cases where the input is in nonrandom order.

E.34.3.5. Data Types

Allow bytea values to be written in hex notation (Peter Eisentraut)


The server parameter bytea_output controls whether hex or traditional format is used for bytea output. Libpq's PQescapeByteaConn() function automatically uses the hex format when connected to PostgreSQL 9.0 or newer servers. However, pre-9.0 libpq versions will not correctly process hex format from newer servers.
The new hex format will be directly compatible with more applications that use binary data, allowing them to store and retrieve it without extra conversion. It is also significantly faster to read and write than the traditional format.

Allow server parameter extra_float_digits to be increased to 3 (Tom Lane)


The previous maximum extra_float_digits setting was 2. There are cases where 3 digits are needed to dump and restore float4 values exactly. pg_dump will now use the setting of 3 when dumping from a server that allows it.

Tighten input checking for int2vector values (Caleb Welton)

E.34.3.5.1. Full Text Search

Add prefix support in synonym dictionaries (Teodor Sigaev)

Add filtering dictionaries (Teodor Sigaev)


Filtering dictionaries allow tokens to be modified then passed to subsequent dictionaries.

Allow underscores in email-address tokens (Teodor Sigaev)

Use more standards-compliant rules for parsing URL tokens (Tom Lane)

1477

Notes de version

E.34.3.6. Functions

Allow function calls to supply parameter names and match them to named parameters in the function definition (Pavel Stehule)
For example, if a function is defined to take parameters a and b, it can be called with func(a := 7, b := 12) or
func(b := 12, a := 7).

Support locale-specific regular expression processing with UTF-8 server encoding (Tom Lane)
Locale-specific regular expression functionality includes case-insensitive matching and locale-specific character classes. Previously, these features worked correctly for non-ASCII characters only if the database used a single-byte server encoding
(such as LATIN1). They will still misbehave in multi-byte encodings other than UTF-8.

Add support for scientific notation in to_char() (EEEE specification) (Pavel Stehule, Brendan Jurd)

Make to_char() honor FM (fill mode) in Y, YY, and YYY specifications (Bruce Momjian, Tom Lane)
It was already honored by YYYY.

Fix to_char() to output localized numeric and monetary strings in the correct encoding on Windows (Hiroshi Inoue, Itagaki Takahiro, Bruce Momjian)

Correct calculations of overlaps and contains operations for polygons (Teodor Sigaev)
The polygon && (overlaps) operator formerly just checked to see if the two polygons' bounding boxes overlapped. It now does
a more correct check. The polygon @> and <@ (contains/contained by) operators formerly checked to see if one polygon's vertexes were all contained in the other; this can wrongly report true for some non-convex polygons. Now they check that all
line segments of one polygon are contained in the other.

E.34.3.6.1. Aggregates

Allow aggregate functions to use ORDER BY (Andrew Gierth)


For example, this is now supported: array_agg(a ORDER BY b). This is useful with aggregates for which the order of
input values is significant, and eliminates the need to use a nonstandard subquery to determine the ordering.

Multi-argument aggregate functions can now use DISTINCT (Andrew Gierth)

Add the string_agg() aggregate function to combine values into a single string (Pavel Stehule)

Aggregate functions that are called with DISTINCT are now passed NULL values if the aggregate transition function is not
marked as STRICT (Andrew Gierth)
For example, agg(DISTINCT x) might pass a NULL x value to agg(). This is more consistent with the behavior in
non-DISTINCT cases.

E.34.3.6.2. Bit Strings

Add get_bit() and set_bit() functions for bit strings, mirroring those for bytea (Leonardo F)

Implement OVERLAY() (replace) for bit strings and bytea (Leonardo F)

E.34.3.6.3. Object Information Functions

Add pg_table_size() and pg_indexes_size() to provide a more user-friendly interface to the


pg_relation_size() function (Bernd Helmle)

Add has_sequence_privilege() for sequence permission checking (Abhijit Menon-Sen)

Update the information_schema views to conform to SQL:2008 (Peter Eisentraut)

Make the information_schema views correctly display maximum octet lengths for char and varchar columns (Peter Eisentraut)

Speed up information_schema privilege views (Joachim Wieland)

E.34.3.6.4. Function and Trigger Creation

1478

Notes de version

Support execution of anonymous code blocks using the DO statement (Petr Jelinek, Joshua Tolley, Hannu Valtonen)
This allows execution of server-side code without the need to create and delete a temporary function definition. Code can be
executed in any language for which the user has permissions to define a function.

Implement SQL-standard-compliant per-column triggers (Itagaki Takahiro)


Such triggers are fired only when the specified column(s) are affected by the query, e.g. appear in an UPDATE's SET list.

Add the WHEN clause to CREATE TRIGGER to allow control over whether a trigger is fired (Itagaki Takahiro)
While the same type of check can always be performed inside the trigger, doing it in an external WHEN clause can have performance benefits.

E.34.3.7. Server-Side Languages

Add the OR REPLACE clause to CREATE LANGUAGE (Tom Lane)


This is helpful to optionally install a language if it does not already exist, and is particularly helpful now that PL/pgSQL is installed by default.

E.34.3.7.1. PL/pgSQL Server-Side Language

Install PL/pgSQL by default (Bruce Momjian)


The language can still be removed from a particular database if the administrator has security or performance concerns about
making it available.

Improve handling of cases where PL/pgSQL variable names conflict with identifiers used in queries within a function (Tom
Lane)
The default behavior is now to throw an error when there is a conflict, so as to avoid surprising behaviors. This can be modified, via the configuration parameter plpgsql.variable_conflict or the per-function option
#variable_conflict, to allow either the variable or the query-supplied column to be used. In any case PL/pgSQL will
no longer attempt to substitute variables in places where they would not be syntactically valid.

Make PL/pgSQL use the main lexer, rather than its own version (Tom Lane)
This ensures accurate tracking of the main system's behavior for details such as string escaping. Some user-visible details,
such as the set of keywords considered reserved in PL/pgSQL, have changed in consequence.

Avoid throwing an unnecessary error for an invalid record reference (Tom Lane)
An error is now thrown only if the reference is actually fetched, rather than whenever the enclosing expression is reached. For
example, many people have tried to do this in triggers:
if TG_OP = 'INSERT' and NEW.col1 = ... then
This will now actually work as expected.

Improve PL/pgSQL's ability to handle row types with dropped columns (Pavel Stehule)

Allow input parameters to be assigned values within PL/pgSQL functions (Steve Prentice)
Formerly, input parameters were treated as being declared CONST, so the function's code could not change their values. This
restriction has been removed to simplify porting of functions from other DBMSes that do not impose the equivalent restriction.
An input parameter now acts like a local variable initialized to the passed-in value.

Improve error location reporting in PL/pgSQL (Tom Lane)

Add count and ALL options to MOVE FORWARD/BACKWARD in PL/pgSQL (Pavel Stehule)

Allow PL/pgSQL's WHERE CURRENT OF to use a cursor variable (Tom Lane)

Allow PL/pgSQL's OPEN cursor FOR EXECUTE to use parameters (Pavel Stehule, Itagaki Takahiro)
This is accomplished with a new USING clause.

E.34.3.7.2. PL/Perl Server-Side Language

1479

Notes de version

Add new PL/Perl functions: quote_literal(), quote_nullable(), quote_ident(), encode_bytea(), decode_bytea(), looks_like_number(), encode_array_literal(), encode_array_constructor()
(Tim Bunce)

Add server parameter plperl.on_init to specify a PL/Perl initialization function (Tim Bunce)
plperl.on_plperl_init and plperl.on_plperlu_init are also available for initialization that is specific to the
trusted or untrusted language respectively.

Support END blocks in PL/Perl (Tim Bunce)


END blocks do not currently allow database access.

Allow use strict in PL/Perl (Tim Bunce)


Perl strict checks can also be globally enabled with the new server parameter plperl.use_strict.

Allow require in PL/Perl (Tim Bunce)


This basically tests to see if the module is loaded, and if not, generates an error. It will not allow loading of modules that the
administrator has not preloaded via the initialization parameters.

Allow use feature in PL/Perl if Perl version 5.10 or later is used (Tim Bunce)

Verify that PL/Perl return values are valid in the server encoding (Andrew Dunstan)

E.34.3.7.3. PL/Python Server-Side Language

Add Unicode support in PL/Python (Peter Eisentraut)


Strings are automatically converted from/to the server encoding as necessary.

Improve bytea support in PL/Python (Caleb Welton)


Bytea values passed into PL/Python are now represented as binary, rather than the PostgreSQL bytea text format. Bytea values
containing null bytes are now also output properly from PL/Python. Passing of boolean, integer, and float values was also improved.

Support arrays as parameters and return values in PL/Python (Peter Eisentraut)

Improve mapping of SQL domains to Python types (Peter Eisentraut)

Add Python 3 support to PL/Python (Peter Eisentraut)


The new server-side language is called plpython3u. This cannot be used in the same session with the Python 2 server-side
language.

Improve error location and exception reporting in PL/Python (Peter Eisentraut)

E.34.3.8. Client Applications

Add an --analyze-only option to vacuumdb, to analyze without vacuuming (Bruce Momjian)

E.34.3.8.1. psql

Add support for quoting/escaping the values of psql variables as SQL strings or identifiers (Pavel Stehule, Robert Haas)
For example, :'var' will produce the value of var quoted and properly escaped as a literal string, while :"var" will produce its value quoted and escaped as an identifier.

Ignore a leading UTF-8-encoded Unicode byte-order marker in script files read by psql (Itagaki Takahiro)
This is enabled when the client encoding is UTF-8. It improves compatibility with certain editors, mostly on Windows, that insist on inserting such markers.

Fix psql --file - to properly honor --single-transaction (Bruce Momjian)

Avoid overwriting of psql's command-line history when two psql sessions are run concurrently (Tom Lane)

Improve psql's tab completion support (Itagaki Takahiro)

Show \timing output when it is enabled, regardless of quiet mode (Peter Eisentraut)
1480

Notes de version

E.34.3.8.1.1. psql Display

Improve display of wrapped columns in psql (Roger Leigh)


This behavior is now the default. The previous formatting is available by using \pset linestyle old-ascii.

Allow psql to use fancy Unicode line-drawing characters via \pset linestyle unicode (Roger Leigh)

E.34.3.8.1.2. psql \d Commands

Make \d show child tables that all from the specified parent (Damien Clochard)
\d shows only the number of child tables, while \d+ shows the names of all child tables.

Show definitions of index columns in \d index_name (Khee Chin)


The definition is useful for expression indexes.

Show a view's defining query only in \d+, not in \d (Peter Eisentraut)


Always including the query was deemed overly verbose.

E.34.3.8.2. pg_dump

Make pg_dump/pg_restore --clean also remove large objects (Itagaki Takahiro)

Fix pg_dump to properly dump large objects when standard_conforming_strings is enabled (Tom Lane)
The previous coding could fail when dumping to an archive file and then generating script output from pg_restore.

pg_restore now emits large-object data in hex format when generating script output (Tom Lane)
This could cause compatibility problems if the script is then loaded into a pre-9.0 server. To work around that, restore directly
to the server, instead.

Allow pg_dump to dump comments attached to columns of composite types (Taro Minowa (Higepon))

Make pg_dump --verbose output the pg_dump and server versions in text output mode (Jim Cox, Tom Lane)
These were already provided in custom output mode.

pg_restore now complains if any command-line arguments remain after the switches and optional file name (Tom Lane)
Previously, it silently ignored any such arguments.

E.34.3.8.3. pg_ctl

Allow pg_ctl to be used safely to start the postmaster during a system reboot (Tom Lane)
Previously, pg_ctl's parent process could have been mistakenly identified as a running postmaster based on a stale postmaster
lock file, resulting in a transient failure to start the database.

Give pg_ctl the ability to initialize the database (by invoking initdb) (Zdenek Kotala)

E.34.3.9. Development Tools


E.34.3.9.1. libpq

Add new libpq functions PQconnectdbParams() and PQconnectStartParams() (Guillaume Lelarge)


These functions are similar to PQconnectdb() and PQconnectStart() except that they accept a null-terminated array
of connection options, rather than requiring all options to be provided in a single string.

Add libpq functions PQescapeLiteral() and PQescapeIdentifier() (Robert Haas)


These functions return appropriately quoted and escaped SQL string literals and identifiers. The caller is not required to preallocate the string result, as is required by PQescapeStringConn().

Add support for a per-user service file (.pg_service.conf), which is checked before the site-wide service file (Peter Eisentraut)
1481

Notes de version

Properly report an error if the specified libpq service cannot be found (Peter Eisentraut)

Add TCP keepalive settings in libpq (Tollef Fog Heen, Fujii Masao, Robert Haas)
Keepalive settings were already supported on the server end of TCP connections.

Avoid extra system calls to block and unblock SIGPIPE in libpq, on platforms that offer alternative methods (Jeremy Kerr)

When a .pgpass-supplied password fails, mention where the password came from in the error message (Bruce Momjian)

Load all SSL certificates given in the client certificate file (Tom Lane)
This improves support for indirectly-signed SSL certificates.

E.34.3.9.2. ecpg

Add SQLDA (SQL Descriptor Area) support to ecpg (Boszormenyi Zoltan)

Add the DESCRIBE [ OUTPUT ] statement to ecpg (Boszormenyi Zoltan)

Add an ECPGtransactionStatus function to return the current transaction status (Bernd Helmle)

Add the string data type in ecpg Informix-compatibility mode (Boszormenyi Zoltan)

Allow ecpg to use new and old variable names without restriction (Michael Meskes)

Allow ecpg to use variable names in free() (Michael Meskes)

Make ecpg_dynamic_type() return zero for non-SQL3 data types (Michael Meskes)
Previously it returned the negative of the data type OID. This could be confused with valid type OIDs, however.

Support long long types on platforms that already have 64-bit long (Michael Meskes)

E.34.3.9.2.1. ecpg Cursors

Add out-of-scope cursor support in ecpg's native mode (Boszormenyi Zoltan)


This allows DECLARE to use variables that are not in scope when OPEN is called. This facility already existed in ecpg's Informix-compatibility mode.

Allow dynamic cursor names in ecpg (Boszormenyi Zoltan)

Allow ecpg to use noise words FROM and IN in FETCH and MOVE (Boszormenyi Zoltan)

E.34.3.10. Build Options

Enable client thread safety by default (Bruce Momjian)


The thread-safety option can be disabled with configure --disable-thread-safety.

Add support for controlling the Linux out-of-memory killer (Alex Hunsaker, Tom Lane)
Now that /proc/self/oom_adj allows disabling of the Linux out-of-memory (OOM) killer, it's recommendable to disable OOM kills for the postmaster. It may then be desirable to re-enable OOM kills for the postmaster's child processes. The
new compile-time option LINUX_OOM_ADJ allows the killer to be reactivated for child processes.

E.34.3.10.1. Makefiles

New Makefile targets world, install-world, and installcheck-world (Andrew Dunstan)


These are similar to the existing all, install, and installcheck targets, but they also build the HTML documentation,
build and test contrib, and test server-side languages and ecpg.

Add data and documentation installation location control to PGXS Makefiles (Mark Cave-Ayland)

Add Makefile rules to build the PostgreSQL documentation as a single HTML file or as a single plain-text file (Peter Eisentraut, Bruce Momjian)

E.34.3.10.2. Windows

1482

Notes de version

Support compiling on 64-bit Windows and running in 64-bit mode (Tsutomu Yamada, Magnus Hagander)
This allows for large shared memory sizes on Windows.

Support server builds using Visual Studio 2008 (Magnus Hagander)

E.34.3.11. Source Code

Distribute prebuilt documentation in a subdirectory tree, rather than as tar archive files inside the distribution tarball (Peter Eisentraut)
For example, the prebuilt HTML documentation is now in doc/src/sgml/html/; the manual pages are packaged similarly.

Make the server's lexer reentrant (Tom Lane)


This was needed for use of the lexer by PL/pgSQL.

Improve speed of memory allocation (Tom Lane, Greg Stark)

User-defined constraint triggers now have entries in pg_constraint as well as pg_trigger (Tom Lane)
Because of this change, pg_constraint.pgconstrname is now redundant and has been removed.

Add system catalog columns pg_constraint.conindid and pg_trigger.tgconstrindid to better document the use of indexes for constraint enforcement (Tom Lane)

Allow multiple conditions to be communicated to backends using a single operating system signal (Fujii Masao)
This allows new features to be added without a platform-specific constraint on the number of signal conditions.

Improve source code test coverage, including contrib, PL/Python, and PL/Perl (Peter Eisentraut, Andrew Dunstan)

Remove the use of flat files for system table bootstrapping (Tom Lane, Alvaro Herrera)
This improves performance when using many roles or databases, and eliminates some possible failure conditions.

Automatically generate the initial contents of pg_attribute for bootstrapped catalogs (John Naylor)
This greatly simplifies changes to these catalogs.

Split the processing of INSERT/UPDATE/DELETE operations out of execMain.c (Marko Tiikkaja)


Updates are now executed in a separate ModifyTable node. This change is necessary infrastructure for future improvements.

Simplify translation of psql's SQL help text (Peter Eisentraut)

Reduce the lengths of some file names so that all file paths in the distribution tarball are less than 100 characters (Tom Lane)
Some decompression programs have problems with longer file paths.

Add a new ERRCODE_INVALID_PASSWORD SQLSTATE error code (Bruce Momjian)

With authors' permissions, remove the few remaining personal source code copyright notices (Bruce Momjian)
The personal copyright notices were insignificant but the community occasionally had to answer questions about them.

Add new documentation section about running PostgreSQL in non-durable mode to improve performance (Bruce Momjian)

Restructure the HTML documentation Makefile rules to make their dependency checks work correctly, avoiding unnecessary rebuilds (Peter Eisentraut)

Use DocBook XSL stylesheets for man page building, rather than Docbook2X (Peter Eisentraut)
This changes the set of tools needed to build the man pages.

Improve PL/Perl code structure (Tim Bunce)

Improve error context reports in PL/Perl (Alexey Klyukin)

E.34.3.11.1. New Build Requirements

Note that these requirements do not apply when building from a distribution tarball, since tarballs include the files that these programs are used to build.

1483

Notes de version

Require Autoconf 2.63 to build configure (Peter Eisentraut)

Require Flex 2.5.31 or later to build from a CVS checkout (Tom Lane)

Require Perl version 5.8 or later to build from a CVS checkout (John Naylor, Andrew Dunstan)

E.34.3.11.2. Portability

Use a more modern API for Bonjour (Tom Lane)


Bonjour support now requires OS X 10.3 or later. The older API has been deprecated by Apple.

Add spinlock support for the SuperH architecture (Nobuhiro Iwamatsu)

Allow non-GCC compilers to use inline functions if they support them (Kurt Harriman)

Remove support for platforms that don't have a working 64-bit integer data type (Tom Lane)

Restructure use of LDFLAGS to be more consistent across platforms (Tom Lane)


LDFLAGS is now used for linking both executables and shared libraries, and we add on LDFLAGS_EX when linking executables, or LDFLAGS_SL when linking shared libraries.

E.34.3.11.3. Server Programming

Make backend header files safe to include in C++ (Kurt Harriman, Peter Eisentraut)
These changes remove keyword conflicts that previously made C++ usage difficult in backend code. However, there are still
other complexities when using C++ for backend functions. extern "C" { } is still necessary in appropriate places, and
memory management and error handling are still problematic.

Add AggCheckCallContext() for use in detecting if a C function is being called as an aggregate (Hitoshi Harada)

Change calling convention for SearchSysCache() and related functions to avoid hard-wiring the maximum number of
cache keys (Robert Haas)
Existing calls will still work for the moment, but can be expected to break in 9.1 or later if not converted to the new style.

Require calls of fastgetattr() and heap_getattr() backend macros to provide a non-NULL fourth argument
(Robert Haas)

Custom typanalyze functions should no longer rely on VacAttrStats.attr to determine the type of data they will be passed
(Tom Lane)
This was changed to allow collection of statistics on index columns for which the storage type is different from the underlying
column data type. There are new fields that tell the actual datatype being analyzed.

E.34.3.11.4. Server Hooks

Add parser hooks for processing ColumnRef and ParamRef nodes (Tom Lane)

Add a ProcessUtility hook so loadable modules can control utility commands (Itagaki Takahiro)

E.34.3.11.5. Binary Upgrade Support

Add contrib/pg_upgrade to support in-place upgrades (Bruce Momjian)


This avoids the requirement of dumping/reloading the database when upgrading to a new major release of PostgreSQL, thus
reducing downtime by orders of magnitude. It supports upgrades to 9.0 from PostgreSQL 8.3 and 8.4.

Add support for preserving relation relfilenode values during binary upgrades (Bruce Momjian)

Add support for preserving pg_type and pg_enum OIDs during binary upgrades (Bruce Momjian)

Move data files within tablespaces into PostgreSQL-version-specific subdirectories (Bruce Momjian)
This simplifies binary upgrades.

E.34.3.12. Contrib
1484

Notes de version

Add multithreading option (-j) to contrib/pgbench (Itagaki Takahiro)


This allows multiple CPUs to be used by pgbench, reducing the risk of pgbench itself becoming the test bottleneck.

Add \shell and \setshell meta commands to contrib/pgbench (Michael Paquier)

New features for contrib/dict_xsyn (Sergey Karpov)


The new options are matchorig, matchsynonyms, and keepsynonyms.

Add full text dictionary contrib/unaccent (Teodor Sigaev)


This filtering dictionary removes accents from letters, which makes full-text searches over multiple languages much easier.

Add dblink_get_notify() to contrib/dblink (Marcus Kempe)


This allows asynchronous notifications in dblink.

Improve contrib/dblink's handling of dropped columns (Tom Lane)


This affects dblink_build_sql_insert() and related functions. These functions now number columns according to
logical not physical column numbers.

Greatly increase contrib/hstore's data length limit, and add B-tree and hash support so GROUP BY and DISTINCT
operations are possible on hstore columns (Andrew Gierth)
New functions and operators were also added. These improvements make hstore a full-function key-value store embedded in
PostgreSQL.

Add contrib/passwordcheck to support site-specific password strength policies (Laurenz Albe)


The source code of this module should be modified to implement site-specific password policies.

Add contrib/pg_archivecleanup tool (Simon Riggs)


This is designed to be used in the archive_cleanup_command server parameter, to remove no-longer-needed archive
files.

Add query text to contrib/auto_explain output (Andrew Dunstan)

Add buffer access counters to contrib/pg_stat_statements (Itagaki Takahiro)

Update contrib/start-scripts/linux to use /proc/self/oom_adj to disable the Linux out-of-memory


(OOM) killer (Alex Hunsaker, Tom Lane)

E.35. Release 8.4.22


Release Date
2014-07-24
This release contains a variety of fixes from 8.4.21. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .
This is expected to be the last PostgreSQL release in the 8.4.X series. Users are encouraged to update to a newer release branch
soon.

E.35.1. Migration to Version 8.4.22


A dump/restore is not required for those running 8.4.X.
However, this release corrects an index corruption problem in some GiST indexes. See the first changelog entry below to find out
whether your installation has been affected and what steps you should take if so.
Also, if you are upgrading from a version earlier than 8.4.19, see Section E.38, Release 8.4.19 .

E.35.2. Changes

Correctly initialize padding bytes in contrib/btree_gist indexes on bit columns (Heikki Linnakangas)
This error could result in incorrect query results due to values that should compare equal not being seen as equal. Users with
1485

Notes de version

GiST indexes on bit or bit varying columns should REINDEX those indexes after installing this update.

Protect against torn pages when deleting GIN list pages (Heikki Linnakangas)
This fix prevents possible index corruption if a system crash occurs while the page update is being written to disk.

Fix possibly-incorrect cache invalidation during nested calls to ReceiveSharedInvalidMessages (Andres Freund)

Don't assume a subquery's output is unique if there's a set-returning function in its targetlist (David Rowley)
This oversight could lead to misoptimization of constructs like WHERE x IN (SELECT y, generate_series(1,10) FROM t GROUP BY y).

Fix failure to detoast fields in composite elements of structured types (Tom Lane)
This corrects cases where TOAST pointers could be copied into other tables without being dereferenced. If the original data is
later deleted, it would lead to errors like missing chunk number 0 for toast value ... when the now-dangling pointer is used.

Fix record type has not been registered failures with whole-row references to the output of Append plan nodes (Tom Lane)

Fix possible crash when invoking a user-defined function while rewinding a cursor (Tom Lane)

Fix query-lifespan memory leak while evaluating the arguments for a function in FROM (Tom Lane)

Fix session-lifespan memory leaks in regular-expression processing (Tom Lane, Arthur O'Dwyer, Greg Stark)

Fix data encoding error in hungarian.stop (Tom Lane)

Fix liveness checks for rows that were inserted in the current transaction and then deleted by a now-rolled-back subtransaction
(Andres Freund)
This could cause problems (at least spurious warnings, and at worst an infinite loop) if CREATE INDEX or CLUSTER were
done later in the same transaction.

Clear pg_stat_activity.xact_start during PREPARE TRANSACTION (Andres Freund)


After the PREPARE, the originating session is no longer in a transaction, so it should not continue to display a transaction
start time.

Fix REASSIGN OWNED to not fail for text search objects (lvaro Herrera)

Block signals during postmaster startup (Tom Lane)


This ensures that the postmaster will properly clean up after itself if, for example, it receives SIGINT while still starting up.

Secure Unix-domain sockets of temporary postmasters started during make check (Noah Misch)
Any local user able to access the socket file could connect as the server's bootstrap superuser, then proceed to execute arbitrary
code as the operating-system user running the test, as we previously noted in CVE-2014-0067. This change defends against
that risk by placing the server's socket in a temporary, mode 0700 subdirectory of /tmp. The hazard remains however on platforms where Unix sockets are not supported, notably Windows, because then the temporary postmaster must accept local TCP
connections.
A useful side effect of this change is to simplify make check testing in builds that override DEFAULT_PGSOCKET_DIR.
Popular non-default values like /var/run/postgresql are often not writable by the build user, requiring workarounds
that will no longer be necessary.

On Windows, allow new sessions to absorb values of PGC_BACKEND parameters (such as log_connections) from the configuration file (Amit Kapila)
Previously, if such a parameter were changed in the file post-startup, the change would have no effect.

Properly quote executable path names on Windows (Nikhil Deshpande)


This oversight could cause initdb and pg_upgrade to fail on Windows, if the installation path contained both spaces and @ signs.

Fix linking of libpython on OS X (Tom Lane)


The method we previously used can fail with the Python library supplied by Xcode 5.0 and later.

Avoid buffer bloat in libpq when the server consistently sends data faster than the client can absorb it (Shin-ichi Morita, Tom
Lane)
libpq could be coerced into enlarging its input buffer until it runs out of memory (which would be reported misleadingly as
1486

Notes de version

lost synchronization with server ). Under ordinary circumstances it's quite far-fetched that data could be continuously transmitted more quickly than the recv() loop can absorb it, but this has been observed when the client is artificially slowed by
scheduler constraints.

Ensure that LDAP lookup attempts in libpq time out as intended (Laurenz Albe)

Fix pg_restore's processing of old-style large object comments (Tom Lane)


A direct-to-database restore from an archive file generated by a pre-9.0 version of pg_dump would usually fail if the archive
contained more than a few comments for large objects.

In contrib/pgcrypto functions, ensure sensitive information is cleared from stack variables before returning (Marko
Kreen)

In contrib/uuid-ossp, cache the state of the OSSP UUID library across calls (Tom Lane)
This improves the efficiency of UUID generation and reduces the amount of entropy drawn from /dev/urandom, on platforms that have that.

Update time zone data files to tzdata release 2014e for DST law changes in Crimea, Egypt, and Morocco.

E.36. Release 8.4.21


Release Date
2014-03-20
This release contains a variety of fixes from 8.4.20. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .
The PostgreSQL community will stop releasing updates for the 8.4.X release series in July 2014. Users are encouraged to update to a newer release branch soon.

E.36.1. Migration to Version 8.4.21


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.19, see Section E.38, Release 8.4.19 .

E.36.2. Changes

Restore GIN metapages unconditionally to avoid torn-page risk (Heikki Linnakangas)


Although this oversight could theoretically result in a corrupted index, it is unlikely to have caused any problems in practice,
since the active part of a GIN metapage is smaller than a standard 512-byte disk sector.

Allow regular-expression operators to be terminated early by query cancel requests (Tom Lane)
This prevents scenarios wherein a pathological regular expression could lock up a server process uninterruptably for a long
time.

Remove incorrect code that tried to allow OVERLAPS with single-element row arguments (Joshua Yanovski)
This code never worked correctly, and since the case is neither specified by the SQL standard nor documented, it seemed better to remove it than fix it.

Avoid getting more than AccessShareLock when de-parsing a rule or view (Dean Rasheed)
This oversight resulted in pg_dump unexpectedly acquiring RowExclusiveLock locks on tables mentioned as the targets
of INSERT/UPDATE/DELETE commands in rules. While usually harmless, that could interfere with concurrent transactions
that tried to acquire, for example, ShareLock on those tables.

Prevent interrupts while reporting non-ERROR messages (Tom Lane)


This guards against rare server-process freezeups due to recursive entry to syslog(), and perhaps other related problems.

Update time zone data files to tzdata release 2014a for DST law changes in Fiji and Turkey, plus historical changes in Israel
and Ukraine.

1487

Notes de version

E.37. Release 8.4.20


Release Date
2014-02-20
This release contains a variety of fixes from 8.4.19. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .
The PostgreSQL community will stop releasing updates for the 8.4.X release series in July 2014. Users are encouraged to update to a newer release branch soon.

E.37.1. Migration to Version 8.4.20


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.19, see Section E.38, Release 8.4.19 .

E.37.2. Changes

Shore up GRANT ... WITH ADMIN OPTION restrictions (Noah Misch)


Granting a role without ADMIN OPTION is supposed to prevent the grantee from adding or removing members from the
granted role, but this restriction was easily bypassed by doing SET ROLE first. The security impact is mostly that a role member can revoke the access of others, contrary to the wishes of his grantor. Unapproved role member additions are a lesser
concern, since an uncooperative role member could provide most of his rights to others anyway by creating views or SECURITY DEFINER functions. (CVE-2014-0060)

Prevent privilege escalation via manual calls to PL validator functions (Andres Freund)
The primary role of PL validator functions is to be called implicitly during CREATE FUNCTION, but they are also normal
SQL functions that a user can call explicitly. Calling a validator on a function actually written in some other language was not
checked for and could be exploited for privilege-escalation purposes. The fix involves adding a call to a privilege-checking
function in each validator function. Non-core procedural languages will also need to make this change to their own validator
functions, if any. (CVE-2014-0061)

Avoid multiple name lookups during table and index DDL (Robert Haas, Andres Freund)
If the name lookups come to different conclusions due to concurrent activity, we might perform some parts of the DDL on a
different table than other parts. At least in the case of CREATE INDEX, this can be used to cause the permissions checks to
be performed against a different table than the index creation, allowing for a privilege escalation attack. (CVE-2014-0062)

Prevent buffer overrun with long datetime strings (Noah Misch)


The MAXDATELEN constant was too small for the longest possible value of type interval, allowing a buffer overrun in interval_out(). Although the datetime input functions were more careful about avoiding buffer overrun, the limit was short
enough to cause them to reject some valid inputs, such as input containing a very long timezone name. The ecpg library
contained these vulnerabilities along with some of its own. (CVE-2014-0063)

Prevent buffer overrun due to integer overflow in size calculations (Noah Misch, Heikki Linnakangas)
Several functions, mostly type input functions, calculated an allocation size without checking for overflow. If overflow did occur, a too-small buffer would be allocated and then written past. (CVE-2014-0064)

Prevent overruns of fixed-size buffers (Peter Eisentraut, Jozef Mlich)


Use strlcpy() and related functions to provide a clear guarantee that fixed-size buffers are not overrun. Unlike the preceding items, it is unclear whether these cases really represent live issues, since in most cases there appear to be previous
constraints on the size of the input string. Nonetheless it seems prudent to silence all Coverity warnings of this type.
(CVE-2014-0065)

Avoid crashing if crypt() returns NULL (Honza Horak, Bruce Momjian)


There are relatively few scenarios in which crypt() could return NULL, but contrib/chkpass would crash if it did.
One practical case in which this could be an issue is if libc is configured to refuse to execute unapproved hashing algorithms
(e.g., FIPS mode ). (CVE-2014-0066)

Document risks of make check in the regression testing instructions (Noah Misch, Tom Lane)

1488

Notes de version

Since the temporary server started by make check uses trust authentication, another user on the same machine could
connect to it as database superuser, and then potentially exploit the privileges of the operating-system user who started the
tests. A future release will probably incorporate changes in the testing procedure to prevent this risk, but some public discussion is needed first. So for the moment, just warn people against using make check when there are untrusted users on the
same machine. (CVE-2014-0067)

Fix possible mis-replay of WAL records when some segments of a relation aren't full size (Greg Stark, Tom Lane)
The WAL update could be applied to the wrong page, potentially many pages past where it should have been. Aside from corrupting data, this error has been observed to result in significant bloat of standby servers compared to their masters, due to
updates being applied far beyond where the end-of-file should have been. This failure mode does not appear to be a significant
risk during crash recovery, only when initially synchronizing a standby created from a base backup taken from a quicklychanging master.

Ensure that insertions into non-leaf GIN index pages write a full-page WAL record when appropriate (Heikki Linnakangas)
The previous coding risked index corruption in the event of a partial-page write during a system crash.

Fix race conditions during server process exit (Robert Haas)


Ensure that signal handlers don't attempt to use the process's MyProc pointer after it's no longer valid.

Fix unsafe references to errno within error reporting logic (Christian Kruse)
This would typically lead to odd behaviors such as missing or inappropriate HINT fields.

Fix possible crashes from using ereport() too early during server startup (Tom Lane)
The principal case we've seen in the field is a crash if the server is started in a directory it doesn't have permission to read.

Clear retry flags properly in OpenSSL socket write function (Alexander Kukushkin)
This omission could result in a server lockup after unexpected loss of an SSL-encrypted connection.

Fix length checking for Unicode identifiers (U&"..." syntax) containing escapes (Tom Lane)
A spurious truncation warning would be printed for such identifiers if the escaped form of the identifier was too long, but the
identifier actually didn't need truncation after de-escaping.

Fix possible crash due to invalid plan for nested sub-selects, such as WHERE (... x IN (SELECT ...) ...) IN
(SELECT ...) (Tom Lane)

Ensure that ANALYZE creates statistics for a table column even when all the values in it are too wide (Tom Lane)
ANALYZE intentionally omits very wide values from its histogram and most-common-values calculations, but it neglected to
do something sane in the case that all the sampled entries are too wide.

In ALTER TABLE ... SET TABLESPACE, allow the database's default tablespace to be used without a permissions
check (Stephen Frost)
CREATE TABLE has always allowed such usage, but ALTER TABLE didn't get the memo.

Fix cannot accept a set error when some arms of a CASE return a set and others don't (Tom Lane)

Fix checks for all-zero client addresses in pgstat functions (Kevin Grittner)

Fix possible misclassification of multibyte characters by the text search parser (Tom Lane)
Non-ASCII characters could be misclassified when using C locale with a multibyte encoding. On Cygwin, non-C locales could
fail as well.

Fix possible misbehavior in plainto_tsquery() (Heikki Linnakangas)


Use memmove() not memcpy() for copying overlapping memory regions. There have been no field reports of this actually
causing trouble, but it's certainly risky.

Accept SHIFT_JIS as an encoding name for locale checking purposes (Tatsuo Ishii)

Fix misbehavior of PQhost() on Windows (Fujii Masao)


It should return localhost if no host has been specified.

Improve error handling in libpq and psql for failures during COPY TO STDOUT/FROM STDIN (Tom Lane)
In particular this fixes an infinite loop that could occur in 9.2 and up if the server connection was lost during COPY FROM
1489

Notes de version

STDIN. Variants of that scenario might be possible in older versions, or with other client applications.

Fix misaligned descriptors in ecpg (MauMau)

In ecpg, handle lack of a hostname in the connection parameters properly (Michael Meskes)

Fix performance regression in contrib/dblink connection startup (Joe Conway)


Avoid an unnecessary round trip when client and server encodings match.

In contrib/isn, fix incorrect calculation of the check digit for ISMN values (Fabien Coelho)

Ensure client-code-only installation procedure works as documented (Peter Eisentraut)

In Mingw and Cygwin builds, install the libpq DLL in the bin directory (Andrew Dunstan)
This duplicates what the MSVC build has long done. It should fix problems with programs like psql failing to start because
they can't find the DLL.

Don't generate plain-text HISTORY and src/test/regress/README files anymore (Tom Lane)
These text files duplicated the main HTML and PDF documentation formats. The trouble involved in maintaining them greatly
outweighs the likely audience for plain-text format. Distribution tarballs will still contain files by these names, but they'll just
be stubs directing the reader to consult the main documentation. The plain-text INSTALL file will still be maintained, as there
is arguably a use-case for that.

Update time zone data files to tzdata release 2013i for DST law changes in Jordan and historical changes in Cuba.
In addition, the zones Asia/Riyadh87, Asia/Riyadh88, and Asia/Riyadh89 have been removed, as they are no longer maintained by IANA, and never represented actual civil timekeeping practice.

E.38. Release 8.4.19


Release Date
2013-12-05
This release contains a variety of fixes from 8.4.18. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.38.1. Migration to Version 8.4.19


A dump/restore is not required for those running 8.4.X.
However, this release corrects a potential data corruption issue. See the first changelog entry below to find out whether your installation has been affected and what steps you can take if so.
Also, if you are upgrading from a version earlier than 8.4.17, see Section E.40, Release 8.4.17 .

E.38.2. Changes

Fix VACUUM's tests to see whether it can update relfrozenxid (Andres Freund)
In some cases VACUUM (either manual or autovacuum) could incorrectly advance a table's relfrozenxid value, allowing
tuples to escape freezing, causing those rows to become invisible once 2^31 transactions have elapsed. The probability of data
loss is fairly low since multiple incorrect advancements would need to happen before actual loss occurs, but it's not zero. Users
upgrading from release 8.4.8 or earlier are not affected, but all later versions contain the bug.
The issue can be ameliorated by, after upgrading, vacuuming all tables in all databases while having vacuum_freeze_table_age set to zero. This will fix any latent corruption but will not be able to fix all pre-existing data
errors. However, an installation can be presumed safe after performing this vacuuming if it has executed fewer than 2^31 update transactions in its lifetime (check this with SELECT txid_current() < 2^31).

Fix race condition in GIN index posting tree page deletion (Heikki Linnakangas)
This could lead to transient wrong answers or query failures.

Avoid flattening a subquery whose SELECT list contains a volatile function wrapped inside a sub-SELECT (Tom Lane)
This avoids unexpected results due to extra evaluations of the volatile function.
1490

Notes de version

Fix planner's processing of non-simple-variable subquery outputs nested within outer joins (Tom Lane)
This error could lead to incorrect plans for queries involving multiple levels of subqueries within JOIN syntax.

Fix premature deletion of temporary files (Andres Freund)

Fix possible read past end of memory in rule printing (Peter Eisentraut)

Fix array slicing of int2vector and oidvector values (Tom Lane)


Expressions of this kind are now implicitly promoted to regular int2 or oid arrays.

Fix incorrect behaviors when using a SQL-standard, simple GMT offset timezone (Tom Lane)
In some cases, the system would use the simple GMT offset value when it should have used the regular timezone setting that
had prevailed before the simple offset was selected. This change also causes the timeofday function to honor the simple
GMT offset zone.

Prevent possible misbehavior when logging translations of Windows error codes (Tom Lane)

Properly quote generated command lines in pg_ctl (Naoya Anzai and Tom Lane)
This fix applies only to Windows.

Fix pg_dumpall to work when a source database sets default_transaction_read_only via ALTER DATABASE
SET (Kevin Grittner)
Previously, the generated script would fail during restore.

Fix ecpg's processing of lists of variables declared varchar (Zoltn Bszrmnyi)

Make contrib/lo defend against incorrect trigger definitions (Marc Cousin)

Update time zone data files to tzdata release 2013h for DST law changes in Argentina, Brazil, Jordan, Libya, Liechtenstein,
Morocco, and Palestine. Also, new timezone abbreviations WIB, WIT, WITA for Indonesia.

E.39. Release 8.4.18


Release Date
2013-10-10
This release contains a variety of fixes from 8.4.17. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.39.1. Migration to Version 8.4.18


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.17, see Section E.40, Release 8.4.17 .

E.39.2. Changes

Prevent corruption of multi-byte characters when attempting to case-fold identifiers (Andrew Dunstan)
PostgreSQL case-folds non-ASCII characters only when using a single-byte server encoding.

Fix memory leak caused by lo_open() failure (Heikki Linnakangas)

Fix memory overcommit bug when work_mem is using more than 24GB of memory (Stephen Frost)

Fix deadlock bug in libpq when using SSL (Stephen Frost)

Properly compute row estimates for boolean columns containing many NULL values (Andrew Gierth)
Previously tests like col IS NOT TRUE and col IS NOT FALSE did not properly factor in NULL values when estimating plan costs.

Prevent pushing down WHERE clauses into unsafe UNION/INTERSECT subqueries (Tom Lane)
Subqueries of a UNION or INTERSECT that contain set-returning functions or volatile functions in their SELECT lists could
1491

Notes de version

be improperly optimized, leading to run-time errors or incorrect query results.

Fix rare case of failed to locate grouping columns planner failure (Tom Lane)

Improve view dumping code's handling of dropped columns in referenced tables (Tom Lane)

Fix possible deadlock during concurrent CREATE INDEX CONCURRENTLY operations (Tom Lane)

Fix regexp_matches() handling of zero-length matches (Jeevan Chalke)


Previously, zero-length matches like '^' could return too many matches.

Fix crash for overly-complex regular expressions (Heikki Linnakangas)

Fix regular expression match failures for back references combined with non-greedy quantifiers (Jeevan Chalke)

Prevent CREATE FUNCTION from checking SET variables unless function body checking is enabled (Tom Lane)

Fix pgp_pub_decrypt() so it works for secret keys with passwords (Marko Kreen)

Remove rare inaccurate warning during vacuum of index-less tables (Heikki Linnakangas)

Avoid possible failure when performing transaction control commands (e.g ROLLBACK) in prepared queries (Tom Lane)

Ensure that floating-point data input accepts standard spellings of infinity on all platforms (Tom Lane)
The C99 standard says that allowable spellings are inf, +inf, -inf, infinity, +infinity, and -infinity. Make
sure we recognize these even if the platform's strtod function doesn't.

Expand ability to compare rows to records and arrays (Rafal Rzepecki, Tom Lane)

Update time zone data files to tzdata release 2013d for DST law changes in Israel, Morocco, Palestine, and Paraguay. Also,
historical zone data corrections for Macquarie Island.

E.40. Release 8.4.17


Release Date
2013-04-04
This release contains a variety of fixes from 8.4.16. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.40.1. Migration to Version 8.4.17


A dump/restore is not required for those running 8.4.X.
However, this release corrects several errors in management of GiST indexes. After installing this update, it is advisable to REINDEX any GiST indexes that meet one or more of the conditions described below.
Also, if you are upgrading from a version earlier than 8.4.10, see Section E.47, Release 8.4.10 .

E.40.2. Changes

Reset OpenSSL randomness state in each postmaster child process (Marko Kreen)
This avoids a scenario wherein random numbers generated by contrib/pgcrypto functions might be relatively easy for
another database user to guess. The risk is only significant when the postmaster is configured with ssl = on but most connections don't use SSL encryption. (CVE-2013-1900)

Fix GiST indexes to not use fuzzy geometric comparisons when it's not appropriate to do so (Alexander Korotkov)
The core geometric types perform comparisons using fuzzy equality, but gist_box_same must do exact comparisons,
else GiST indexes using it might become inconsistent. After installing this update, users should REINDEX any GiST indexes
on box, polygon, circle, or point columns, since all of these use gist_box_same.

Fix erroneous range-union and penalty logic in GiST indexes that use contrib/btree_gist for variable-width data
types, that is text, bytea, bit, and numeric columns (Tom Lane)
These errors could result in inconsistent indexes in which some keys that are present would not be found by searches, and also
in useless index bloat. Users are advised to REINDEX such indexes after installing this update.
1492

Notes de version

Fix bugs in GiST page splitting code for multi-column indexes (Tom Lane)
These errors could result in inconsistent indexes in which some keys that are present would not be found by searches, and also
in indexes that are unnecessarily inefficient to search. Users are advised to REINDEX multi-column GiST indexes after installing this update.

Fix infinite-loop risk in regular expression compilation (Tom Lane, Don Porter)

Fix potential null-pointer dereference in regular expression compilation (Tom Lane)

Fix to_char() to use ASCII-only case-folding rules where appropriate (Tom Lane)
This fixes misbehavior of some template patterns that should be locale-independent, but mishandled I and i in Turkish
locales.

Fix unwanted rejection of timestamp 1999-12-31 24:00:00 (Tom Lane)

Remove useless picksplit doesn't support secondary split log messages (Josh Hansen, Tom Lane)
This message seems to have been added in expectation of code that was never written, and probably never will be, since
GiST's default handling of secondary splits is actually pretty good. So stop nagging end users about it.

Fix possible failure to send a session's last few transaction commit/abort counts to the statistics collector (Tom Lane)

Eliminate memory leaks in PL/Perl's spi_prepare() function (Alex Hunsaker, Tom Lane)

Fix pg_dumpall to handle database names containing = correctly (Heikki Linnakangas)

Avoid crash in pg_dump when an incorrect connection string is given (Heikki Linnakangas)

Ignore invalid indexes in pg_dump (Michael Paquier)


Dumping invalid indexes can cause problems at restore time, for example if the reason the index creation failed was because it
tried to enforce a uniqueness condition not satisfied by the table's data. Also, if the index creation is in fact still in progress, it
seems reasonable to consider it to be an uncommitted DDL change, which pg_dump wouldn't be expected to dump anyway.

Fix contrib/pg_trgm's similarity() function to return zero for trigram-less strings (Tom Lane)
Previously it returned NaN due to internal division by zero.

Update time zone data files to tzdata release 2013b for DST law changes in Chile, Haiti, Morocco, Paraguay, and some Russian areas. Also, historical zone data corrections for numerous places.
Also, update the time zone abbreviation files for recent changes in Russia and elsewhere: CHOT, GET, IRKT, KGT, KRAT,
MAGT, MAWT, MSK, NOVT, OMST, TKT, VLAT, WST, YAKT, YEKT now follow their current meanings, and VOLT
(Europe/Volgograd) and MIST (Antarctica/Macquarie) are added to the default abbreviations list.

E.41. Release 8.4.16


Release Date
2013-02-07
This release contains a variety of fixes from 8.4.15. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.41.1. Migration to Version 8.4.16


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.10, see Section E.47, Release 8.4.10 .

E.41.2. Changes

Prevent execution of enum_recv from SQL (Tom Lane)


The function was misdeclared, allowing a simple SQL command to crash the server. In principle an attacker might be able to
use it to examine the contents of server memory. Our thanks to Sumit Soni (via Secunia SVCRP) for reporting this issue.
(CVE-2013-0255)
1493

Notes de version

Update minimum recovery point when truncating a relation file (Heikki Linnakangas)
Once data has been discarded, it's no longer safe to stop recovery at an earlier point in the timeline.

Fix SQL grammar to allow subscripting or field selection from a sub-SELECT result (Tom Lane)

Protect against race conditions when scanning pg_tablespace (Stephen Frost, Tom Lane)
CREATE DATABASE and DROP DATABASE could misbehave if there were concurrent updates of pg_tablespace entries.

Prevent DROP OWNED from trying to drop whole databases or tablespaces (lvaro Herrera)
For safety, ownership of these objects must be reassigned, not dropped.

Fix error in vacuum_freeze_table_age implementation (Andres Freund)


In installations that have existed for more than vacuum_freeze_min_age transactions, this mistake prevented autovacuum from using partial-table scans, so that a full-table scan would always happen instead.

Prevent misbehavior when a RowExpr or XmlExpr is parse-analyzed twice (Andres Freund, Tom Lane)
This mistake could be user-visible in contexts such as CREATE TABLE LIKE INCLUDING INDEXES.

Improve defenses against integer overflow in hashtable sizing calculations (Jeff Davis)

Reject out-of-range dates in to_date() (Hitoshi Harada)

Ensure that non-ASCII prompt strings are translated to the correct code page on Windows (Alexander Law, Noah Misch)
This bug affected psql and some other client programs.

Fix possible crash in psql's \? command when not connected to a database (Meng Qingzhong)

Fix one-byte buffer overrun in libpq's PQprintTuples (Xi Wang)


This ancient function is not used anywhere by PostgreSQL itself, but it might still be used by some client code.

Make ecpglib use translated messages properly (Chen Huajun)

Properly install ecpg_compat and pgtypes libraries on MSVC (Jiang Guiqing)

Rearrange configure's tests for supplied functions so it is not fooled by bogus exports from libedit/libreadline (Christoph Berg)

Ensure Windows build number increases over time (Magnus Hagander)

Make pgxs build executables with the right .exe suffix when cross-compiling for Windows (Zoltan Boszormenyi)

Add new timezone abbreviation FET (Tom Lane)


This is now used in some eastern-European time zones.

E.42. Release 8.4.15


Release Date
2012-12-06
This release contains a variety of fixes from 8.4.14. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.42.1. Migration to Version 8.4.15


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.10, see Section E.47, Release 8.4.10 .

E.42.2. Changes

Fix multiple bugs associated with CREATE INDEX CONCURRENTLY (Andres Freund, Tom Lane)
Fix CREATE INDEX CONCURRENTLY to use in-place updates when changing the state of an index's pg_index row. This
prevents race conditions that could cause concurrent sessions to miss updating the target index, thus resulting in corrupt
1494

Notes de version

concurrently-created indexes.
Also, fix various other operations to ensure that they ignore invalid indexes resulting from a failed CREATE INDEX
CONCURRENTLY command. The most important of these is VACUUM, because an auto-vacuum could easily be launched
on the table before corrective action can be taken to fix or remove the invalid index.

Avoid corruption of internal hash tables when out of memory (Hitoshi Harada)

Fix planning of non-strict equivalence clauses above outer joins (Tom Lane)
The planner could derive incorrect constraints from a clause equating a non-strict construct to something else, for example
WHERE COALESCE(foo, 0) = 0 when foo is coming from the nullable side of an outer join.

Improve planner's ability to prove exclusion constraints from equivalence classes (Tom Lane)

Fix partial-row matching in hashed subplans to handle cross-type cases correctly (Tom Lane)
This affects multicolumn NOT IN subplans, such as WHERE (a, b) NOT IN (SELECT x, y FROM ...) when for
instance b and y are int4 and int8 respectively. This mistake led to wrong answers or crashes depending on the specific datatypes involved.

Acquire buffer lock when re-fetching the old tuple for an AFTER ROW UPDATE/DELETE trigger (Andres Freund)
In very unusual circumstances, this oversight could result in passing incorrect data to the precheck logic for a foreign-key enforcement trigger. That could result in a crash, or in an incorrect decision about whether to fire the trigger.

Fix ALTER COLUMN TYPE to handle alled check constraints properly (Pavan Deolasee)
This worked correctly in pre-8.4 releases, and now works correctly in 8.4 and later.

Fix REASSIGN OWNED to handle grants on tablespaces (lvaro Herrera)

Ignore incorrect pg_attribute entries for system columns for views (Tom Lane)
Views do not have any system columns. However, we forgot to remove such entries when converting a table to a view. That's
fixed properly for 9.3 and later, but in previous branches we need to defend against existing mis-converted views.

Fix rule printing to dump INSERT INTO table DEFAULT VALUES correctly (Tom Lane)

Guard against stack overflow when there are too many UNION/INTERSECT/EXCEPT clauses in a query (Tom Lane)

Prevent platform-dependent failures when dividing the minimum possible integer value by -1 (Xi Wang, Tom Lane)

Fix possible access past end of string in date parsing (Hitoshi Harada)

Produce an understandable error message if the length of the path name for a Unix-domain socket exceeds the platform-specific limit (Tom Lane, Andrew Dunstan)
Formerly, this would result in something quite unhelpful, such as Non-recoverable failure in name resolution .

Fix memory leaks when sending composite column values to the client (Tom Lane)

Make pg_ctl more robust about reading the postmaster.pid file (Heikki Linnakangas)
Fix race conditions and possible file descriptor leakage.

Fix possible crash in psql if incorrectly-encoded data is presented and the client_encoding setting is a client-only encoding, such as SJIS (Jiang Guiqing)

Fix bugs in the restore.sql script emitted by pg_dump in tar output format (Tom Lane)
The script would fail outright on tables whose names include upper-case characters. Also, make the script capable of restoring
data in --inserts mode as well as the regular COPY mode.

Fix pg_restore to accept POSIX-conformant tar files (Brian Weaver, Tom Lane)
The original coding of pg_dump's tar output mode produced files that are not fully conformant with the POSIX standard.
This has been corrected for version 9.3. This patch updates previous branches so that they will accept both the incorrect and
the corrected formats, in hopes of avoiding compatibility problems when 9.3 comes out.

Fix pg_resetxlog to locate postmaster.pid correctly when given a relative path to the data directory (Tom Lane)
This mistake could lead to pg_resetxlog not noticing that there is an active postmaster using the data directory.

Fix libpq's lo_import() and lo_export() functions to report file I/O errors properly (Tom Lane)

Fix ecpg's processing of nested structure pointer variables (Muhammad Usama)


1495

Notes de version

Make contrib/pageinspect's btree page inspection functions take buffer locks while examining pages (Tom Lane)

Fix pgxs support for building loadable modules on AIX (Tom Lane)
Building modules outside the original source tree didn't work on AIX.

Update time zone data files to tzdata release 2012j for DST law changes in Cuba, Israel, Jordan, Libya, Palestine, Western Samoa, and portions of Brazil.

E.43. Release 8.4.14


Release Date
2012-09-24
This release contains a variety of fixes from 8.4.13. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.43.1. Migration to Version 8.4.14


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.10, see Section E.47, Release 8.4.10 .

E.43.2. Changes

Fix planner's assignment of executor parameters, and fix executor's rescan logic for CTE plan nodes (Tom Lane)
These errors could result in wrong answers from queries that scan the same WITH subquery multiple times.

Improve page-splitting decisions in GiST indexes (Alexander Korotkov, Robert Haas, Tom Lane)
Multi-column GiST indexes might suffer unexpected bloat due to this error.

Fix cascading privilege revoke to stop if privileges are still held (Tom Lane)
If we revoke a grant option from some role X, but X still holds that option via a grant from someone else, we should not recursively revoke the corresponding privilege from role(s) Y that X had granted it to.

Fix handling of SIGFPE when PL/Perl is in use (Andres Freund)


Perl resets the process's SIGFPE handler to SIG_IGN, which could result in crashes later on. Restore the normal Postgres signal handler after initializing PL/Perl.

Prevent PL/Perl from crashing if a recursive PL/Perl function is redefined while being executed (Tom Lane)

Work around possible misoptimization in PL/Perl (Tom Lane)


Some Linux distributions contain an incorrect version of pthread.h that results in incorrect compiled code in PL/Perl, leading to crashes if a PL/Perl function calls another one that throws an error.

Update time zone data files to tzdata release 2012f for DST law changes in Fiji

E.44. Release 8.4.13


Release Date
2012-08-17
This release contains a variety of fixes from 8.4.12. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.44.1. Migration to Version 8.4.13


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.10, see Section E.47, Release 8.4.10 .
1496

Notes de version

E.44.2. Changes

Prevent access to external files/URLs via XML entity references (Noah Misch, Tom Lane)
xml_parse() would attempt to fetch external files or URLs as needed to resolve DTD and entity references in an XML value, thus allowing unprivileged database users to attempt to fetch data with the privileges of the database server. While the external data wouldn't get returned directly to the user, portions of it could be exposed in error messages if the data didn't parse
as valid XML; and in any case the mere ability to check existence of a file might be useful to an attacker. (CVE-2012-3489)

Prevent access to external files/URLs via contrib/xml2's xslt_process() (Peter Eisentraut)


libxslt offers the ability to read and write both files and URLs through stylesheet commands, thus allowing unprivileged database users to both read and write data with the privileges of the database server. Disable that through proper use of libxslt's security options. (CVE-2012-3488)
Also, remove xslt_process()'s ability to fetch documents and stylesheets from external files/URLs. While this was a documented feature , it was long regarded as a bad idea. The fix for CVE-2012-3489 broke that capability, and rather than expend effort on trying to fix it, we're just going to summarily remove it.

Prevent too-early recycling of btree index pages (Noah Misch)


When we allowed read-only transactions to skip assigning XIDs, we introduced the possibility that a deleted btree page could
be recycled while a read-only transaction was still in flight to it. This would result in incorrect index search results. The probability of such an error occurring in the field seems very low because of the timing requirements, but nonetheless it should be
fixed.

Fix crash-safety bug with newly-created-or-reset sequences (Tom Lane)


If ALTER SEQUENCE was executed on a freshly created or reset sequence, and then precisely one nextval() call was
made on it, and then the server crashed, WAL replay would restore the sequence to a state in which it appeared that no nextval() had been done, thus allowing the first sequence value to be returned again by the next nextval() call. In particular
this could manifest for serial columns, since creation of a serial column's sequence includes an ALTER SEQUENCE OWNED BY step.

Ensure the backup_label file is fsync'd after pg_start_backup() (Dave Kerr)

Back-patch 9.1 improvement to compress the fsync request queue (Robert Haas)
This improves performance during checkpoints. The 9.1 change has now seen enough field testing to seem safe to back-patch.

Only allow autovacuum to be auto-canceled by a directly blocked process (Tom Lane)


The original coding could allow inconsistent behavior in some cases; in particular, an autovacuum could get canceled after less
than deadlock_timeout grace period.

Improve logging of autovacuum cancels (Robert Haas)

Fix log collector so that log_truncate_on_rotation works during the very first log rotation after server start (Tom
Lane)

Fix WITH attached to a nested set operation (UNION/INTERSECT/EXCEPT) (Tom Lane)

Ensure that a whole-row reference to a subquery doesn't include any extra GROUP BY or ORDER BY columns (Tom Lane)

Disallow copying whole-row references in CHECK constraints and index definitions during CREATE TABLE (Tom Lane)
This situation can arise in CREATE TABLE with LIKE or INHERITS. The copied whole-row variable was incorrectly labeled with the row type of the original table not the new one. Rejecting the case seems reasonable for LIKE, since the row types
might well diverge later. For INHERITS we should ideally allow it, with an implicit coercion to the parent table's row type;
but that will require more work than seems safe to back-patch.

Fix memory leak in ARRAY(SELECT ...) subqueries (Heikki Linnakangas, Tom Lane)

Fix extraction of common prefixes from regular expressions (Tom Lane)


The code could get confused by quantified parenthesized subexpressions, such as ^(foo)?bar. This would lead to incorrect
index optimization of searches for such patterns.

Fix bugs with parsing signed hh:mm and hh:mm:ss fields in interval constants (Amit Kapila, Tom Lane)

Report errors properly in contrib/xml2's xslt_process() (Tom Lane)

Update time zone data files to tzdata release 2012e for DST law changes in Morocco and Tokelau
1497

Notes de version

E.45. Release 8.4.12


Release Date
2012-06-04
This release contains a variety of fixes from 8.4.11. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.45.1. Migration to Version 8.4.12


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.10, see Section E.47, Release 8.4.10 .

E.45.2. Changes

Fix incorrect password transformation in contrib/pgcrypto's DES crypt() function (Solar Designer)
If a password string contained the byte value 0x80, the remainder of the password was ignored, causing the password to be
much weaker than it appeared. With this fix, the rest of the string is properly included in the DES hash. Any stored password
values that are affected by this bug will thus no longer match, so the stored values may need to be updated. (CVE-2012-2143)

Ignore SECURITY DEFINER and SET attributes for a procedural language's call handler (Tom Lane)
Applying such attributes to a call handler could crash the server. (CVE-2012-2655)

Allow numeric timezone offsets in timestamp input to be up to 16 hours away from UTC (Tom Lane)
Some historical time zones have offsets larger than 15 hours, the previous limit. This could result in dumped data values being
rejected during reload.

Fix timestamp conversion to cope when the given time is exactly the last DST transition time for the current timezone (Tom
Lane)
This oversight has been there a long time, but was not noticed previously because most DST-using zones are presumed to have
an indefinite sequence of future DST transitions.

Fix text to name and char to name casts to perform string truncation correctly in multibyte encodings (Karl Schnaitter)

Fix memory copying bug in to_tsquery() (Heikki Linnakangas)

Fix planner's handling of outer PlaceHolderVars within subqueries (Tom Lane)


This bug concerns sub-SELECTs that reference variables coming from the nullable side of an outer join of the surrounding
query. In 9.1, queries affected by this bug would fail with ERROR: Upper-level PlaceHolderVar found where not
expected . But in 9.0 and 8.4, you'd silently get possibly-wrong answers, since the value transmitted into the subquery
wouldn't go to null when it should.

Fix slow session startup when pg_attribute is very large (Tom Lane)
If pg_attribute exceeds one-fourth of shared_buffers, cache rebuilding code that is sometimes needed during session
start would trigger the synchronized-scan logic, causing it to take many times longer than normal. The problem was particularly acute if many new sessions were starting at once.

Ensure sequential scans check for query cancel reasonably often (Merlin Moncure)
A scan encountering many consecutive pages that contain no live tuples would not respond to interrupts meanwhile.

Ensure the Windows implementation of PGSemaphoreLock() clears ImmediateInterruptOK before returning (Tom
Lane)
This oversight meant that a query-cancel interrupt received later in the same query could be accepted at an unsafe time, with
unpredictable but not good consequences.

Show whole-row variables safely when printing views or rules (Abbas Butt, Tom Lane)
Corner cases involving ambiguous names (that is, the name could be either a table or column name of the query) were printed
in an ambiguous way, risking that the view or rule would be interpreted differently after dump and reload. Avoid the ambiguous case by attaching a no-op cast.
1498

Notes de version

Fix COPY FROM to properly handle null marker strings that correspond to invalid encoding (Tom Lane)
A null marker string such as E'\\0' should work, and did work in the past, but the case got broken in 8.4.

Ensure autovacuum worker processes perform stack depth checking properly (Heikki Linnakangas)
Previously, infinite recursion in a function invoked by auto-ANALYZE could crash worker processes.

Fix logging collector to not lose log coherency under high load (Andrew Dunstan)
The collector previously could fail to reassemble large messages if it got too busy.

Fix logging collector to ensure it will restart file rotation after receiving SIGHUP (Tom Lane)

Fix WAL replay logic for GIN indexes to not fail if the index was subsequently dropped (Tom Lane)

Fix memory leak in PL/pgSQL's RETURN NEXT command (Joe Conway)

Fix PL/pgSQL's GET DIAGNOSTICS command when the target is the function's first variable (Tom Lane)

Fix potential access off the end of memory in psql's expanded display (\x) mode (Peter Eisentraut)

Fix several performance problems in pg_dump when the database contains many objects (Jeff Janes, Tom Lane)
pg_dump could get very slow if the database contained many schemas, or if many objects are in dependency loops, or if there
are many owned sequences.

Fix contrib/dblink's dblink_exec() to not leak temporary database connections upon error (Tom Lane)

Fix contrib/dblink to report the correct connection name in error messages (Kyotaro Horiguchi)

Update time zone data files to tzdata release 2012c for DST law changes in Antarctica, Armenia, Chile, Cuba, Falkland Islands, Gaza, Haiti, Hebron, Morocco, Syria, and Tokelau Islands; also historical corrections for Canada.

E.46. Release 8.4.11


Release Date
2012-02-27
This release contains a variety of fixes from 8.4.10. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.46.1. Migration to Version 8.4.11


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.10, see Section E.47, Release 8.4.10 .

E.46.2. Changes

Require execute permission on the trigger function for CREATE TRIGGER (Robert Haas)
This missing check could allow another user to execute a trigger function with forged input data, by installing it on a table he
owns. This is only of significance for trigger functions marked SECURITY DEFINER, since otherwise trigger functions run
as the table owner anyway. (CVE-2012-0866)

Remove arbitrary limitation on length of common name in SSL certificates (Heikki Linnakangas)
Both libpq and the server truncated the common name extracted from an SSL certificate at 32 bytes. Normally this would
cause nothing worse than an unexpected verification failure, but there are some rather-implausible scenarios in which it might
allow one certificate holder to impersonate another. The victim would have to have a common name exactly 32 bytes long, and
the attacker would have to persuade a trusted CA to issue a certificate in which the common name has that string as a prefix.
Impersonating a server would also require some additional exploit to redirect client connections. (CVE-2012-0867)

Convert newlines to spaces in names written in pg_dump comments (Robert Haas)


pg_dump was incautious about sanitizing object names that are emitted within SQL comments in its output script. A name
containing a newline would at least render the script syntactically incorrect. Maliciously crafted object names could present a
SQL injection risk when the script is reloaded. (CVE-2012-0868)
1499

Notes de version

Fix btree index corruption from insertions concurrent with vacuuming (Tom Lane)
An index page split caused by an insertion could sometimes cause a concurrently-running VACUUM to miss removing index
entries that it should remove. After the corresponding table rows are removed, the dangling index entries would cause errors
(such as could not read block N in file ... ) or worse, silently wrong query results after unrelated rows are re-inserted at the
now-free table locations. This bug has been present since release 8.2, but occurs so infrequently that it was not diagnosed until
now. If you have reason to suspect that it has happened in your database, reindexing the affected index will fix things.

Update per-column permissions, not only per-table permissions, when changing table owner (Tom Lane)
Failure to do this meant that any previously granted column permissions were still shown as having been granted by the old
owner. This meant that neither the new owner nor a superuser could revoke the now-untraceable-to-table-owner permissions.

Allow non-existent values for some settings in ALTER USER/DATABASE SET (Heikki Linnakangas)
Allow default_text_search_config, default_tablespace, and temp_tablespaces to be set to names that
are not known. This is because they might be known in another database where the setting is intended to be used, or for the tablespace cases because the tablespace might not be created yet. The same issue was previously recognized for
search_path, and these settings now act like that one.

Avoid crashing when we have problems deleting table files post-commit (Tom Lane)
Dropping a table should lead to deleting the underlying disk files only after the transaction commits. In event of failure then
(for instance, because of wrong file permissions) the code is supposed to just emit a warning message and go on, since it's too
late to abort the transaction. This logic got broken as of release 8.4, causing such situations to result in a PANIC and an unrestartable database.

Track the OID counter correctly during WAL replay, even when it wraps around (Tom Lane)
Previously the OID counter would remain stuck at a high value until the system exited replay mode. The practical consequences of that are usually nil, but there are scenarios wherein a standby server that's been promoted to master might take a
long time to advance the OID counter to a reasonable value once values are needed.

Fix regular expression back-references with * attached (Tom Lane)


Rather than enforcing an exact string match, the code would effectively accept any string that satisfies the pattern subexpression referenced by the back-reference symbol.
A similar problem still afflicts back-references that are embedded in a larger quantified expression, rather than being the immediate subject of the quantifier. This will be addressed in a future PostgreSQL release.

Fix recently-introduced memory leak in processing of inet/cidr values (Heikki Linnakangas)


A patch in the December 2011 releases of PostgreSQL caused memory leakage in these operations, which could be significant in scenarios such as building a btree index on such a column.

Fix dangling pointer after CREATE TABLE AS/SELECT INTO in a SQL-language function (Tom Lane)
In most cases this only led to an assertion failure in assert-enabled builds, but worse consequences seem possible.

Avoid double close of file handle in syslogger on Windows (MauMau)


Ordinarily this error was invisible, but it would cause an exception when running on a debug version of Windows.

Fix I/O-conversion-related memory leaks in plpgsql (Andres Freund, Jan Urbanski, Tom Lane)
Certain operations would leak memory until the end of the current function.

Improve pg_dump's handling of alled table columns (Tom Lane)


pg_dump mishandled situations where a child column has a different default expression than its parent column. If the default is
textually identical to the parent's default, but not actually the same (for instance, because of schema search path differences) it
would not be recognized as different, so that after dump and restore the child would be allowed to all the parent's default.
Child columns that are NOT NULL where their parent is not could also be restored subtly incorrectly.

Fix pg_restore's direct-to-database mode for INSERT-style table data (Tom Lane)
Direct-to-database restores from archive files made with --inserts or --column-inserts options fail when using
pg_restore from a release dated September or December 2011, as a result of an oversight in a fix for another problem. The archive file itself is not at fault, and text-mode output is okay.

Allow AT option in ecpg DEALLOCATE statements (Michael Meskes)


The infrastructure to support this has been there for awhile, but through an oversight there was still an error check rejecting the
1500

Notes de version

case.

Fix error in contrib/intarray's int[] & int[] operator (Guillaume Lelarge)


If the smallest integer the two input arrays have in common is 1, and there are smaller values in either array, then 1 would be
incorrectly omitted from the result.

Fix error detection in contrib/pgcrypto's encrypt_iv() and decrypt_iv() (Marko Kreen)


These functions failed to report certain types of invalid-input errors, and would instead return random garbage values for incorrect input.

Fix one-byte buffer overrun in contrib/test_parser (Paul Guyot)


The code would try to read one more byte than it should, which would crash in corner cases. Since contrib/
test_parser is only example code, this is not a security issue in itself, but bad example code is still bad.

Use __sync_lock_test_and_set() for spinlocks on ARM, if available (Martin Pitt)


This function replaces our previous use of the SWPB instruction, which is deprecated and not available on ARMv6 and later.
Reports suggest that the old code doesn't fail in an obvious way on recent ARM boards, but simply doesn't interlock concurrent accesses, leading to bizarre failures in multiprocess operation.

Use -fexcess-precision=standard option when building with gcc versions that accept it (Andrew Dunstan)
This prevents assorted scenarios wherein recent versions of gcc will produce creative results.

Allow use of threaded Python on FreeBSD (Chris Rees)


Our configure script previously believed that this combination wouldn't work; but FreeBSD fixed the problem, so remove that
error check.

E.47. Release 8.4.10


Release Date
2011-12-05
This release contains a variety of fixes from 8.4.9. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.47.1. Migration to Version 8.4.10


A dump/restore is not required for those running 8.4.X.
However,
a
longstanding
error
was
discovered
in
the
definition
of
the
information_schema.referential_constraints view. If you rely on correct results from that view, you should replace its definition as explained in the first changelog item below.
Also, if you are upgrading from a version earlier than 8.4.8, see Section E.49, Release 8.4.8 .

E.47.2. Changes

Fix bugs in information_schema.referential_constraints view (Tom Lane)


This view was being insufficiently careful about matching the foreign-key constraint to the depended-on primary or unique
key constraint. That could result in failure to show a foreign key constraint at all, or showing it multiple times, or claiming that
it depends on a different constraint than the one it really does.
Since the view definition is installed by initdb, merely upgrading will not fix the problem. If you need to fix this in an existing
installation, you can (as a superuser) drop the information_schema schema then re-create it by sourcing SHAREDIR/
information_schema.sql. (Run pg_config --sharedir if you're uncertain where SHAREDIR is.) This must be
repeated in each database to be fixed.

Fix incorrect replay of WAL records for GIN index updates (Tom Lane)
This could result in transiently failing to find index entries after a crash, or on a hot-standby server. The problem would be repaired by the next VACUUM of the index, however.
1501

Notes de version

Fix TOAST-related data corruption during CREATE TABLE dest AS SELECT * FROM src or INSERT INTO
dest SELECT * FROM src (Tom Lane)
If a table has been modified by ALTER TABLE ADD COLUMN, attempts to copy its data verbatim to another table could
produce corrupt results in certain corner cases. The problem can only manifest in this precise form in 8.4 and later, but we patched earlier versions as well in case there are other code paths that could trigger the same bug.

Fix race condition during toast table access from stale syscache entries (Tom Lane)
The typical symptom was transient errors like missing chunk number 0 for toast value NNNNN in pg_toast_2619 , where
the cited toast table would always belong to a system catalog.

Track dependencies of functions on items used in parameter default expressions (Tom Lane)
Previously, a referenced object could be dropped without having dropped or modified the function, leading to misbehavior
when the function was used. Note that merely installing this update will not fix the missing dependency entries; to do that,
you'd need to CREATE OR REPLACE each such function afterwards. If you have functions whose defaults depend on nonbuilt-in objects, doing so is recommended.

Allow inlining of set-returning SQL functions with multiple OUT parameters (Tom Lane)

Make DatumGetInetP() unpack inet datums that have a 1-byte header, and add a new macro, DatumGetInetPP(),
that does not (Heikki Linnakangas)
This change affects no core code, but might prevent crashes in add-on code that expects DatumGetInetP() to produce an
unpacked datum as per usual convention.

Improve locale support in money type's input and output (Tom Lane)
Aside from not supporting all standard lc_monetary formatting options, the input and output functions were inconsistent,
meaning there were locales in which dumped money values could not be re-read.

Don't let transform_null_equals affect CASE foo WHEN NULL ... constructs (Heikki Linnakangas)
transform_null_equals is only supposed to affect foo = NULL expressions written directly by the user, not equality
checks generated internally by this form of CASE.

Change foreign-key trigger creation order to better support self-referential foreign keys (Tom Lane)
For a cascading foreign key that references its own table, a row update will fire both the ON UPDATE trigger and the CHECK
trigger as one event. The ON UPDATE trigger must execute first, else the CHECK will check a non-final state of the row and
possibly throw an inappropriate error. However, the firing order of these triggers is determined by their names, which generally sort in creation order since the triggers have auto-generated names following the convention
RI_ConstraintTrigger_NNNN . A proper fix would require modifying that convention, which we will do in 9.2, but it
seems risky to change it in existing releases. So this patch just changes the creation order of the triggers. Users encountering
this type of error should drop and re-create the foreign key constraint to get its triggers into the right order.

Avoid floating-point underflow while tracking buffer allocation rate (Greg Matthews)
While harmless in itself, on certain platforms this would result in annoying kernel log messages.

Preserve configuration file name and line number values when starting child processes under Windows (Tom Lane)
Formerly, these would not be displayed correctly in the pg_settings view.

Preserve blank lines within commands in psql's command history (Robert Haas)
The former behavior could cause problems if an empty line was removed from within a string literal, for example.

Fix pg_dump to dump user-defined casts between auto-generated types, such as table rowtypes (Tom Lane)

Use the preferred version of xsubpp to build PL/Perl, not necessarily the operating system's main copy (David Wheeler and
Alex Hunsaker)

Fix incorrect coding in contrib/dict_int and contrib/dict_xsyn (Tom Lane)


Some functions incorrectly assumed that memory returned by palloc() is guaranteed zeroed.

Honor query cancel interrupts promptly in pgstatindex() (Robert Haas)

Ensure VPATH builds properly install all server header files (Peter Eisentraut)

Shorten file names reported in verbose error messages (Peter Eisentraut)


Regular builds have always reported just the name of the C file containing the error message call, but VPATH builds formerly
1502

Notes de version

reported an absolute path name.

Fix interpretation of Windows timezone names for Central America (Tom Lane)
Map Central America Standard Time to CST6, not CST6CDT, because DST is generally not observed anywhere in Central
America.

Update time zone data files to tzdata release 2011n for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa;
also historical corrections for Alaska and British East Africa.

E.48. Release 8.4.9


Release Date
2011-09-26
This release contains a variety of fixes from 8.4.8. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.48.1. Migration to Version 8.4.9


A dump/restore is not required for those running 8.4.X.
However, if you are upgrading from a version earlier than 8.4.8, see Section E.49, Release 8.4.8 .

E.48.2. Changes

Fix bugs in indexing of in-doubt HOT-updated tuples (Tom Lane)


These bugs could result in index corruption after reindexing a system catalog. They are not believed to affect user indexes.

Fix multiple bugs in GiST index page split processing (Heikki Linnakangas)
The probability of occurrence was low, but these could lead to index corruption.

Fix possible buffer overrun in tsvector_concat() (Tom Lane)


The function could underestimate the amount of memory needed for its result, leading to server crashes.

Fix crash in xml_recv when processing a standalone parameter (Tom Lane)

Make pg_options_to_table return NULL for an option with no value (Tom Lane)
Previously such cases would result in a server crash.

Avoid possibly accessing off the end of memory in ANALYZE and in SJIS-2004 encoding conversion (Noah Misch)
This fixes some very-low-probability server crash scenarios.

Prevent intermittent hang in interactions of startup process with bgwriter process (Simon Riggs)
This affected recovery in non-hot-standby cases.

Fix race condition in relcache init file invalidation (Tom Lane)


There was a window wherein a new backend process could read a stale init file but miss the inval messages that would tell it
the data is stale. The result would be bizarre failures in catalog accesses, typically could not read block 0 in file ... later during startup.

Fix memory leak at end of a GiST index scan (Tom Lane)


Commands that perform many separate GiST index scans, such as verification of a new GiST-based exclusion constraint on a
table already containing many rows, could transiently require large amounts of memory due to this leak.

Fix incorrect memory accounting (leading to possible memory bloat) in tuplestores supporting holdable cursors and plpgsql's
RETURN NEXT command (Tom Lane)

Fix performance problem when constructing a large, lossy bitmap (Tom Lane)

Fix join selectivity estimation for unique columns (Tom Lane)


1503

Notes de version

This fixes an erroneous planner heuristic that could lead to poor estimates of the result size of a join.

Fix nested PlaceHolderVar expressions that appear only in sub-select target lists (Tom Lane)
This mistake could result in outputs of an outer join incorrectly appearing as NULL.

Allow nested EXISTS queries to be optimized properly (Tom Lane)

Fix array- and path-creating functions to ensure padding bytes are zeroes (Tom Lane)
This avoids some situations where the planner will think that semantically-equal constants are not equal, resulting in poor optimization.

Fix EXPLAIN to handle gating Result nodes within inner-indexscan subplans (Tom Lane)
The usual symptom of this oversight was bogus varno errors.

Work around gcc 4.6.0 bug that breaks WAL replay (Tom Lane)
This could lead to loss of committed transactions after a server crash.

Fix dump bug for VALUES in a view (Tom Lane)

Disallow SELECT FOR UPDATE/SHARE on sequences (Tom Lane)


This operation doesn't work as expected and can lead to failures.

Fix VACUUM so that it always updates pg_class.reltuples/relpages (Tom Lane)


This fixes some scenarios where autovacuum could make increasingly poor decisions about when to vacuum tables.

Defend against integer overflow when computing size of a hash table (Tom Lane)

Fix cases where CLUSTER might attempt to access already-removed TOAST data (Tom Lane)

Fix portability bugs in use of credentials control messages for peer authentication (Tom Lane)

Fix SSPI login when multiple roundtrips are required (Ahmed Shinwari, Magnus Hagander)
The typical symptom of this problem was The function requested is not supported errors during SSPI login.

Throw an error if pg_hba.conf contains hostssl but SSL is disabled (Tom Lane)
This was concluded to be more user-friendly than the previous behavior of silently ignoring such lines.

Fix typo in pg_srand48 seed initialization (Andres Freund)


This led to failure to use all bits of the provided seed. This function is not used on most platforms (only those without srandom), and the potential security exposure from a less-random-than-expected seed seems minimal in any case.

Avoid integer overflow when the sum of LIMIT and OFFSET values exceeds 2^63 (Heikki Linnakangas)

Add overflow checks to int4 and int8 versions of generate_series() (Robert Haas)

Fix trailing-zero removal in to_char() (Marti Raudsepp)


In a format with FM and no digit positions after the decimal point, zeroes to the left of the decimal point could be removed incorrectly.

Fix pg_size_pretty() to avoid overflow for inputs close to 2^63 (Tom Lane)

Weaken plpgsql's check for typmod matching in record values (Tom Lane)
An overly enthusiastic check could lead to discarding length modifiers that should have been kept.

Correctly handle quotes in locale names during initdb (Heikki Linnakangas)


The case can arise with some Windows locales, such as People's Republic of China .

Fix pg_upgrade to preserve toast tables' relfrozenxids during an upgrade from 8.3 (Bruce Momjian)
Failure to do this could lead to pg_clog files being removed too soon after the upgrade.

In pg_ctl, support silent mode for service registrations on Windows (MauMau)

Fix psql's counting of script file line numbers during COPY from a different file (Tom Lane)

Fix pg_restore's direct-to-database mode for standard_conforming_strings (Tom Lane)


1504

Notes de version

pg_restore could emit incorrect commands when restoring directly to a database server from an archive file that had been
made with standard_conforming_strings set to on.

Be more user-friendly about unsupported cases for parallel pg_restore (Tom Lane)
This change ensures that such cases are detected and reported before any restore actions have been taken.

Fix write-past-buffer-end and memory leak in libpq's LDAP service lookup code (Albe Laurenz)

In libpq, avoid failures when using nonblocking I/O and an SSL connection (Martin Pihlak, Tom Lane)

Improve libpq's handling of failures during connection startup (Tom Lane)


In particular, the response to a server report of fork() failure during SSL connection startup is now saner.

Improve libpq's error reporting for SSL failures (Tom Lane)

Fix PQsetvalue() to avoid possible crash when adding a new tuple to a PGresult originally obtained from a server query
(Andrew Chernow)

Make ecpglib write double values with 15 digits precision (Akira Kurosawa)

In ecpglib, be sure LC_NUMERIC setting is restored after an error (Michael Meskes)

Apply upstream fix for blowfish signed-character bug (CVE-2011-2483) (Tom Lane)
contrib/pg_crypto's blowfish encryption code could give wrong results on platforms where char is signed (which is
most), leading to encrypted passwords being weaker than they should be.

Fix memory leak in contrib/seg (Heikki Linnakangas)

Fix pgstatindex() to give consistent results for empty indexes (Tom Lane)

Allow building with perl 5.14 (Alex Hunsaker)

Update configure script's method for probing existence of system functions (Tom Lane)
The version of autoconf we used in 8.3 and 8.2 could be fooled by compilers that perform link-time optimization.

Fix assorted issues with build and install file paths containing spaces (Tom Lane)

Update time zone data files to tzdata release 2011i for DST law changes in Canada, Egypt, Russia, Samoa, and South Sudan.

E.49. Release 8.4.8


Release Date
2011-04-18
This release contains a variety of fixes from 8.4.7. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.49.1. Migration to Version 8.4.8


A dump/restore is not required for those running 8.4.X.
However, if your installation was upgraded from a previous major release by running pg_upgrade, you should take action to
prevent possible data loss due to a now-fixed bug in pg_upgrade. The recommended solution is to run VACUUM FREEZE on all
TOAST tables. More information is available at http://wiki.postgresql.org/wiki/20110408pg_upgrade_fix.
Also, if you are upgrading from a version earlier than 8.4.2, see Section E.55, Release 8.4.2 .

E.49.2. Changes

Fix pg_upgrade's handling of TOAST tables (Bruce Momjian)


The pg_class.relfrozenxid value for TOAST tables was not correctly copied into the new installation during pg_upgrade.
This could later result in pg_clog files being discarded while they were still needed to validate tuples in the TOAST tables,
leading to could not access status of transaction failures.

1505

Notes de version

This error poses a significant risk of data loss for installations that have been upgraded with pg_upgrade. This patch corrects
the problem for future uses of pg_upgrade, but does not in itself cure the issue in installations that have been processed with a
buggy version of pg_upgrade.

Suppress incorrect PD_ALL_VISIBLE flag was incorrectly set warning (Heikki Linnakangas)
VACUUM would sometimes issue this warning in cases that are actually valid.

Disallow including a composite type in itself (Tom Lane)


This prevents scenarios wherein the server could recurse infinitely while processing the composite type. While there are some
possible uses for such a structure, they don't seem compelling enough to justify the effort required to make sure it always
works safely.

Avoid potential deadlock during catalog cache initialization (Nikhil Sontakke)


In some cases the cache loading code would acquire share lock on a system index before locking the index's catalog. This
could deadlock against processes trying to acquire exclusive locks in the other, more standard order.

Fix dangling-pointer problem in BEFORE ROW UPDATE trigger handling when there was a concurrent update to the target
tuple (Tom Lane)
This bug has been observed to result in intermittent cannot extract system attribute from virtual tuple failures while trying
to do UPDATE RETURNING ctid. There is a very small probability of more serious errors, such as generating incorrect index entries for the updated tuple.

Disallow DROP TABLE when there are pending deferred trigger events for the table (Tom Lane)
Formerly the DROP would go through, leading to could not open relation with OID nnn errors when the triggers were
eventually fired.

Prevent crash triggered by constant-false WHERE conditions during GEQO optimization (Tom Lane)

Improve planner's handling of semi-join and anti-join cases (Tom Lane)

Fix selectivity estimation for text search to account for NULLs (Jesper Krogh)

Improve PL/pgSQL's ability to handle row types with dropped columns (Pavel Stehule)
This is a back-patch of fixes previously made in 9.0.

Fix PL/Python memory leak involving array slices (Daniel Popowich)

Fix pg_restore to cope with long lines (over 1KB) in TOC files (Tom Lane)

Put in more safeguards against crashing due to division-by-zero with overly enthusiastic compiler optimization (Aurelien Jarno)

Support use of dlopen() in FreeBSD and OpenBSD on MIPS (Tom Lane)


There was a hard-wired assumption that this system function was not available on MIPS hardware on these systems. Use a
compile-time test instead, since more recent versions have it.

Fix compilation failures on HP-UX (Heikki Linnakangas)

Fix version-incompatibility problem with libintl on Windows (Hiroshi Inoue)

Fix usage of xcopy in Windows build scripts to work correctly under Windows 7 (Andrew Dunstan)
This affects the build scripts only, not installation or usage.

Fix path separator used by pg_regress on Cygwin (Andrew Dunstan)

Update time zone data files to tzdata release 2011f for DST law changes in Chile, Cuba, Falkland Islands, Morocco, Samoa,
and Turkey; also historical corrections for South Australia, Alaska, and Hawaii.

E.50. Release 8.4.7


Release Date
2011-01-31
1506

Notes de version

This release contains a variety of fixes from 8.4.6. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.50.1. Migration to Version 8.4.7


A dump/restore is not required for those running 8.4.X. However, if you are upgrading from a version earlier than 8.4.2, see Section E.55, Release 8.4.2 .

E.50.2. Changes

Avoid failures when EXPLAIN tries to display a simple-form CASE expression (Tom Lane)
If the CASE's test expression was a constant, the planner could simplify the CASE into a form that confused the expression-display code, resulting in unexpected CASE WHEN clause errors.

Fix assignment to an array slice that is before the existing range of subscripts (Tom Lane)
If there was a gap between the newly added subscripts and the first pre-existing subscript, the code miscalculated how many
entries needed to be copied from the old array's null bitmap, potentially leading to data corruption or crash.

Avoid unexpected conversion overflow in planner for very distant date values (Tom Lane)
The date type supports a wider range of dates than can be represented by the timestamp types, but the planner assumed it could
always convert a date to timestamp with impunity.

Fix pg_restore's text output for large objects (BLOBs) when standard_conforming_strings is on (Tom Lane)
Although restoring directly to a database worked correctly, string escaping was incorrect if pg_restore was asked for SQL text
output and standard_conforming_strings had been enabled in the source database.

Fix erroneous parsing of tsquery values containing ... & !(subexpression) | ... (Tom Lane)
Queries containing this combination of operators were not executed correctly. The same error existed in contrib/intarray's query_int type and contrib/ltree's ltxtquery type.

Fix buffer overrun in contrib/intarray's input function for the query_int type (Apple)
This bug is a security risk since the function's return address could be overwritten. Thanks to Apple Inc's security team for reporting this issue and supplying the fix. (CVE-2010-4015)

Fix bug in contrib/seg's GiST picksplit algorithm (Alexander Korotkov)


This could result in considerable inefficiency, though not actually incorrect answers, in a GiST index on a seg column. If you
have such an index, consider REINDEXing it after installing this update. (This is identical to the bug that was fixed in
contrib/cube in the previous update.)

E.51. Release 8.4.6


Release Date
2010-12-16
This release contains a variety of fixes from 8.4.5. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.51.1. Migration to Version 8.4.6


A dump/restore is not required for those running 8.4.X. However, if you are upgrading from a version earlier than 8.4.2, see Section E.55, Release 8.4.2 .

E.51.2. Changes

Force the default wal_sync_method to be fdatasync on Linux (Tom Lane, Marti Raudsepp)
The default on Linux has actually been fdatasync for many years, but recent kernel changes caused PostgreSQL to
choose open_datasync instead. This choice did not result in any performance improvement, and caused outright failures
on certain filesystems, notably ext4 with the data=journal mount option.
1507

Notes de version

Fix assorted bugs in WAL replay logic for GIN indexes (Tom Lane)
This could result in bad buffer id: 0 failures or corruption of index contents during replication.

Fix recovery from base backup when the starting checkpoint WAL record is not in the same WAL segment as its redo point
(Jeff Davis)

Fix persistent slowdown of autovacuum workers when multiple workers remain active for a long time (Tom Lane)
The effective vacuum_cost_limit for an autovacuum worker could drop to nearly zero if it processed enough tables, causing it to run extremely slowly.

Add support for detecting register-stack overrun on IA64 (Tom Lane)


The IA64 architecture has two hardware stacks. Full prevention of stack-overrun failures requires checking both.

Add a check for stack overflow in copyObject() (Tom Lane)


Certain code paths could crash due to stack overflow given a sufficiently complex query.

Fix detection of page splits in temporary GiST indexes (Heikki Linnakangas)


It is possible to have a concurrent page split in a temporary index, if for example there is an open cursor scanning the index
when an insertion is done. GiST failed to detect this case and hence could deliver wrong results when execution of the cursor
continued.

Fix error checking during early connection processing (Tom Lane)


The check for too many child processes was skipped in some cases, possibly leading to postmaster crash when attempting to
add the new child process to fixed-size arrays.

Improve efficiency of window functions (Tom Lane)


Certain cases where a large number of tuples needed to be read in advance, but work_mem was large enough to allow them all
to be held in memory, were unexpectedly slow. percent_rank(), cume_dist() and ntile() in particular were subject to this problem.

Avoid memory leakage while ANALYZE'ing complex index expressions (Tom Lane)

Ensure an index that uses a whole-row Var still depends on its table (Tom Lane)
An index declared like create index i on t (foo(t.*)) would not automatically get dropped when its table was
dropped.

Do not inline a SQL function with multiple OUT parameters (Tom Lane)
This avoids a possible crash due to loss of information about the expected result rowtype.

Behave correctly if ORDER BY, LIMIT, FOR UPDATE, or WITH is attached to the VALUES part of INSERT ... VALUES
(Tom Lane)

Fix constant-folding of COALESCE() expressions (Tom Lane)


The planner would sometimes attempt to evaluate sub-expressions that in fact could never be reached, possibly leading to
unexpected errors.

Fix postmaster crash when connection acceptance (accept() or one of the calls made immediately after it) fails, and the
postmaster was compiled with GSSAPI support (Alexander Chernikov)

Fix missed unlink of temporary files when log_temp_files is active (Tom Lane)
If an error occurred while attempting to emit the log message, the unlink was not done, resulting in accumulation of temp files.

Add print functionality for InhRelation nodes (Tom Lane)


This avoids a failure when debug_print_parse is enabled and certain types of query are executed.

Fix incorrect calculation of distance from a point to a horizontal line segment (Tom Lane)
This bug affected several different geometric distance-measurement operators.

Fix incorrect calculation of transaction status in ecpg (Itagaki Takahiro)

Fix PL/pgSQL's handling of simple expressions to not fail in recursion or error-recovery cases (Tom Lane)

Fix PL/Python's handling of set-returning functions (Jan Urbanski)

1508

Notes de version

Attempts to call SPI functions within the iterator generating a set result would fail.

Fix bug in contrib/cube's GiST picksplit algorithm (Alexander Korotkov)


This could result in considerable inefficiency, though not actually incorrect answers, in a GiST index on a cube column. If you
have such an index, consider REINDEXing it after installing this update.

Don't emit identifier will be truncated notices in contrib/dblink except when creating new connections (Itagaki Takahiro)

Fix potential coredump on missing public key in contrib/pgcrypto (Marti Raudsepp)

Fix memory leak in contrib/xml2's XPath query functions (Tom Lane)

Update time zone data files to tzdata release 2010o for DST law changes in Fiji and Samoa; also historical corrections for
Hong Kong.

E.52. Release 8.4.5


Release Date
2010-10-04
This release contains a variety of fixes from 8.4.4. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.52.1. Migration to Version 8.4.5


A dump/restore is not required for those running 8.4.X. However, if you are upgrading from a version earlier than 8.4.2, see Section E.55, Release 8.4.2 .

E.52.2. Changes

Use a separate interpreter for each calling SQL userid in PL/Perl and PL/Tcl (Tom Lane)
This change prevents security problems that can be caused by subverting Perl or Tcl code that will be executed later in the
same session under another SQL user identity (for example, within a SECURITY DEFINER function). Most scripting languages offer numerous ways that that might be done, such as redefining standard functions or operators called by the target
function. Without this change, any SQL user with Perl or Tcl language usage rights can do essentially anything with the SQL
privileges of the target function's owner.
The cost of this change is that intentional communication among Perl and Tcl functions becomes more difficult. To provide an
escape hatch, PL/PerlU and PL/TclU functions continue to use only one interpreter per session. This is not considered a security issue since all such functions execute at the trust level of a database superuser already.
It is likely that third-party procedural languages that claim to offer trusted execution have similar security issues. We advise
contacting the authors of any PL you are depending on for security-critical purposes.
Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433).

Prevent possible crashes in pg_get_expr() by disallowing it from being called with an argument that is not one of the system catalog columns it's intended to be used with (Heikki Linnakangas, Tom Lane)

Treat exit code 128 (ERROR_WAIT_NO_CHILDREN) as non-fatal on Windows (Magnus Hagander)


Under high load, Windows processes will sometimes fail at startup with this error code. Formerly the postmaster treated this as
a panic condition and restarted the whole database, but that seems to be an overreaction.

Fix incorrect placement of placeholder evaluation (Tom Lane)


This bug could result in query outputs being non-null when they should be null, in cases where the inner side of an outer join
is a sub-select with non-strict expressions in its output list.

Fix possible duplicate scans of UNION ALL member relations (Tom Lane)

Fix cannot handle unplanned sub-select error (Tom Lane)


This occurred when a sub-select contains a join alias reference that expands into an expression containing another sub-select.
1509

Notes de version

Fix mishandling of whole-row Vars that reference a view or sub-select and appear within a nested sub-select (Tom Lane)

Fix mishandling of cross-type IN comparisons (Tom Lane)


This could result in failures if the planner tried to implement an IN join with a sort-then-unique-then-plain-join plan.

Fix computation of ANALYZE statistics for tsvector columns (Jan Urbanski)


The original coding could produce incorrect statistics, leading to poor plan choices later.

Improve planner's estimate of memory used by array_agg(), string_agg(), and similar aggregate functions (Hitoshi
Harada)
The previous drastic underestimate could lead to out-of-memory failures due to inappropriate choice of a hash-aggregation
plan.

Fix failure to mark cached plans as transient (Tom Lane)


If a plan is prepared while CREATE INDEX CONCURRENTLY is in progress for one of the referenced tables, it is supposed to be re-planned once the index is ready for use. This was not happening reliably.

Reduce PANIC to ERROR in some occasionally-reported btree failure cases, and provide additional detail in the resulting error messages (Tom Lane)
This should improve the system's robustness with corrupted indexes.

Fix incorrect search logic for partial-match queries with GIN indexes (Tom Lane)
Cases involving AND/OR combination of several GIN index conditions didn't always give the right answer, and were sometimes much slower than necessary.

Prevent show_session_authorization() from crashing within autovacuum processes (Tom Lane)

Defend against functions returning setof record where not all the returned rows are actually of the same rowtype (Tom Lane)

Fix possible corruption of pending trigger event lists during subtransaction rollback (Tom Lane)
This could lead to a crash or incorrect firing of triggers.

Fix possible failure when hashing a pass-by-reference function result (Tao Ma, Tom Lane)

Improve merge join's handling of NULLs in the join columns (Tom Lane)
A merge join can now stop entirely upon reaching the first NULL, if the sort order is such that NULLs sort high.

Take care to fsync the contents of lockfiles (both postmaster.pid and the socket lockfile) while writing them (Tom Lane)
This omission could result in corrupted lockfile contents if the machine crashes shortly after postmaster start. That could in
turn prevent subsequent attempts to start the postmaster from succeeding, until the lockfile is manually removed.

Avoid recursion while assigning XIDs to heavily-nested subtransactions (Andres Freund, Robert Haas)
The original coding could result in a crash if there was limited stack space.

Avoid holding open old WAL segments in the walwriter process (Magnus Hagander, Heikki Linnakangas)
The previous coding would prevent removal of no-longer-needed segments.

Fix log_line_prefix's %i escape, which could produce junk early in backend startup (Tom Lane)

Prevent misinterpretation of partially-specified relation options for TOAST tables (Itagaki Takahiro)
In particular, fillfactor would be read as zero if any other reloption had been set for the table, leading to serious bloat.

Fix allance count tracking in ALTER TABLE ... ADD CONSTRAINT (Robert Haas)

Fix possible data corruption in ALTER TABLE ... SET TABLESPACE when archiving is enabled (Jeff Davis)

Allow CREATE DATABASE and ALTER DATABASE ... SET TABLESPACE to be interrupted by query-cancel
(Guillaume Lelarge)

Improve CREATE INDEX's checking of whether proposed index expressions are immutable (Tom Lane)

Fix REASSIGN OWNED to handle operator classes and families (Asko Tiidumaa)

Fix possible core dump when comparing two empty tsquery values (Tom Lane)

Fix LIKE's handling of patterns containing % followed by _ (Tom Lane)


1510

Notes de version

We've fixed this before, but there were still some incorrectly-handled cases.

Re-allow input of Julian dates prior to 0001-01-01 AD (Tom Lane)


Input such as 'J100000'::date worked before 8.4, but was unintentionally broken by added error-checking.

Fix PL/pgSQL to throw an error, not crash, if a cursor is closed within a FOR loop that is iterating over that cursor (Heikki
Linnakangas)

In PL/Python, defend against null pointer results from PyCObject_AsVoidPtr and PyCObject_FromVoidPtr (Peter
Eisentraut)

In libpq, fix full SSL certificate verification for the case where both host and hostaddr are specified (Tom Lane)

Make psql recognize DISCARD ALL as a command that should not be encased in a transaction block in autocommit-off
mode (Itagaki Takahiro)

Fix some issues in pg_dump's handling of SQL/MED objects (Tom Lane)


Notably, pg_dump would always fail if run by a non-superuser, which was not intended.

Improve pg_dump and pg_restore's handling of non-seekable archive files (Tom Lane, Robert Haas)
This is important for proper functioning of parallel restore.

Improve parallel pg_restore's ability to cope with selective restore (-L option) (Tom Lane)
The original code tended to fail if the -L file commanded a non-default restore ordering.

Fix ecpg to process data from RETURNING clauses correctly (Michael Meskes)

Fix some memory leaks in ecpg (Zoltan Boszormenyi)

Improve contrib/dblink's handling of tables containing dropped columns (Tom Lane)

Fix connection leak after duplicate connection name errors in contrib/dblink (Itagaki Takahiro)

Fix contrib/dblink to handle connection names longer than 62 bytes correctly (Itagaki Takahiro)

Add hstore(text, text) function to contrib/hstore (Robert Haas)


This function is the recommended substitute for the now-deprecated => operator. It was back-patched so that future-proofed
code can be used with older server versions. Note that the patch will be effective only after contrib/hstore is installed or
reinstalled in a particular database. Users might prefer to execute the CREATE FUNCTION command by hand, instead.

Update build infrastructure and documentation to reflect the source code repository's move from CVS to Git (Magnus Hagander and others)

Update time zone data files to tzdata release 2010l for DST law changes in Egypt and Palestine; also historical corrections for
Finland.
This change also adds new names for two Micronesian timezones: Pacific/Chuuk is now preferred over Pacific/Truk (and the
preferred abbreviation is CHUT not TRUT) and Pacific/Pohnpei is preferred over Pacific/Ponape.

Make Windows' N. Central Asia Standard Time timezone map to Asia/Novosibirsk, not Asia/Almaty (Magnus Hagander)
Microsoft changed the DST behavior of this zone in the timezone update from KB976098. Asia/Novosibirsk is a better match
to its new behavior.

E.53. Release 8.4.4


Release Date
2010-05-17
This release contains a variety of fixes from 8.4.3. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.53.1. Migration to Version 8.4.4


A dump/restore is not required for those running 8.4.X. However, if you are upgrading from a version earlier than 8.4.2, see Sec1511

Notes de version

tion E.55, Release 8.4.2 .

E.53.2. Changes

Enforce restrictions in plperl using an opmask applied to the whole interpreter, instead of using Safe.pm (Tim Bunce,
Andrew Dunstan)
Recent developments have convinced us that Safe.pm is too insecure to rely on for making plperl trustable. This change
removes use of Safe.pm altogether, in favor of using a separate interpreter with an opcode mask that is always applied. Pleasant side effects of the change include that it is now possible to use Perl's strict pragma in a natural way in plperl, and
that Perl's $a and $b variables work as expected in sort routines, and that function compilation is significantly faster.
(CVE-2010-1169)

Prevent PL/Tcl from executing untrustworthy code from pltcl_modules (Tom)


PL/Tcl's feature for autoloading Tcl code from a database table could be exploited for trojan-horse attacks, because there was
no restriction on who could create or insert into that table. This change disables the feature unless pltcl_modules is owned by a
superuser. (However, the permissions on the table are not checked, so installations that really need a less-than-secure modules
table can still grant suitable privileges to trusted non-superusers.) Also, prevent loading code into the unrestricted normal
Tcl interpreter unless we are really going to execute a pltclu function. (CVE-2010-1170)

Fix data corruption during WAL replay of ALTER ... SET TABLESPACE (Tom)
When archive_mode is on, ALTER ... SET TABLESPACE generates a WAL record whose replay logic was incorrect.
It could write the data to the wrong place, leading to possibly-unrecoverable data corruption. Data corruption would be observed on standby slaves, and could occur on the master as well if a database crash and recovery occurred after committing the
ALTER and before the next checkpoint.

Fix possible crash if a cache reset message is received during rebuild of a relcache entry (Heikki)
This error was introduced in 8.4.3 while fixing a related failure.

Apply per-function GUC settings while running the language validator for the function (Itagaki Takahiro)
This avoids failures if the function's code is invalid without the setting; an example is that SQL functions may not parse if the
search_path is not correct.

Do constraint exclusion for alled UPDATE and DELETE target tables when constraint_exclusion = partition
(Tom)
Due to an oversight, this setting previously only caused constraint exclusion to be checked in SELECT commands.

Do not allow an unprivileged user to reset superuser-only parameter settings (Alvaro)


Previously, if an unprivileged user ran ALTER USER ... RESET ALL for himself, or ALTER DATABASE ... RESET
ALL for a database he owns, this would remove all special parameter settings for the user or database, even ones that are only
supposed to be changeable by a superuser. Now, the ALTER will only remove the parameters that the user has permission to
change.

Avoid possible crash during backend shutdown if shutdown occurs when a CONTEXT addition would be made to log entries
(Tom)
In some cases the context-printing function would fail because the current transaction had already been rolled back when it
came time to print a log message.

Fix erroneous handling of %r parameter in recovery_end_command (Heikki)


The value always came out zero.

Ensure the archiver process responds to changes in archive_command as soon as possible (Tom)

Fix pl/pgsql's CASE statement to not fail when the case expression is a query that returns no rows (Tom)

Update pl/perl's ppport.h for modern Perl versions (Andrew)

Fix assorted memory leaks in pl/python (Andreas Freund, Tom)

Handle empty-string connect parameters properly in ecpg (Michael)

Prevent infinite recursion in psql when expanding a variable that refers to itself (Tom)

Fix psql's \copy to not add spaces around a dot within \copy (select ...) (Tom)
Addition of spaces around the decimal point in a numeric literal would result in a syntax error.
1512

Notes de version

Avoid formatting failure in psql when running in a locale context that doesn't match the client_encoding (Tom)

Fix unnecessary GIN indexes do not support whole-index scans errors for unsatisfiable queries using contrib/intarray operators (Tom)

Ensure that contrib/pgstattuple functions respond to cancel interrupts promptly (Tatsuhito Kasahara)

Make server startup deal properly with the case that shmget() returns EINVAL for an existing shared memory segment
(Tom)
This behavior has been observed on BSD-derived kernels including OS X. It resulted in an entirely-misleading startup failure
complaining that the shared memory request size was too large.

Avoid possible crashes in syslogger process on Windows (Heikki)

Deal more robustly with incomplete time zone information in the Windows registry (Magnus)

Update the set of known Windows time zone names (Magnus)

Update time zone data files to tzdata release 2010j for DST law changes in Argentina, Australian Antarctic, Bangladesh,
Mexico, Morocco, Pakistan, Palestine, Russia, Syria, Tunisia; also historical corrections for Taiwan.
Also, add PKST (Pakistan Summer Time) to the default set of timezone abbreviations.

E.54. Release 8.4.3


Release Date
2010-03-15
This release contains a variety of fixes from 8.4.2. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.54.1. Migration to Version 8.4.3


A dump/restore is not required for those running 8.4.X. However, if you are upgrading from a version earlier than 8.4.2, see Section E.55, Release 8.4.2 .

E.54.2. Changes

Add new configuration parameter ssl_renegotiation_limit to control how often we do session key renegotiation for
an SSL connection (Magnus)
This can be set to zero to disable renegotiation completely, which may be required if a broken SSL library is used. In particular, some vendors are shipping stopgap patches for CVE-2009-3555 that cause renegotiation attempts to fail.

Fix possible deadlock during backend startup (Tom)

Fix possible crashes due to not handling errors during relcache reload cleanly (Tom)

Fix possible crash due to use of dangling pointer to a cached plan (Tatsuo)

Fix possible crash due to overenthusiastic invalidation of cached plan for ROLLBACK (Tom)

Fix possible crashes when trying to recover from a failure in subtransaction start (Tom)

Fix server memory leak associated with use of savepoints and a client encoding different from server's encoding (Tom)

Fix incorrect WAL data emitted during end-of-recovery cleanup of a GIST index page split (Yoichi Hirai)
This would result in index corruption, or even more likely an error during WAL replay, if we were unlucky enough to crash
during end-of-recovery cleanup after having completed an incomplete GIST insertion.

Fix bug in WAL redo cleanup method for GIN indexes (Heikki)

Fix incorrect comparison of scan key in GIN index search (Teodor)

Make substring() for bit types treat any negative length as meaning all the rest of the string (Tom)
The previous coding treated only -1 that way, and would produce an invalid result value for other negative values, possibly
leading to a crash (CVE-2010-0442).
1513

Notes de version

Fix integer-to-bit-string conversions to handle the first fractional byte correctly when the output bit width is wider than the given integer by something other than a multiple of 8 bits (Tom)

Fix some cases of pathologically slow regular expression matching (Tom)

Fix bug occurring when trying to inline a SQL function that returns a set of a composite type that contains dropped columns
(Tom)

Fix bug with trying to update a field of an element of a composite-type array column (Tom)

Avoid failure when EXPLAIN has to print a FieldStore or assignment ArrayRef expression (Tom)
These cases can arise now that EXPLAIN VERBOSE tries to print plan node target lists.

Avoid an unnecessary coercion failure in some cases where an undecorated literal string appears in a subquery within
UNION/INTERSECT/EXCEPT (Tom)
This fixes a regression for some cases that worked before 8.4.

Avoid undesirable rowtype compatibility check failures in some cases where a whole-row Var has a rowtype that contains
dropped columns (Tom)

Fix the STOP WAL LOCATION entry in backup history files to report the next WAL segment's name when the end location
is exactly at a segment boundary (Itagaki Takahiro)

Always pass the catalog ID to an option validator function specified in CREATE FOREIGN DATA WRAPPER (Martin
Pihlak)

Fix some more cases of temporary-file leakage (Heikki)


This corrects a problem introduced in the previous minor release. One case that failed is when a plpgsql function returning set
is called within another function's exception handler.

Add support for doing FULL JOIN ON FALSE (Tom)


This prevents a regression from pre-8.4 releases for some queries that can now be simplified to a constant-false join condition.

Improve constraint exclusion processing of boolean-variable cases, in particular make it possible to exclude a partition that has
a bool_column = false constraint (Tom)

Prevent treating an INOUT cast as representing binary compatibility (Heikki)

Include column name in the message when warning about inability to grant or revoke column-level privileges (Stephen Frost)
This is more useful than before and helps to prevent confusion when a REVOKE generates multiple messages, which formerly appeared to be duplicates.

When reading pg_hba.conf and related files, do not treat @something as a file inclusion request if the @ appears inside
quote marks; also, never treat @ by itself as a file inclusion request (Tom)
This prevents erratic behavior if a role or database name starts with @. If you need to include a file whose path name contains
spaces, you can still do so, but you must write @"/path to/file" rather than putting the quotes around the whole
construct.

Prevent infinite loop on some platforms if a directory is named as an inclusion target in pg_hba.conf and related files
(Tom)

Fix possible infinite loop if SSL_read or SSL_write fails without setting errno (Tom)
This is reportedly possible with some Windows versions of openssl.

Disallow GSSAPI authentication on local connections, since it requires a hostname to function correctly (Magnus)

Protect ecpg against applications freeing strings unexpectedly (Michael)

Make ecpg report the proper SQLSTATE if the connection disappears (Michael)

Fix translation of cell contents in psql \d output (Heikki)

Fix psql's numericlocale option to not format strings it shouldn't in latex and troff output formats (Heikki)

Fix a small per-query memory leak in psql (Tom)

Make psql return the correct exit status (3) when ON_ERROR_STOP and --single-transaction are both specified and
an error occurs during the implied COMMIT (Bruce)

1514

Notes de version

Fix pg_dump's output of permissions for foreign servers (Heikki)

Fix possible crash in parallel pg_restore due to out-of-range dependency IDs (Tom)

Fix plpgsql failure in one case where a composite column is set to NULL (Tom)

Fix possible failure when calling PL/Perl functions from PL/PerlU or vice versa (Tim Bunce)

Add volatile markings in PL/Python to avoid possible compiler-specific misbehavior (Zdenek Kotala)

Ensure PL/Tcl initializes the Tcl interpreter fully (Tom)


The only known symptom of this oversight is that the Tcl clock command misbehaves if using Tcl 8.5 or later.

Prevent ExecutorEnd from being run on portals created within a failed transaction or subtransaction (Tom)
This is known to cause issues when using contrib/auto_explain.

Prevent crash in contrib/dblink when too many key columns are specified to a dblink_build_sql_* function
(Rushabh Lathia, Joe Conway)

Allow zero-dimensional arrays in contrib/ltree operations (Tom)


This case was formerly rejected as an error, but it's more convenient to treat it the same as a zero-element array. In particular
this avoids unnecessary failures when an ltree operation is applied to the result of ARRAY(SELECT ...) and the sub-select
returns no rows.

Fix assorted crashes in contrib/xml2 caused by sloppy memory management (Tom)

Make building of contrib/xml2 more robust on Windows (Andrew)

Fix race condition in Windows signal handling (Radu Ilie)


One known symptom of this bug is that rows in pg_listener could be dropped under heavy load.

Make the configure script report failure if the C compiler does not provide a working 64-bit integer datatype (Tom)
This case has been broken for some time, and no longer seems worth supporting, so just reject it at configure time instead.

Update time zone data files to tzdata release 2010e for DST law changes in Bangladesh, Chile, Fiji, Mexico, Paraguay, Samoa.

E.55. Release 8.4.2


Release Date
2009-12-14
This release contains a variety of fixes from 8.4.1. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.55.1. Migration to Version 8.4.2


A dump/restore is not required for those running 8.4.X. However, if you have any hash indexes, you should REINDEX them after
updating to 8.4.2, to repair possible damage.

E.55.2. Changes

Protect against indirect security threats caused by index functions changing session-local state (Gurjeet Singh, Tom)
This change prevents allegedly-immutable index functions from possibly subverting a superuser's session (CVE-2009-4136).

Reject SSL certificates containing an embedded null byte in the common name (CN) field (Magnus)
This prevents unintended matching of a certificate to a server or client name during SSL validation (CVE-2009-4034).

Fix hash index corruption (Tom)


The 8.4 change that made hash indexes keep entries sorted by hash value failed to update the bucket splitting and compaction
routines to preserve the ordering. So application of either of those operations could lead to permanent corruption of an index,
in the sense that searches might fail to find entries that are present. To deal with this, it is recommended to REINDEX any hash
indexes you may have after installing this update.
1515

Notes de version

Fix possible crash during backend-startup-time cache initialization (Tom)

Avoid crash on empty thesaurus dictionary (Tom)

Prevent signals from interrupting VACUUM at unsafe times (Alvaro)


This fix prevents a PANIC if a VACUUM FULL is canceled after it's already committed its tuple movements, as well as transient errors if a plain VACUUM is interrupted after having truncated the table.

Fix possible crash due to integer overflow in hash table size calculation (Tom)
This could occur with extremely large planner estimates for the size of a hashjoin's result.

Fix crash if a DROP is attempted on an internally-dependent object (Tom)

Fix very rare crash in inet/cidr comparisons (Chris Mikkelson)

Ensure that shared tuple-level locks held by prepared transactions are not ignored (Heikki)

Fix premature drop of temporary files used for a cursor that is accessed within a subtransaction (Heikki)

Fix memory leak in syslogger process when rotating to a new CSV logfile (Tom)

Fix memory leak in postmaster when re-parsing pg_hba.conf (Tom)

Fix Windows permission-downgrade logic (Jesse Morris)


This fixes some cases where the database failed to start on Windows, often with misleading error messages such as could not
locate matching postgres executable .

Make FOR UPDATE/SHARE in the primary query not propagate into WITH queries (Tom)
For example, in
WITH w AS (SELECT * FROM foo) SELECT * FROM w, bar ... FOR UPDATE
the FOR UPDATE will now affect bar but not foo. This is more useful and consistent than the original 8.4 behavior, which
tried to propagate FOR UPDATE into the WITH query but always failed due to assorted implementation restrictions. It also
follows the design rule that WITH queries are executed as if independent of the main query.

Fix bug with a WITH RECURSIVE query immediately inside another one (Tom)

Fix concurrency bug in hash indexes (Tom)


Concurrent insertions could cause index scans to transiently report wrong results.

Fix incorrect logic for GiST index page splits, when the split depends on a non-first column of the index (Paul Ramsey)

Fix wrong search results for a multi-column GIN index with fastupdate enabled (Teodor)

Fix bugs in WAL entry creation for GIN indexes (Tom)


These bugs were masked when full_page_writes was on, but with it off a WAL replay failure was certain if a crash occurred before the next checkpoint.

Don't error out if recycling or removing an old WAL file fails at the end of checkpoint (Heikki)
It's better to treat the problem as non-fatal and allow the checkpoint to complete. Future checkpoints will retry the removal.
Such problems are not expected in normal operation, but have been seen to be caused by misdesigned Windows anti-virus and
backup software.

Ensure WAL files aren't repeatedly archived on Windows (Heikki)


This is another symptom that could happen if some other process interfered with deletion of a no-longer-needed file.

Fix PAM password processing to be more robust (Tom)


The previous code is known to fail with the combination of the Linux pam_krb5 PAM module with Microsoft Active Directory as the domain controller. It might have problems elsewhere too, since it was making unjustified assumptions about what
arguments the PAM stack would pass to it.

Raise the maximum authentication token (Kerberos ticket) size in GSSAPI and SSPI authentication methods (Ian Turner)
While the old 2000-byte limit was more than enough for Unix Kerberos implementations, tickets issued by Windows Domain
Controllers can be much larger.

Ensure that domain constraints are enforced in constructs like ARRAY[...]::domain, where the domain is over an array
1516

Notes de version

type (Heikki)

Fix foreign-key logic for some cases involving composite-type columns as foreign keys (Tom)

Ensure that a cursor's snapshot is not modified after it is created (Alvaro)


This could lead to a cursor delivering wrong results if later operations in the same transaction modify the data the cursor is
supposed to return.

Fix CREATE TABLE to properly merge default expressions coming from different allance parent tables (Tom)
This used to work but was broken in 8.4.

Re-enable collection of access statistics for sequences (Akira Kurosawa)


This used to work but was broken in 8.3.

Fix processing of ownership dependencies during CREATE OR REPLACE FUNCTION (Tom)

Fix incorrect handling of WHERE x=x conditions (Tom)


In some cases these could get ignored as redundant, but they aren't -- they're equivalent to x IS NOT NULL.

Fix incorrect plan construction when using hash aggregation to implement DISTINCT for textually identical volatile expressions (Tom)

Fix Assert failure for a volatile SELECT DISTINCT ON expression (Tom)

Fix ts_stat() to not fail on an empty tsvector value (Tom)

Make text search parser accept underscores in XML attributes (Peter)

Fix encoding handling in xml binary input (Heikki)


If the XML header doesn't specify an encoding, we now assume UTF-8 by default; the previous handling was inconsistent.

Fix bug with calling plperl from plperlu or vice versa (Tom)
An error exit from the inner function could result in crashes due to failure to re-select the correct Perl interpreter for the outer
function.

Fix session-lifespan memory leak when a PL/Perl function is redefined (Tom)

Ensure that Perl arrays are properly converted to PostgreSQL arrays when returned by a set-returning PL/Perl function
(Andrew Dunstan, Abhijit Menon-Sen)
This worked correctly already for non-set-returning functions.

Fix rare crash in exception processing in PL/Python (Peter)

Fix ecpg problem with comments in DECLARE CURSOR statements (Michael)

Fix ecpg to not treat recently-added keywords as reserved words (Tom)


This affected the keywords CALLED, CATALOG, DEFINER, ENUM, FOLLOWING, INVOKER, OPTIONS, PARTITION,
PRECEDING, RANGE, SECURITY, SERVER, UNBOUNDED, and WRAPPER.

Re-allow regular expression special characters in psql's \df function name parameter (Tom)

In contrib/fuzzystrmatch, correct the calculation of levenshtein distances with non-default costs (Marcin Mank)

In contrib/pg_standby, disable triggering failover with a signal on Windows (Fujii Masao)


This never did anything useful, because Windows doesn't have Unix-style signals, but recent changes made it actually crash.

Put FREEZE and VERBOSE options in the right order in the VACUUM command that contrib/vacuumdb produces
(Heikki)

Fix possible leak of connections when contrib/dblink encounters an error (Tatsuhito Kasahara)

Ensure psql's flex module is compiled with the correct system header definitions (Tom)
This fixes build failures on platforms where --enable-largefile causes incompatible changes in the generated code.

Make the postmaster ignore any application_name parameter in connection request packets, to improve compatibility
with future libpq versions (Tom)

Update the timezone abbreviation files to match current reality (Joachim Wieland)
1517

Notes de version

This includes adding IDT to the default timezone abbreviation set.

Update time zone data files to tzdata release 2009s for DST law changes in Antarctica, Argentina, Bangladesh, Fiji, Novokuznetsk, Pakistan, Palestine, Samoa, Syria; also historical corrections for Hong Kong.

E.56. Release 8.4.1


Release Date
2009-09-09
This release contains a variety of fixes from 8.4. For information about new features in the 8.4 major release, see Section E.57,
Release 8.4 .

E.56.1. Migration to Version 8.4.1


A dump/restore is not required for those running 8.4.X.

E.56.2. Changes

Fix WAL page header initialization at the end of archive recovery (Heikki)
This could lead to failure to process the WAL in a subsequent archive recovery.

Fix cannot make new WAL entries during recovery error (Tom)

Fix problem that could make expired rows visible after a crash (Tom)
This bug involved a page status bit potentially not being set correctly after a server crash.

Disallow RESET ROLE and RESET SESSION AUTHORIZATION inside security-definer functions (Tom, Heikki)
This covers a case that was missed in the previous patch that disallowed SET ROLE and SET SESSION AUTHORIZATION inside security-definer functions. (See CVE-2007-6600)

Make LOAD of an already-loaded loadable module into a no-op (Tom)


Formerly, LOAD would attempt to unload and re-load the module, but this is unsafe and not all that useful.

Make window function PARTITION BY and ORDER BY items always be interpreted as simple expressions (Tom)
In 8.4.0 these lists were parsed following the rules used for top-level GROUP BY and ORDER BY lists. But this was not correct per the SQL standard, and it led to possible circularity.

Fix several errors in planning of semi-joins (Tom)


These led to wrong query results in some cases where IN or EXISTS was used together with another join.

Fix handling of whole-row references to subqueries that are within an outer join (Tom)
An example is SELECT COUNT(ss.*) FROM ... LEFT JOIN (SELECT ...) ss ON .... Here, ss.* would
be treated as ROW(NULL,NULL,...) for null-extended join rows, which is not the same as a simple NULL. Now it is treated as a simple NULL.

Fix Windows shared-memory allocation code (Tsutomu Yamada, Magnus)


This bug led to the often-reported could not reattach to shared memory error message.

Fix locale handling with plperl (Heikki)


This bug could cause the server's locale setting to change when a plperl function is called, leading to data corruption.

Fix handling of reloptions to ensure setting one option doesn't force default values for others (Itagaki Takahiro)

Ensure that a fast shutdown request will forcibly terminate open sessions, even if a smart shutdown was already in progress (Fujii Masao)

Avoid memory leak for array_agg() in GROUP BY queries (Tom)

Treat to_char(..., 'TH') as an uppercase ordinal suffix with 'HH'/'HH12' (Heikki)


1518

Notes de version

It was previously handled as 'th' (lowercase).

Include the fractional part in the result of EXTRACT(second) and EXTRACT(milliseconds) for time and time with
time zone inputs (Tom)
This has always worked for floating-point datetime configurations, but was broken in the integer datetime code.

Fix overflow for INTERVAL 'x ms' when x is more than 2 million and integer datetimes are in use (Alex Hunsaker)

Improve performance when processing toasted values in index scans (Tom)


This is particularly useful for PostGIS.

Fix a typo that disabled commit_delay (Jeff Janes)

Output early-startup messages to postmaster.log if the server is started in silent mode (Tom)
Previously such error messages were discarded, leading to difficulty in debugging.

Remove translated FAQs (Peter)


They are now on the wiki. The main FAQ was moved to the wiki some time ago.

Fix pg_ctl to not go into an infinite loop if postgresql.conf is empty (Jeff Davis)

Fix several errors in pg_dump's --binary-upgrade mode (Bruce, Tom)


pg_dump --binary-upgrade is used by pg_migrator.

Fix contrib/xml2's xslt_process() to properly handle the maximum number of parameters (twenty) (Tom)

Improve robustness of libpq's code to recover from errors during COPY FROM STDIN (Tom)

Avoid including conflicting readline and editline header files when both libraries are installed (Zdenek Kotala)

Work around gcc bug that causes floating-point exception instead of division by zero on some platforms (Tom)

Update time zone data files to tzdata release 2009l for DST law changes in Bangladesh, Egypt, Mauritius.

E.57. Release 8.4


Release Date
2009-07-01

E.57.1. Overview
After many years of development, PostgreSQL has become feature-complete in many areas. This release shows a targeted approach to adding features (e.g., authentication, monitoring, space reuse), and adds capabilities defined in the later SQL standards.
The major areas of enhancement are:

Windowing Functions

Common Table Expressions and Recursive Queries

Default and variadic parameters for functions

Parallel Restore

Column Permissions

Per-database locale settings

Improved hash indexes

Improved join performance for EXISTS and NOT EXISTS queries

Easier-to-use Warm Standby

Automatic sizing of the Free Space Map

Visibility Map (greatly reduces vacuum overhead for slowly-changing tables)


1519

Notes de version

Version-aware psql (backslash commands work against older servers)

Support SSL certificates for user authentication

Per-function runtime statistics

Easy editing of functions in psql

New contrib modules: pg_stat_statements, auto_explain, citext, btree_gin

The above items are explained in more detail in the sections below.

E.57.2. Migration to Version 8.4


A dump/restore using pg_dump is required for those wishing to migrate data from any previous release.
Observe the following incompatibilities:

E.57.2.1. General

Use 64-bit integer datetimes by default (Neil Conway)


Previously this was selected by configure's --enable-integer-datetimes option. To retain the old behavior, build
with --disable-integer-datetimes.

Remove ipcclean utility command (Bruce)


The utility only worked on a few platforms. Users should use their operating system tools instead.

E.57.2.2. Server Settings

Change default setting for log_min_messages to warning (previously it was notice) to reduce log file volume (Tom)

Change default setting for max_prepared_transactions to zero (previously it was 5) (Tom)

Make debug_print_parse, debug_print_rewritten, and debug_print_plan output appear at LOG message


level, not DEBUG1 as formerly (Tom)

Make debug_pretty_print default to on (Tom)

Remove explain_pretty_print parameter (no longer needed) (Tom)

Make log_temp_files settable by superusers only, like other logging options (Simon Riggs)

Remove automatic appending of the epoch timestamp when no % escapes are present in log_filename (Robert Haas)
This change was made because some users wanted a fixed log filename, for use with an external log rotation tool.

Remove log_restartpoints from recovery.conf; instead use log_checkpoints (Simon)

Remove krb_realm and krb_server_hostname; these are now set in pg_hba.conf instead (Magnus)

There are also significant changes in pg_hba.conf, as described below.

E.57.2.3. Queries

Change TRUNCATE and LOCK to apply to child tables of the specified table(s) (Peter)
These commands now accept an ONLY option that prevents processing child tables; this option must be used if the old behavior is needed.

SELECT DISTINCT and UNION/INTERSECT/EXCEPT no longer always produce sorted output (Tom)
Previously, these types of queries always removed duplicate rows by means of Sort/Unique processing (i.e., sort then remove
adjacent duplicates). Now they can be implemented by hashing, which will not produce sorted output. If an application relied
on the output being in sorted order, the recommended fix is to add an ORDER BY clause. As a short-term workaround, the previous behavior can be restored by disabling enable_hashagg, but that is a very performance-expensive fix. SELECT
DISTINCT ON never uses hashing, however, so its behavior is unchanged.

Force child tables to all CHECK constraints from parents (Alex Hunsaker, Nikhil Sontakke, Tom)
1520

Notes de version

Formerly it was possible to drop such a constraint from a child table, allowing rows that violate the constraint to be visible
when scanning the parent table. This was deemed inconsistent, as well as contrary to SQL standard.

Disallow negative LIMIT or OFFSET values, rather than treating them as zero (Simon)

Disallow LOCK TABLE outside a transaction block (Tom)


Such an operation is useless because the lock would be released immediately.

Sequences now contain an additional start_value column (Zoltan Boszormenyi)


This supports ALTER SEQUENCE ... RESTART.

E.57.2.4. Functions and Operators

Make numeric zero raised to a fractional power return 0, rather than throwing an error, and make numeric zero raised to the
zero power return 1, rather than error (Bruce)
This matches the longstanding float8 behavior.

Allow unary minus of floating-point values to produce minus zero (Tom)


The changed behavior is more IEEE-standard compliant.

Throw an error if an escape character is the last character in a LIKE pattern (i.e., it has nothing to escape) (Tom)
Previously, such an escape character was silently ignored, thus possibly masking application logic errors.

Remove ~=~ and ~<>~ operators formerly used for LIKE index comparisons (Tom)
Pattern indexes now use the regular equality operator.

xpath() now passes its arguments to libxml without any changes (Andrew)
This means that the XML argument must be a well-formed XML document. The previous coding attempted to allow XML
fragments, but it did not work well.

Make xmlelement() format attribute values just like content values (Peter)
Previously, attribute values were formatted according to the normal SQL output behavior, which is sometimes at odds with
XML rules.

Rewrite memory management for libxml-using functions (Tom)


This change should avoid some compatibility problems with use of libxml in PL/Perl and other add-on code.

Adopt a faster algorithm for hash functions (Kenneth Marshall, based on work of Bob Jenkins)
Many of the built-in hash functions now deliver different results on little-endian and big-endian platforms.

E.57.2.4.1. Temporal Functions and Operators

DateStyle no longer controls interval output formatting; instead there is a new variable IntervalStyle (Ron Mayer)

Improve consistency of handling of fractional seconds in timestamp and interval output (Ron Mayer)
This may result in displaying a different number of fractional digits than before, or rounding instead of truncating.

Make to_char()'s localized month/day names depend on LC_TIME, not LC_MESSAGES (Euler Taveira de Oliveira)

Cause to_date() and to_timestamp() to more consistently report errors for invalid input (Brendan Jurd)
Previous versions would often ignore or silently misread input that did not match the format string. Such cases will now result
in an error.

Fix to_timestamp() to not require upper/lower case matching for meridian (AM/PM) and era (BC/AD) format designations
(Brendan Jurd)
For example, input value ad now matches the format string AD.

E.57.3. Changes
1521

Notes de version

Below you will find a detailed account of the changes between PostgreSQL 8.4 and the previous major release.

E.57.3.1. Performance

Improve optimizer statistics calculations (Jan Urbanski, Tom)


In particular, estimates for full-text-search operators are greatly improved.

Allow SELECT DISTINCT and UNION/INTERSECT/EXCEPT to use hashing (Tom)


This means that these types of queries no longer automatically produce sorted output.

Create explicit concepts of semi-joins and anti-joins (Tom)


This work formalizes our previous ad-hoc treatment of IN (SELECT ...) clauses, and extends it to EXISTS and NOT
EXISTS clauses. It should result in significantly better planning of EXISTS and NOT EXISTS queries. In general, logically
equivalent IN and EXISTS clauses should now have similar performance, whereas previously IN often won.

Improve optimization of sub-selects beneath outer joins (Tom)


Formerly, a sub-select or view could not be optimized very well if it appeared within the nullable side of an outer join and
contained non-strict expressions (for instance, constants) in its result list.

Improve the performance of text_position() and related functions by using Boyer-Moore-Horspool searching (David
Rowley)
This is particularly helpful for long search patterns.

Reduce I/O load of writing the statistics collection file by writing the file only when requested (Martin Pihlak)

Improve performance for bulk inserts (Robert Haas, Simon)

Increase the default value of default_statistics_target from 10 to 100 (Greg Sabino Mullane, Tom)
The maximum value was also increased from 1000 to 10000.

Perform constraint_exclusion checking by default in queries involving allance or UNION ALL (Tom)
A new constraint_exclusion setting, partition, was added to specify this behavior.

Allow I/O read-ahead for bitmap index scans (Greg Stark)


The amount of read-ahead is controlled by effective_io_concurrency. This feature is available only if the kernel has
posix_fadvise() support.

Inline simple set-returning SQL functions in FROM clauses (Richard Rowell)

Improve performance of multi-batch hash joins by providing a special case for join key values that are especially common in
the outer relation (Bryce Cutt, Ramon Lawrence)

Reduce volume of temporary data in multi-batch hash joins by suppressing physical tlist optimization (Michael Henderson,
Ramon Lawrence)

Avoid waiting for idle-in-transaction sessions during CREATE INDEX CONCURRENTLY (Simon)

Improve performance of shared cache invalidation (Tom)

E.57.3.2. Server
E.57.3.2.1. Settings

Convert many postgresql.conf settings to enumerated values so that pg_settings can display the valid values
(Magnus)

Add cursor_tuple_fraction parameter to control the fraction of a cursor's rows that the planner assumes will be fetched (Robert Hell)

Allow underscores in the names of custom variable classes in postgresql.conf (Tom)

E.57.3.2.2. Authentication and security

Remove support for the (insecure) crypt authentication method (Magnus)


1522

Notes de version

This effectively obsoletes pre-PostgreSQL 7.2 client libraries, as there is no longer any non-plaintext password method that
they can use.

Support regular expressions in pg_ident.conf (Magnus)

Allow Kerberos/GSSAPI parameters to be changed without restarting the postmaster (Magnus)

Support SSL certificate chains in server certificate file (Andrew Gierth)


Including the full certificate chain makes the client able to verify the certificate without having all intermediate CA certificates
present in the local store, which is often the case for commercial CAs.

Report appropriate error message for combination of MD5 authentication and db_user_namespace enabled (Bruce)

E.57.3.2.3. pg_hba.conf

Change all authentication options to use name=value syntax (Magnus)


This makes incompatible changes to the ldap, pam and ident authentication methods. All pg_hba.conf entries with
these methods need to be rewritten using the new format.

Remove the ident sameuser option, instead making that behavior the default if no usermap is specified (Magnus)

Allow a usermap parameter for all external authentication methods (Magnus)


Previously a usermap was only supported for ident authentication.

Add clientcert option to control requesting of a client certificate (Magnus)


Previously this was controlled by the presence of a root certificate file in the server's data directory.

Add cert authentication method to allow user authentication via SSL certificates (Magnus)
Previously SSL certificates could only verify that the client had access to a certificate, not authenticate a user.

Allow krb5, gssapi and sspi realm and krb5 host settings to be specified in pg_hba.conf (Magnus)
These override the settings in postgresql.conf.

Add include_realm parameter for krb5, gssapi, and sspi methods (Magnus)
This allows identical usernames from different realms to be authenticated as different database users using usermaps.

Parse pg_hba.conf fully when it is loaded, so that errors are reported immediately (Magnus)
Previously, most errors in the file wouldn't be detected until clients tried to connect, so an erroneous file could render the system unusable. With the new behavior, if an error is detected during reload then the bad file is rejected and the postmaster
continues to use its old copy.

Show all parsing errors in pg_hba.conf instead of aborting after the first one (Selena Deckelmann)

Support ident authentication over Unix-domain sockets on Solaris (Garick Hamlin)

E.57.3.2.4. Continuous Archiving

Provide an option to pg_start_backup() to force its implied checkpoint to finish as quickly as possible (Tom)
The default behavior avoids excess I/O consumption, but that is pointless if no concurrent query activity is going on.

Make pg_stop_backup() wait for modified WAL files to be archived (Simon)


This guarantees that the backup is valid at the time pg_stop_backup() completes.

When archiving is enabled, rotate the last WAL segment at shutdown so that all transactions can be archived immediately
(Guillaume Smet, Heikki)

Delay smart shutdown while a continuous archiving base backup is in progress (Laurenz Albe)

Cancel a continuous archiving base backup if fast shutdown is requested (Laurenz Albe)

Allow recovery.conf boolean variables to take the same range of string values as postgresql.conf boolean variables (Bruce)

1523

Notes de version

E.57.3.2.5. Monitoring

Add pg_conf_load_time() to report when the PostgreSQL configuration files were last loaded (George Gensure)

Add pg_terminate_backend() to safely terminate a backend (the SIGTERM signal works also) (Tom, Bruce)
While it's always been possible to SIGTERM a single backend, this was previously considered unsupported; and testing of the
case found some bugs that are now fixed.

Add ability to track user-defined functions' call counts and runtimes (Martin Pihlak)
Function statistics appear in a new system view, pg_stat_user_functions. Tracking is controlled by the new parameter track_functions.

Allow specification of the maximum query string size in pg_stat_activity via new
track_activity_query_size parameter (Thomas Lee)

Increase the maximum line length sent to syslog, in hopes of improving performance (Tom)

Add read-only configuration variables segment_size, wal_block_size, and wal_segment_size (Bernd Helmle)

When reporting a deadlock, report the text of all queries involved in the deadlock to the server log (Itagaki Takahiro)

Add pg_stat_get_activity(pid) function to return information about a specific process id (Magnus)

Allow the location of the server's statistics file to be specified via stats_temp_directory (Magnus)
This allows the statistics file to be placed in a RAM-resident directory to reduce I/O requirements. On startup/shutdown, the
file is copied to its traditional location ($PGDATA/global/) so it is preserved across restarts.

E.57.3.3. Queries

Add support for WINDOW functions (Hitoshi Harada)

Add support for WITH clauses (CTEs), including WITH RECURSIVE (Yoshiyuki Asaba, Tatsuo Ishii, Tom)

Add TABLE command (Peter)


TABLE tablename is a SQL standard short-hand for SELECT * FROM tablename.

Allow AS to be optional when specifying a SELECT (or RETURNING) column output label (Hiroshi Saito)
This works so long as the column label is not any PostgreSQL keyword; otherwise AS is still needed.

Support set-returning functions in SELECT result lists even for functions that return their result via a tuplestore (Tom)
In particular, this means that functions written in PL/pgSQL and other PL languages can now be called this way.

Support set-returning functions in the output of aggregation and grouping queries (Tom)

Allow SELECT FOR UPDATE/SHARE to work on allance trees (Tom)

Add infrastructure for SQL/MED (Martin Pihlak, Peter)


There are no remote or external SQL/MED capabilities yet, but this change provides a standardized and future-proof system
for managing connection information for modules like dblink and plproxy.

Invalidate cached plans when referenced schemas, functions, operators, or operator classes are modified (Martin Pihlak, Tom)
This improves the system's ability to respond to on-the-fly DDL changes.

Allow comparison of composite types and allow arrays of anonymous composite types (Tom)
This allows constructs such as row(1, 1.1) = any (array[row(7, 7.7), row(1, 1.0)]). This is particularly useful in recursive queries.

Add support for Unicode string literal and identifier specifications using code points, e.g. U&'d\0061t\+000061' (Peter)

Reject \000 in string literals and COPY data (Tom)


Previously, this was accepted but had the effect of terminating the string contents.

Improve the parser's ability to report error locations (Tom)


An error location is now reported for many semantic errors, such as mismatched datatypes, that previously could not be locali1524

Notes de version

zed.
E.57.3.3.1. TRUNCATE

Support statement-level ON TRUNCATE triggers (Simon)

Add RESTART/CONTINUE IDENTITY options for TRUNCATE TABLE (Zoltan Boszormenyi)


The start value of a sequence can be changed by ALTER SEQUENCE START WITH.

Allow TRUNCATE tab1, tab1 to succeed (Bruce)

Add a separate TRUNCATE permission (Robert Haas)

E.57.3.3.2. EXPLAIN

Make EXPLAIN VERBOSE show the output columns of each plan node (Tom)
Previously EXPLAIN VERBOSE output an internal representation of the query plan. (That behavior is now available via
debug_print_plan.)

Make EXPLAIN identify subplans and initplans with individual labels (Tom)

Make EXPLAIN honor debug_print_plan (Tom)

Allow EXPLAIN on CREATE TABLE AS (Peter)

E.57.3.3.3. LIMIT/OFFSET

Allow sub-selects in LIMIT and OFFSET (Tom)

Add SQL-standard syntax for LIMIT/OFFSET capabilities (Peter)


To wit, OFFSET num {ROW|ROWS} FETCH {FIRST|NEXT} [num] {ROW|ROWS} ONLY.

E.57.3.4. Object Manipulation

Add support for column-level privileges (Stephen Frost, KaiGai Kohei)

Refactor multi-object DROP operations to reduce the need for CASCADE (Alex Hunsaker)
For example, if table B has a dependency on table A, the command DROP TABLE A, B no longer requires the CASCADE
option.

Fix various problems with concurrent DROP commands by ensuring that locks are taken before we begin to drop dependencies of an object (Tom)

Improve reporting of dependencies during DROP commands (Tom)

Add WITH [NO] DATA clause to CREATE TABLE AS, per the SQL standard (Peter, Tom)

Add support for user-defined I/O conversion casts (Heikki)

Allow CREATE AGGREGATE to use an internal transition datatype (Tom)

Add LIKE clause to CREATE TYPE (Tom)


This simplifies creation of data types that use the same internal representation as an existing type.

Allow specification of the type category and preferred status for user-defined base types (Tom)
This allows more control over the coercion behavior of user-defined types.

Allow CREATE OR REPLACE VIEW to add columns to the end of a view (Robert Haas)

E.57.3.4.1. ALTER

Add ALTER TYPE RENAME (Petr Jelinek)

1525

Notes de version

Add ALTER SEQUENCE ... RESTART (with no parameter) to reset a sequence to its initial value (Zoltan Boszormenyi)

Modify the ALTER TABLE syntax to allow all reasonable combinations for tables, indexes, sequences, and views (Tom)
This change allows the following new syntaxes:

ALTER SEQUENCE OWNER TO

ALTER VIEW ALTER COLUMN SET/DROP DEFAULT

ALTER VIEW OWNER TO

ALTER VIEW SET SCHEMA

There is no actual new functionality here, but formerly you had to say ALTER TABLE to do these things, which was confusing.

Add support for the syntax ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE (Peter)
This is SQL-standard syntax for functionality that was already supported.

Make ALTER TABLE SET WITHOUT OIDS rewrite the table to physically remove OID values (Tom)
Also, add ALTER TABLE SET WITH OIDS to rewrite the table to add OIDs.

E.57.3.4.2. Database Manipulation

Improve reporting of CREATE/DROP/RENAME DATABASE failure when uncommitted prepared transactions are the
cause (Tom)

Make LC_COLLATE and LC_CTYPE into per-database settings (Radek Strnad, Heikki)
This makes collation similar to encoding, which was always configurable per database.

Improve checks that the database encoding, collation (LC_COLLATE), and character classes (LC_CTYPE) match (Heikki,
Tom)
Note in particular that a new database's encoding and locale settings can be changed only when copying from template0.
This prevents possibly copying data that doesn't match the settings.

Add ALTER DATABASE SET TABLESPACE to move a database to a new tablespace (Guillaume Lelarge, Bernd Helmle)

E.57.3.5. Utility Operations

Add a VERBOSE option to the CLUSTER command and clusterdb (Jim Cox)

Decrease memory requirements for recording pending trigger events (Tom)

E.57.3.5.1. Indexes

Dramatically improve the speed of building and accessing hash indexes (Tom Raney, Shreya Bhargava)
This allows hash indexes to be sometimes faster than btree indexes. However, hash indexes are still not crash-safe.

Make hash indexes store only the hash code, not the full value of the indexed column (Xiao Meng)
This greatly reduces the size of hash indexes for long indexed values, improving performance.

Implement fast update option for GIN indexes (Teodor, Oleg)


This option greatly improves update speed at a small penalty in search speed.

xxx_pattern_ops indexes can now be used for simple equality comparisons, not only for LIKE (Tom)

E.57.3.5.2. Full Text Indexes

Remove the requirement to use @@@ when doing GIN weighted lookups on full text indexes (Tom, Teodor)
The normal @@ text search operator can be used instead.

Add an optimizer selectivity function for @@ text search operations (Jan Urbanski)
1526

Notes de version

Allow prefix matching in full text searches (Teodor Sigaev, Oleg Bartunov)

Support multi-column GIN indexes (Teodor Sigaev)

Improve support for Nepali language and Devanagari alphabet (Teodor)

E.57.3.5.3. VACUUM

Track free space in separate per-relation fork files (Heikki)


Free space discovered by VACUUM is now recorded in *_fsm files, rather than in a fixed-sized shared memory area. The
max_fsm_pages and max_fsm_relations settings have been removed, greatly simplifying administration of free space
management.

Add a visibility map to track pages that do not require vacuuming (Heikki)
This allows VACUUM to avoid scanning all of a table when only a portion of the table needs vacuuming. The visibility map
is stored in per-relation fork files.

Add vacuum_freeze_table_age parameter to control when VACUUM should ignore the visibility map and do a full
table scan to freeze tuples (Heikki)

Track transaction snapshots more carefully (Alvaro)


This improves VACUUM's ability to reclaim space in the presence of long-running transactions.

Add ability to specify per-relation autovacuum and TOAST parameters in CREATE TABLE (Alvaro, Euler Taveira de Oliveira)
Autovacuum options used to be stored in a system table.

Add --freeze option to vacuumdb (Bruce)

E.57.3.6. Data Types

Add a CaseSensitive option for text search synonym dictionaries (Simon)

Improve the precision of NUMERIC division (Tom)

Add basic arithmetic operators for int2 with int8 (Tom)


This eliminates the need for explicit casting in some situations.

Allow UUID input to accept an optional hyphen after every fourth digit (Robert Haas)

Allow on/off as input for the boolean data type (Itagaki Takahiro)

Allow spaces around NaN in the input string for type numeric (Sam Mason)

E.57.3.6.1. Temporal Data Types

Reject year 0 BC and years 000 and 0000 (Tom)


Previously these were interpreted as 1 BC. (Note: years 0 and 00 are still assumed to be the year 2000.)

Include SGT (Singapore time) in the default list of known time zone abbreviations (Tom)

Support infinity and -infinity as values of type date (Tom)

Make parsing of interval literals more standard-compliant (Tom, Ron Mayer)


For example, INTERVAL '1' YEAR now does what it's supposed to.

Allow interval fractional-seconds precision to be specified after the second keyword, for SQL standard compliance (Tom)
Formerly the precision had to be specified after the keyword interval. (For backwards compatibility, this syntax is still supported, though deprecated.) Data type definitions will now be output using the standard format.

Support the IS0 8601 interval syntax (Ron Mayer, Kevin Grittner)
For example, INTERVAL 'P1Y2M3DT4H5M6.7S' is now supported.

Add IntervalStyle parameter which controls how interval values are output (Ron Mayer)
1527

Notes de version

Valid values are: postgres, postgres_verbose, sql_standard, iso_8601. This setting also controls the handling
of negative interval input when only some fields have positive/negative designations.

Improve consistency of handling of fractional seconds in timestamp and interval output (Ron Mayer)

E.57.3.6.2. Arrays

Improve the handling of casts applied to ARRAY[] constructs, such as ARRAY[...]::integer[] (Brendan Jurd)
Formerly PostgreSQL attempted to determine a data type for the ARRAY[] construct without reference to the ensuing cast.
This could fail unnecessarily in many cases, in particular when the ARRAY[] construct was empty or contained only ambiguous entries such as NULL. Now the cast is consulted to determine the type that the array elements must be.

Make SQL-syntax ARRAY dimensions optional to match the SQL standard (Peter)

Add array_ndims() to return the number of dimensions of an array (Robert Haas)

Add array_length() to return the length of an array for a specified dimension (Jim Nasby, Robert Haas, Peter Eisentraut)

Add aggregate function array_agg(), which returns all aggregated values as a single array (Robert Haas, Jeff Davis, Peter)

Add unnest(), which converts an array to individual row values (Tom)


This is the opposite of array_agg().

Add array_fill() to create arrays initialized with a value (Pavel Stehule)

Add generate_subscripts() to simplify generating the range of an array's subscripts (Pavel Stehule)

E.57.3.6.3. Wide-Value Storage (TOAST)

Consider TOAST compression on values as short as 32 bytes (previously 256 bytes) (Greg Stark)

Require 25% minimum space savings before using TOAST compression (previously 20% for small values and any-savings-at-all for large values) (Greg)

Improve TOAST heuristics for rows that have a mix of large and small toastable fields, so that we prefer to push large values
out of line and don't compress small values unnecessarily (Greg, Tom)

E.57.3.7. Functions

Document that setseed() allows values from -1 to 1 (not just 0 to 1), and enforce the valid range (Kris Jurka)

Add server-side function lo_import(filename, oid) (Tatsuo)

Add quote_nullable(), which behaves like quote_literal() but returns the string NULL for a null argument
(Brendan Jurd)

Improve full text search headline() function to allow extracting several fragments of text (Sushant Sinha)

Add suppress_redundant_updates_trigger() trigger function to avoid overhead for non-data-changing updates


(Andrew)

Add div(numeric, numeric) to perform numeric division without rounding (Tom)

Add timestamp and timestamptz versions of generate_series() (Hitoshi Harada)

E.57.3.7.1. Object Information Functions

Implement current_query() for use by functions that need to know the currently running query (Tomas Doran)

Add pg_get_keywords() to return a list of the parser keywords (Dave Page)

Add pg_get_functiondef() to see a function's definition (Abhijit Menon-Sen)

Allow the second argument of pg_get_expr() to be zero when deparsing an expression that does not contain variables
(Tom)

Modify pg_relation_size() to use regclass (Heikki)


1528

Notes de version

pg_relation_size(data_type_name) no longer works.

Add boot_val and reset_val columns to pg_settings output (Greg Smith)

Add source file name and line number columns to pg_settings output for variables set in a configuration file (Magnus, Alvaro)
For security reasons, these columns are only visible to superusers.

Add support for CURRENT_CATALOG, CURRENT_SCHEMA, SET CATALOG, SET SCHEMA (Peter)
These provide SQL-standard syntax for existing features.

Add pg_typeof() which returns the data type of any value (Brendan Jurd)

Make version() return information about whether the server is a 32- or 64-bit binary (Bruce)

Fix the behavior of information schema columns is_insertable_into and is_updatable to be consistent (Peter)

Improve the behavior of information schema datetime_precision columns (Peter)


These columns now show zero for date columns, and 6 (the default precision) for time, timestamp, and interval without a declared precision, rather than showing null as formerly.

Convert remaining builtin set-returning functions to use OUT parameters (Jaime Casanova)
This makes it possible to call these functions without specifying a column list: pg_show_all_settings(),
pg_lock_status(), pg_prepared_xact(), pg_prepared_statement(), pg_cursor()

Make pg_*_is_visible() and has_*_privilege() functions return NULL for invalid OIDs, rather than reporting
an error (Tom)

Extend has_*_privilege() functions to allow inquiring about the OR of multiple privileges in one call (Stephen Frost,
Tom)

Add has_column_privilege() and has_any_column_privilege() functions (Stephen Frost, Tom)

E.57.3.7.2. Function Creation

Support variadic functions (functions with a variable number of arguments) (Pavel Stehule)
Only trailing arguments can be optional, and they all must be of the same data type.

Support default values for function arguments (Pavel Stehule)

Add CREATE FUNCTION ... RETURNS TABLE clause (Pavel Stehule)

Allow SQL-language functions to return the output of an INSERT/UPDATE/DELETE RETURNING clause (Tom)

E.57.3.7.3. PL/pgSQL Server-Side Language

Support EXECUTE USING for easier insertion of data values into a dynamic query string (Pavel Stehule)

Allow looping over the results of a cursor using a FOR loop (Pavel Stehule)

Support RETURN QUERY EXECUTE (Pavel Stehule)

Improve the RAISE command (Pavel Stehule)

Support DETAIL and HINT fields

Support specification of the SQLSTATE error code

Support an exception name parameter

Allow RAISE without parameters in an exception block to re-throw the current error

Allow specification of SQLSTATE codes in EXCEPTION lists (Pavel Stehule)


This is useful for handling custom SQLSTATE codes.

Support the CASE statement (Pavel Stehule)


1529

Notes de version

Make RETURN QUERY set the special FOUND and GET DIAGNOSTICS ROW_COUNT variables (Pavel Stehule)

Make FETCH and MOVE set the GET DIAGNOSTICS ROW_COUNT variable (Andrew Gierth)

Make EXIT without a label always exit the innermost loop (Tom)
Formerly, if there were a BEGIN block more closely nested than any loop, it would exit that block instead. The new behavior
matches Oracle(TM) and is also what was previously stated by our own documentation.

Make processing of string literals and nested block comments match the main SQL parser's processing (Tom)
In particular, the format string in RAISE now works the same as any other string literal, including being subject to standard_conforming_strings. This change also fixes other cases in which valid commands would fail when standard_conforming_strings is on.

Avoid memory leakage when the same function is called at varying exception-block nesting depths (Tom)

E.57.3.8. Client Applications

Fix pg_ctl restart to preserve command-line arguments (Bruce)

Add -w/--no-password option that prevents password prompting in all utilities that have a -W/--password option
(Peter)

Remove -q (quiet) option of createdb, createuser, dropdb, dropuser (Peter)


These options have had no effect since PostgreSQL 8.3.

E.57.3.8.1. psql

Remove verbose startup banner; now just suggest help (Joshua Drake)

Make help show common backslash commands (Greg Sabino Mullane)

Add \pset format wrapped mode to wrap output to the screen width, or file/pipe output too if \pset columns is set
(Bryce Nesbitt)

Allow all supported spellings of boolean values in \pset, rather than just on and off (Bruce)
Formerly, any string other than off was silently taken to mean true. psql will now complain about unrecognized spellings
(but still take them as true).

Use the pager for wide output (Bruce)

Require a space between a one-letter backslash command and its first argument (Bernd Helmle)
This removes a historical source of ambiguity.

Improve tab completion support for schema-qualified and quoted identifiers (Greg Sabino Mullane)

Add optional on/off argument for \timing (David Fetter)

Display access control rights on multiple lines (Brendan Jurd, Andreas Scherbaum)

Make \l show database access privileges (Andrew Gilligan)

Make \l+ show database sizes, if permissions allow (Andrew Gilligan)

Add the \ef command to edit function definitions (Abhijit Menon-Sen)

E.57.3.8.2. psql \d* commands

Make \d* commands that do not have a pattern argument show system objects only if the S modifier is specified (Greg Sabino
Mullane, Bruce)
The former behavior was inconsistent across different variants of \d, and in most cases it provided no easy way to see just user
objects.

Improve \d* commands to work with older PostgreSQL server versions (back to 7.4), not only the current server version
(Guillaume Lelarge)

Make \d show foreign-key constraints that reference the selected table (Kenneth D'Souza)
1530

Notes de version

Make \d on a sequence show its column values (Euler Taveira de Oliveira)

Add column storage type and other relation options to the \d+ display (Gregory Stark, Euler Taveira de Oliveira)

Show relation size in \dt+ output (Dickson S. Guedes)

Show the possible values of enum types in \dT+ (David Fetter)

Allow \dC to accept a wildcard pattern, which matches either datatype involved in the cast (Tom)

Add a function type column to \df's output, and add options to list only selected types of functions (David Fetter)

Make \df not hide functions that take or return type cstring (Tom)
Previously, such functions were hidden because most of them are datatype I/O functions, which were deemed uninteresting.
The new policy about hiding system functions by default makes this wart unnecessary.

E.57.3.8.3. pg_dump

Add a --no-tablespaces option to pg_dump/pg_dumpall/pg_restore so that dumps can be restored to clusters that have
non-matching tablespace layouts (Gavin Roy)

Remove -d and -D options from pg_dump and pg_dumpall (Tom)


These options were too frequently confused with the option to select a database name in other PostgreSQL client applications. The functionality is still available, but you must now spell out the long option name --inserts or -column-inserts.

Remove -i/--ignore-version option from pg_dump and pg_dumpall (Tom)


Use of this option does not throw an error, but it has no effect. This option was removed because the version checks are necessary for safety.

Disable statement_timeout during dump and restore (Joshua Drake)

Add pg_dump/pg_dumpall option --lock-wait-timeout (David Gould)


This allows dumps to fail if unable to acquire a shared lock within the specified amount of time.

Reorder pg_dump --data-only output to dump tables referenced by foreign keys before the referencing tables (Tom)
This allows data loads when foreign keys are already present. If circular references make a safe ordering impossible, a NOTICE is issued.

Allow pg_dump, pg_dumpall, and pg_restore to use a specified role (Benedek Lszl)

Allow pg_restore to use multiple concurrent connections to do the restore (Andrew)


The number of concurrent connections is controlled by the option --jobs. This is supported only for custom-format archives.

E.57.3.9. Programming Tools


E.57.3.9.1. libpq

Allow the OID to be specified when importing a large object, via new function lo_import_with_oid() (Tatsuo)

Add events support (Andrew Chernow, Merlin Moncure)


This adds the ability to register callbacks to manage private data associated with PGconn and PGresult objects.

Improve error handling to allow the return of multiple error messages as multi-line error reports (Magnus)

Make PQexecParams() and related functions return PGRES_EMPTY_QUERY for an empty query (Tom)
They previously returned PGRES_COMMAND_OK.

Document how to avoid the overhead of WSACleanup() on Windows (Andrew Chernow)

Do not rely on Kerberos tickets to determine the default database username (Magnus)
Previously, a Kerberos-capable build of libpq would use the principal name from any available Kerberos ticket as default database username, even if the connection wasn't using Kerberos authentication. This was deemed inconsistent and confusing. The
1531

Notes de version

default username is now determined the same way with or without Kerberos. Note however that the database username must
still match the ticket when Kerberos authentication is used.
E.57.3.9.2. libpq SSL (Secure Sockets Layer) support

Fix certificate validation for SSL connections (Magnus)


libpq now supports verifying both the certificate and the name of the server when making SSL connections. If a root certificate
is not available to use for verification, SSL connections will fail. The sslmode parameter is used to enable certificate verification and set the level of checking. The default is still not to do any verification, allowing connections to SSL-enabled servers
without requiring a root certificate on the client.

Support wildcard server certificates (Magnus)


If a certificate CN starts with *, it will be treated as a wildcard when matching the hostname, allowing the use of the same certificate for multiple servers.

Allow the file locations for client certificates to be specified (Mark Woodward, Alvaro, Magnus)

Add a PQinitOpenSSL function to allow greater control over OpenSSL/libcrypto initialization (Andrew Chernow)

Make libpq unregister its OpenSSL callbacks when no database connections remain open (Bruce, Magnus, Russell Smith)
This is required for applications that unload the libpq library, otherwise invalid OpenSSL callbacks will remain.

E.57.3.9.3. ecpg

Add localization support for messages (Euler Taveira de Oliveira)

ecpg parser is now automatically generated from the server parser (Michael)
Previously the ecpg parser was hand-maintained.

E.57.3.9.4. Server Programming Interface (SPI)

Add support for single-use plans with out-of-line parameters (Tom)

Add new SPI_OK_REWRITTEN return code for SPI_execute() (Heikki)


This is used when a command is rewritten to another type of command.

Remove unnecessary inclusions from executor/spi.h (Tom)


SPI-using modules might need to add some #include lines if they were depending on spi.h to include things for them.

E.57.3.10. Build Options

Update build system to use Autoconf 2.61 (Peter)

Require GNU bison for source code builds (Peter)


This has effectively been required for several years, but now there is no infrastructure claiming to support other parser tools.

Add pg_config --htmldir option (Peter)

Pass float4 by value inside the server (Zoltan Boszormenyi)


Add configure option --disable-float4-byval to use the old behavior. External C functions that use old-style (version
0) call convention and pass or return float4 values will be broken by this change, so you may need the configure option if you
have such functions and don't want to update them.

Pass float8, int8, and related datatypes by value inside the server on 64-bit platforms (Zoltan Boszormenyi)
Add configure option --disable-float8-byval to use the old behavior. As above, this change might break old-style
external C functions.

Add configure options --with-segsize, --with-blocksize, --with-wal-blocksize, -with-wal-segsize (Zdenek Kotala, Tom)

1532

Notes de version

This simplifies build-time control over several constants that previously could only be changed by editing
pg_config_manual.h.

Allow threaded builds on Solaris 2.5 (Bruce)

Use the system's getopt_long() on Solaris (Zdenek Kotala, Tom)


This makes option processing more consistent with what Solaris users expect.

Add support for the Sun Studio compiler on Linux (Julius Stroffek)

Append the major version number to the backend gettext domain, and the soname major version number to libraries' gettext
domain (Peter)
This simplifies parallel installations of multiple versions.

Add support for code coverage testing with gcov (Michelle Caisse)

Allow out-of-tree builds on Mingw and Cygwin (Richard Evans)

Fix the use of Mingw as a cross-compiling source platform (Peter)

E.57.3.11. Source Code

Support 64-bit time zone data files (Heikki)


This adds support for daylight saving time (DST) calculations beyond the year 2038.

Deprecate use of platform's time_t data type (Tom)


Some platforms have migrated to 64-bit time_t, some have not, and Windows can't make up its mind what it's doing. Define
pg_time_t to have the same meaning as time_t, but always be 64 bits (unless the platform has no 64-bit integer type), and use
that type in all module APIs and on-disk data formats.

Fix bug in handling of the time zone database when cross-compiling (Richard Evans)

Link backend object files in one step, rather than in stages (Peter)

Improve gettext support to allow better translation of plurals (Peter)

Add message translation support to the PL languages (Alvaro, Peter)

Add more DTrace probes (Robert Lor)

Enable DTrace support on Mac OS X Leopard and other non-Solaris platforms (Robert Lor)

Simplify and standardize conversions between C strings and text datums, by providing common functions for the purpose
(Brendan Jurd, Tom)

Clean up the include/catalog/ header files so that frontend programs can include them without including
postgres.h (Zdenek Kotala)

Make name char-aligned, and suppress zero-padding of name entries in indexes (Tom)

Recover better if dynamically-loaded code executes exit() (Tom)

Add a hook to let plug-ins monitor the executor (Itagaki Takahiro)

Add a hook to allow the planner's statistics lookup behavior to be overridden (Simon Riggs)

Add shmem_startup_hook() for custom shared memory requirements (Tom)

Replace the index access method amgetmulti entry point with amgetbitmap, and extend the API for amgettuple to
support run-time determination of operator lossiness (Heikki, Tom, Teodor)
The API for GIN and GiST opclass consistent functions has been extended as well.

Add support for partial-match searches in GIN indexes (Teodor Sigaev, Oleg Bartunov)

Replace pg_class column reltriggers with boolean relhastriggers (Simon)


Also remove unused pg_class columns relukeys, relfkeys, and relrefs.

Add a relistemp column to pg_class to ease identification of temporary tables (Tom)

Move platform FAQs into the main documentation (Peter)


1533

Notes de version

Prevent parser input files from being built with any conflicts (Peter)

Add support for the KOI8U (Ukrainian) encoding (Peter)

Add Japanese message translations (Japan PostgreSQL Users Group)


This used to be maintained as a separate project.

Fix problem when setting LC_MESSAGES on MSVC-built systems (Hiroshi Inoue, Hiroshi Saito, Magnus)

E.57.3.12. Contrib

Add contrib/auto_explain to automatically run EXPLAIN on queries exceeding a specified duration (Itagaki Takahiro, Tom)

Add contrib/btree_gin to allow GIN indexes to handle more datatypes (Oleg, Teodor)

Add contrib/citext to provide a case-insensitive, multibyte-aware text data type (David Wheeler)

Add contrib/pg_stat_statements for server-wide tracking of statement execution statistics (Itagaki Takahiro)

Add duration and query mode options to contrib/pgbench (Itagaki Takahiro)

Make contrib/pgbench use table names pgbench_accounts, pgbench_branches, pgbench_history, and pgbench_tellers,
rather than just accounts, branches, history, and tellers (Tom)
This is to reduce the risk of accidentally destroying real data by running pgbench.

Fix contrib/pgstattuple to handle tables and indexes with over 2 billion pages (Tatsuhito Kasahara)

In contrib/fuzzystrmatch, add a version of the Levenshtein string-distance function that allows the user to specify the
costs of insertion, deletion, and substitution (Volkan Yazici)

Make contrib/ltree support multibyte encodings (laser)

Enable contrib/dblink to use connection information stored in the SQL/MED catalogs (Joe Conway)

Improve contrib/dblink's reporting of errors from the remote server (Joe Conway)

Make contrib/dblink set client_encoding to match the local database's encoding (Joe Conway)
This prevents encoding problems when communicating with a remote database that uses a different encoding.

Make sure contrib/dblink uses a password supplied by the user, and not accidentally taken from the server's .pgpass
file (Joe Conway)
This is a minor security enhancement.

Add fsm_page_contents() to contrib/pageinspect (Heikki)

Modify get_raw_page() to support free space map (*_fsm) files. Also update contrib/pg_freespacemap.

Add support for multibyte encodings to contrib/pg_trgm (Teodor)

Rewrite contrib/intagg to use new functions array_agg() and unnest() (Tom)

Make contrib/pg_standby recover all available WAL before failover (Fujii Masao, Simon, Heikki)
To make this work safely, you now need to set the new recovery_end_command option in recovery.conf to clean up
the trigger file after failover. pg_standby will no longer remove the trigger file itself.

contrib/pg_standby's -l option is now a no-op, because it is unsafe to use a symlink (Simon)

E.58. Release 8.3.23


Release Date
2013-02-07
This release contains a variety of fixes from 8.3.22. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

1534

Notes de version

This is expected to be the last PostgreSQL release in the 8.3.X series. Users are encouraged to update to a newer release branch
soon.

E.58.1. Migration to Version 8.3.23


A dump/restore is not required for those running 8.3.X.
However, if you are upgrading from a version earlier than 8.3.17, see Section E.64, Release 8.3.17 .

E.58.2. Changes

Prevent execution of enum_recv from SQL (Tom Lane)


The function was misdeclared, allowing a simple SQL command to crash the server. In principle an attacker might be able to
use it to examine the contents of server memory. Our thanks to Sumit Soni (via Secunia SVCRP) for reporting this issue.
(CVE-2013-0255)

Fix SQL grammar to allow subscripting or field selection from a sub-SELECT result (Tom Lane)

Protect against race conditions when scanning pg_tablespace (Stephen Frost, Tom Lane)
CREATE DATABASE and DROP DATABASE could misbehave if there were concurrent updates of pg_tablespace entries.

Prevent DROP OWNED from trying to drop whole databases or tablespaces (lvaro Herrera)
For safety, ownership of these objects must be reassigned, not dropped.

Prevent misbehavior when a RowExpr or XmlExpr is parse-analyzed twice (Andres Freund, Tom Lane)
This mistake could be user-visible in contexts such as CREATE TABLE LIKE INCLUDING INDEXES.

Improve defenses against integer overflow in hashtable sizing calculations (Jeff Davis)

Ensure that non-ASCII prompt strings are translated to the correct code page on Windows (Alexander Law, Noah Misch)
This bug affected psql and some other client programs.

Fix possible crash in psql's \? command when not connected to a database (Meng Qingzhong)

Fix one-byte buffer overrun in libpq's PQprintTuples (Xi Wang)


This ancient function is not used anywhere by PostgreSQL itself, but it might still be used by some client code.

Rearrange configure's tests for supplied functions so it is not fooled by bogus exports from libedit/libreadline (Christoph Berg)

Ensure Windows build number increases over time (Magnus Hagander)

Make pgxs build executables with the right .exe suffix when cross-compiling for Windows (Zoltan Boszormenyi)

Add new timezone abbreviation FET (Tom Lane)


This is now used in some eastern-European time zones.

E.59. Release 8.3.22


Release Date
2012-12-06
This release contains a variety of fixes from 8.3.21. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .
The PostgreSQL community will stop releasing updates for the 8.3.X release series in February 2013. Users are encouraged to
update to a newer release branch soon.

E.59.1. Migration to Version 8.3.22


A dump/restore is not required for those running 8.3.X.
However, if you are upgrading from a version earlier than 8.3.17, see Section E.64, Release 8.3.17 .
1535

Notes de version

E.59.2. Changes

Fix multiple bugs associated with CREATE INDEX CONCURRENTLY (Andres Freund, Tom Lane)
Fix CREATE INDEX CONCURRENTLY to use in-place updates when changing the state of an index's pg_index row. This
prevents race conditions that could cause concurrent sessions to miss updating the target index, thus resulting in corrupt
concurrently-created indexes.
Also, fix various other operations to ensure that they ignore invalid indexes resulting from a failed CREATE INDEX
CONCURRENTLY command. The most important of these is VACUUM, because an auto-vacuum could easily be launched
on the table before corrective action can be taken to fix or remove the invalid index.

Avoid corruption of internal hash tables when out of memory (Hitoshi Harada)

Fix planning of non-strict equivalence clauses above outer joins (Tom Lane)
The planner could derive incorrect constraints from a clause equating a non-strict construct to something else, for example
WHERE COALESCE(foo, 0) = 0 when foo is coming from the nullable side of an outer join.

Improve planner's ability to prove exclusion constraints from equivalence classes (Tom Lane)

Fix partial-row matching in hashed subplans to handle cross-type cases correctly (Tom Lane)
This affects multicolumn NOT IN subplans, such as WHERE (a, b) NOT IN (SELECT x, y FROM ...) when for
instance b and y are int4 and int8 respectively. This mistake led to wrong answers or crashes depending on the specific datatypes involved.

Acquire buffer lock when re-fetching the old tuple for an AFTER ROW UPDATE/DELETE trigger (Andres Freund)
In very unusual circumstances, this oversight could result in passing incorrect data to the precheck logic for a foreign-key enforcement trigger. That could result in a crash, or in an incorrect decision about whether to fire the trigger.

Fix REASSIGN OWNED to handle grants on tablespaces (lvaro Herrera)

Ignore incorrect pg_attribute entries for system columns for views (Tom Lane)
Views do not have any system columns. However, we forgot to remove such entries when converting a table to a view. That's
fixed properly for 9.3 and later, but in previous branches we need to defend against existing mis-converted views.

Fix rule printing to dump INSERT INTO table DEFAULT VALUES correctly (Tom Lane)

Guard against stack overflow when there are too many UNION/INTERSECT/EXCEPT clauses in a query (Tom Lane)

Prevent platform-dependent failures when dividing the minimum possible integer value by -1 (Xi Wang, Tom Lane)

Fix possible access past end of string in date parsing (Hitoshi Harada)

Produce an understandable error message if the length of the path name for a Unix-domain socket exceeds the platform-specific limit (Tom Lane, Andrew Dunstan)
Formerly, this would result in something quite unhelpful, such as Non-recoverable failure in name resolution .

Fix memory leaks when sending composite column values to the client (Tom Lane)

Make pg_ctl more robust about reading the postmaster.pid file (Heikki Linnakangas)
Fix race conditions and possible file descriptor leakage.

Fix possible crash in psql if incorrectly-encoded data is presented and the client_encoding setting is a client-only encoding, such as SJIS (Jiang Guiqing)

Fix bugs in the restore.sql script emitted by pg_dump in tar output format (Tom Lane)
The script would fail outright on tables whose names include upper-case characters. Also, make the script capable of restoring
data in --inserts mode as well as the regular COPY mode.

Fix pg_restore to accept POSIX-conformant tar files (Brian Weaver, Tom Lane)
The original coding of pg_dump's tar output mode produced files that are not fully conformant with the POSIX standard.
This has been corrected for version 9.3. This patch updates previous branches so that they will accept both the incorrect and
the corrected formats, in hopes of avoiding compatibility problems when 9.3 comes out.

Fix pg_resetxlog to locate postmaster.pid correctly when given a relative path to the data directory (Tom Lane)
This mistake could lead to pg_resetxlog not noticing that there is an active postmaster using the data directory.
1536

Notes de version

Fix libpq's lo_import() and lo_export() functions to report file I/O errors properly (Tom Lane)

Fix ecpg's processing of nested structure pointer variables (Muhammad Usama)

Make contrib/pageinspect's btree page inspection functions take buffer locks while examining pages (Tom Lane)

Fix pgxs support for building loadable modules on AIX (Tom Lane)
Building modules outside the original source tree didn't work on AIX.

Update time zone data files to tzdata release 2012j for DST law changes in Cuba, Israel, Jordan, Libya, Palestine, Western Samoa, and portions of Brazil.

E.60. Release 8.3.21


Release Date
2012-09-24
This release contains a variety of fixes from 8.3.20. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .
The PostgreSQL community will stop releasing updates for the 8.3.X release series in February 2013. Users are encouraged to
update to a newer release branch soon.

E.60.1. Migration to Version 8.3.21


A dump/restore is not required for those running 8.3.X.
However, if you are upgrading from a version earlier than 8.3.17, see Section E.64, Release 8.3.17 .

E.60.2. Changes

Improve page-splitting decisions in GiST indexes (Alexander Korotkov, Robert Haas, Tom Lane)
Multi-column GiST indexes might suffer unexpected bloat due to this error.

Fix cascading privilege revoke to stop if privileges are still held (Tom Lane)
If we revoke a grant option from some role X, but X still holds that option via a grant from someone else, we should not recursively revoke the corresponding privilege from role(s) Y that X had granted it to.

Fix handling of SIGFPE when PL/Perl is in use (Andres Freund)


Perl resets the process's SIGFPE handler to SIG_IGN, which could result in crashes later on. Restore the normal Postgres signal handler after initializing PL/Perl.

Prevent PL/Perl from crashing if a recursive PL/Perl function is redefined while being executed (Tom Lane)

Work around possible misoptimization in PL/Perl (Tom Lane)


Some Linux distributions contain an incorrect version of pthread.h that results in incorrect compiled code in PL/Perl, leading to crashes if a PL/Perl function calls another one that throws an error.

Update time zone data files to tzdata release 2012f for DST law changes in Fiji

E.61. Release 8.3.20


Release Date
2012-08-17
This release contains a variety of fixes from 8.3.19. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .
The PostgreSQL community will stop releasing updates for the 8.3.X release series in February 2013. Users are encouraged to
update to a newer release branch soon.
1537

Notes de version

E.61.1. Migration to Version 8.3.20


A dump/restore is not required for those running 8.3.X.
However, if you are upgrading from a version earlier than 8.3.17, see Section E.64, Release 8.3.17 .

E.61.2. Changes

Prevent access to external files/URLs via XML entity references (Noah Misch, Tom Lane)
xml_parse() would attempt to fetch external files or URLs as needed to resolve DTD and entity references in an XML value, thus allowing unprivileged database users to attempt to fetch data with the privileges of the database server. While the external data wouldn't get returned directly to the user, portions of it could be exposed in error messages if the data didn't parse
as valid XML; and in any case the mere ability to check existence of a file might be useful to an attacker. (CVE-2012-3489)

Prevent access to external files/URLs via contrib/xml2's xslt_process() (Peter Eisentraut)


libxslt offers the ability to read and write both files and URLs through stylesheet commands, thus allowing unprivileged database users to both read and write data with the privileges of the database server. Disable that through proper use of libxslt's security options. (CVE-2012-3488)
Also, remove xslt_process()'s ability to fetch documents and stylesheets from external files/URLs. While this was a documented feature , it was long regarded as a bad idea. The fix for CVE-2012-3489 broke that capability, and rather than expend effort on trying to fix it, we're just going to summarily remove it.

Prevent too-early recycling of btree index pages (Noah Misch)


When we allowed read-only transactions to skip assigning XIDs, we introduced the possibility that a deleted btree page could
be recycled while a read-only transaction was still in flight to it. This would result in incorrect index search results. The probability of such an error occurring in the field seems very low because of the timing requirements, but nonetheless it should be
fixed.

Fix crash-safety bug with newly-created-or-reset sequences (Tom Lane)


If ALTER SEQUENCE was executed on a freshly created or reset sequence, and then precisely one nextval() call was
made on it, and then the server crashed, WAL replay would restore the sequence to a state in which it appeared that no nextval() had been done, thus allowing the first sequence value to be returned again by the next nextval() call. In particular
this could manifest for serial columns, since creation of a serial column's sequence includes an ALTER SEQUENCE OWNED BY step.

Ensure the backup_label file is fsync'd after pg_start_backup() (Dave Kerr)

Back-patch 9.1 improvement to compress the fsync request queue (Robert Haas)
This improves performance during checkpoints. The 9.1 change has now seen enough field testing to seem safe to back-patch.

Only allow autovacuum to be auto-canceled by a directly blocked process (Tom Lane)


The original coding could allow inconsistent behavior in some cases; in particular, an autovacuum could get canceled after less
than deadlock_timeout grace period.

Improve logging of autovacuum cancels (Robert Haas)

Fix log collector so that log_truncate_on_rotation works during the very first log rotation after server start (Tom
Lane)

Ensure that a whole-row reference to a subquery doesn't include any extra GROUP BY or ORDER BY columns (Tom Lane)

Disallow copying whole-row references in CHECK constraints and index definitions during CREATE TABLE (Tom Lane)
This situation can arise in CREATE TABLE with LIKE or INHERITS. The copied whole-row variable was incorrectly labeled with the row type of the original table not the new one. Rejecting the case seems reasonable for LIKE, since the row types
might well diverge later. For INHERITS we should ideally allow it, with an implicit coercion to the parent table's row type;
but that will require more work than seems safe to back-patch.

Fix memory leak in ARRAY(SELECT ...) subqueries (Heikki Linnakangas, Tom Lane)

Fix extraction of common prefixes from regular expressions (Tom Lane)


The code could get confused by quantified parenthesized subexpressions, such as ^(foo)?bar. This would lead to incorrect
index optimization of searches for such patterns.

Report errors properly in contrib/xml2's xslt_process() (Tom Lane)


1538

Notes de version

Update time zone data files to tzdata release 2012e for DST law changes in Morocco and Tokelau

E.62. Release 8.3.19


Release Date
2012-06-04
This release contains a variety of fixes from 8.3.18. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.62.1. Migration to Version 8.3.19


A dump/restore is not required for those running 8.3.X.
However, if you are upgrading from a version earlier than 8.3.17, see Section E.64, Release 8.3.17 .

E.62.2. Changes

Fix incorrect password transformation in contrib/pgcrypto's DES crypt() function (Solar Designer)
If a password string contained the byte value 0x80, the remainder of the password was ignored, causing the password to be
much weaker than it appeared. With this fix, the rest of the string is properly included in the DES hash. Any stored password
values that are affected by this bug will thus no longer match, so the stored values may need to be updated. (CVE-2012-2143)

Ignore SECURITY DEFINER and SET attributes for a procedural language's call handler (Tom Lane)
Applying such attributes to a call handler could crash the server. (CVE-2012-2655)

Allow numeric timezone offsets in timestamp input to be up to 16 hours away from UTC (Tom Lane)
Some historical time zones have offsets larger than 15 hours, the previous limit. This could result in dumped data values being
rejected during reload.

Fix timestamp conversion to cope when the given time is exactly the last DST transition time for the current timezone (Tom
Lane)
This oversight has been there a long time, but was not noticed previously because most DST-using zones are presumed to have
an indefinite sequence of future DST transitions.

Fix text to name and char to name casts to perform string truncation correctly in multibyte encodings (Karl Schnaitter)

Fix memory copying bug in to_tsquery() (Heikki Linnakangas)

Fix slow session startup when pg_attribute is very large (Tom Lane)
If pg_attribute exceeds one-fourth of shared_buffers, cache rebuilding code that is sometimes needed during session
start would trigger the synchronized-scan logic, causing it to take many times longer than normal. The problem was particularly acute if many new sessions were starting at once.

Ensure sequential scans check for query cancel reasonably often (Merlin Moncure)
A scan encountering many consecutive pages that contain no live tuples would not respond to interrupts meanwhile.

Ensure the Windows implementation of PGSemaphoreLock() clears ImmediateInterruptOK before returning (Tom
Lane)
This oversight meant that a query-cancel interrupt received later in the same query could be accepted at an unsafe time, with
unpredictable but not good consequences.

Show whole-row variables safely when printing views or rules (Abbas Butt, Tom Lane)
Corner cases involving ambiguous names (that is, the name could be either a table or column name of the query) were printed
in an ambiguous way, risking that the view or rule would be interpreted differently after dump and reload. Avoid the ambiguous case by attaching a no-op cast.

Ensure autovacuum worker processes perform stack depth checking properly (Heikki Linnakangas)
Previously, infinite recursion in a function invoked by auto-ANALYZE could crash worker processes.
1539

Notes de version

Fix logging collector to not lose log coherency under high load (Andrew Dunstan)
The collector previously could fail to reassemble large messages if it got too busy.

Fix logging collector to ensure it will restart file rotation after receiving SIGHUP (Tom Lane)

Fix PL/pgSQL's GET DIAGNOSTICS command when the target is the function's first variable (Tom Lane)

Fix several performance problems in pg_dump when the database contains many objects (Jeff Janes, Tom Lane)
pg_dump could get very slow if the database contained many schemas, or if many objects are in dependency loops, or if there
are many owned sequences.

Fix contrib/dblink's dblink_exec() to not leak temporary database connections upon error (Tom Lane)

Update time zone data files to tzdata release 2012c for DST law changes in Antarctica, Armenia, Chile, Cuba, Falkland Islands, Gaza, Haiti, Hebron, Morocco, Syria, and Tokelau Islands; also historical corrections for Canada.

E.63. Release 8.3.18


Release Date
2012-02-27
This release contains a variety of fixes from 8.3.17. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.63.1. Migration to Version 8.3.18


A dump/restore is not required for those running 8.3.X.
However, if you are upgrading from a version earlier than 8.3.17, see Section E.64, Release 8.3.17 .

E.63.2. Changes

Require execute permission on the trigger function for CREATE TRIGGER (Robert Haas)
This missing check could allow another user to execute a trigger function with forged input data, by installing it on a table he
owns. This is only of significance for trigger functions marked SECURITY DEFINER, since otherwise trigger functions run
as the table owner anyway. (CVE-2012-0866)

Convert newlines to spaces in names written in pg_dump comments (Robert Haas)


pg_dump was incautious about sanitizing object names that are emitted within SQL comments in its output script. A name
containing a newline would at least render the script syntactically incorrect. Maliciously crafted object names could present a
SQL injection risk when the script is reloaded. (CVE-2012-0868)

Fix btree index corruption from insertions concurrent with vacuuming (Tom Lane)
An index page split caused by an insertion could sometimes cause a concurrently-running VACUUM to miss removing index
entries that it should remove. After the corresponding table rows are removed, the dangling index entries would cause errors
(such as could not read block N in file ... ) or worse, silently wrong query results after unrelated rows are re-inserted at the
now-free table locations. This bug has been present since release 8.2, but occurs so infrequently that it was not diagnosed until
now. If you have reason to suspect that it has happened in your database, reindexing the affected index will fix things.

Allow non-existent values for some settings in ALTER USER/DATABASE SET (Heikki Linnakangas)
Allow default_text_search_config, default_tablespace, and temp_tablespaces to be set to names that
are not known. This is because they might be known in another database where the setting is intended to be used, or for the tablespace cases because the tablespace might not be created yet. The same issue was previously recognized for
search_path, and these settings now act like that one.

Track the OID counter correctly during WAL replay, even when it wraps around (Tom Lane)
Previously the OID counter would remain stuck at a high value until the system exited replay mode. The practical consequences of that are usually nil, but there are scenarios wherein a standby server that's been promoted to master might take a
long time to advance the OID counter to a reasonable value once values are needed.

Fix regular expression back-references with * attached (Tom Lane)


1540

Notes de version

Rather than enforcing an exact string match, the code would effectively accept any string that satisfies the pattern subexpression referenced by the back-reference symbol.
A similar problem still afflicts back-references that are embedded in a larger quantified expression, rather than being the immediate subject of the quantifier. This will be addressed in a future PostgreSQL release.

Fix recently-introduced memory leak in processing of inet/cidr values (Heikki Linnakangas)


A patch in the December 2011 releases of PostgreSQL caused memory leakage in these operations, which could be significant in scenarios such as building a btree index on such a column.

Avoid double close of file handle in syslogger on Windows (MauMau)


Ordinarily this error was invisible, but it would cause an exception when running on a debug version of Windows.

Fix I/O-conversion-related memory leaks in plpgsql (Andres Freund, Jan Urbanski, Tom Lane)
Certain operations would leak memory until the end of the current function.

Improve pg_dump's handling of alled table columns (Tom Lane)


pg_dump mishandled situations where a child column has a different default expression than its parent column. If the default is
textually identical to the parent's default, but not actually the same (for instance, because of schema search path differences) it
would not be recognized as different, so that after dump and restore the child would be allowed to all the parent's default.
Child columns that are NOT NULL where their parent is not could also be restored subtly incorrectly.

Fix pg_restore's direct-to-database mode for INSERT-style table data (Tom Lane)
Direct-to-database restores from archive files made with --inserts or --column-inserts options fail when using
pg_restore from a release dated September or December 2011, as a result of an oversight in a fix for another problem. The archive file itself is not at fault, and text-mode output is okay.

Fix error in contrib/intarray's int[] & int[] operator (Guillaume Lelarge)


If the smallest integer the two input arrays have in common is 1, and there are smaller values in either array, then 1 would be
incorrectly omitted from the result.

Fix error detection in contrib/pgcrypto's encrypt_iv() and decrypt_iv() (Marko Kreen)


These functions failed to report certain types of invalid-input errors, and would instead return random garbage values for incorrect input.

Fix one-byte buffer overrun in contrib/test_parser (Paul Guyot)


The code would try to read one more byte than it should, which would crash in corner cases. Since contrib/
test_parser is only example code, this is not a security issue in itself, but bad example code is still bad.

Use __sync_lock_test_and_set() for spinlocks on ARM, if available (Martin Pitt)


This function replaces our previous use of the SWPB instruction, which is deprecated and not available on ARMv6 and later.
Reports suggest that the old code doesn't fail in an obvious way on recent ARM boards, but simply doesn't interlock concurrent accesses, leading to bizarre failures in multiprocess operation.

Use -fexcess-precision=standard option when building with gcc versions that accept it (Andrew Dunstan)
This prevents assorted scenarios wherein recent versions of gcc will produce creative results.

Allow use of threaded Python on FreeBSD (Chris Rees)


Our configure script previously believed that this combination wouldn't work; but FreeBSD fixed the problem, so remove that
error check.

E.64. Release 8.3.17


Release Date
2011-12-05
This release contains a variety of fixes from 8.3.16. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .
1541

Notes de version

E.64.1. Migration to Version 8.3.17


A dump/restore is not required for those running 8.3.X.
However,
a
longstanding
error
was
discovered
in
the
definition
of
the
information_schema.referential_constraints view. If you rely on correct results from that view, you should replace its definition as explained in the first changelog item below.
Also, if you are upgrading from a version earlier than 8.3.8, see Section E.73, Release 8.3.8 .

E.64.2. Changes

Fix bugs in information_schema.referential_constraints view (Tom Lane)


This view was being insufficiently careful about matching the foreign-key constraint to the depended-on primary or unique
key constraint. That could result in failure to show a foreign key constraint at all, or showing it multiple times, or claiming that
it depends on a different constraint than the one it really does.
Since the view definition is installed by initdb, merely upgrading will not fix the problem. If you need to fix this in an existing
installation, you can (as a superuser) drop the information_schema schema then re-create it by sourcing SHAREDIR/
information_schema.sql. (Run pg_config --sharedir if you're uncertain where SHAREDIR is.) This must be
repeated in each database to be fixed.

Fix TOAST-related data corruption during CREATE TABLE dest AS SELECT * FROM src or INSERT INTO
dest SELECT * FROM src (Tom Lane)
If a table has been modified by ALTER TABLE ADD COLUMN, attempts to copy its data verbatim to another table could
produce corrupt results in certain corner cases. The problem can only manifest in this precise form in 8.4 and later, but we patched earlier versions as well in case there are other code paths that could trigger the same bug.

Fix race condition during toast table access from stale syscache entries (Tom Lane)
The typical symptom was transient errors like missing chunk number 0 for toast value NNNNN in pg_toast_2619 , where
the cited toast table would always belong to a system catalog.

Make DatumGetInetP() unpack inet datums that have a 1-byte header, and add a new macro, DatumGetInetPP(),
that does not (Heikki Linnakangas)
This change affects no core code, but might prevent crashes in add-on code that expects DatumGetInetP() to produce an
unpacked datum as per usual convention.

Improve locale support in money type's input and output (Tom Lane)
Aside from not supporting all standard lc_monetary formatting options, the input and output functions were inconsistent,
meaning there were locales in which dumped money values could not be re-read.

Don't let transform_null_equals affect CASE foo WHEN NULL ... constructs (Heikki Linnakangas)
transform_null_equals is only supposed to affect foo = NULL expressions written directly by the user, not equality
checks generated internally by this form of CASE.

Change foreign-key trigger creation order to better support self-referential foreign keys (Tom Lane)
For a cascading foreign key that references its own table, a row update will fire both the ON UPDATE trigger and the CHECK
trigger as one event. The ON UPDATE trigger must execute first, else the CHECK will check a non-final state of the row and
possibly throw an inappropriate error. However, the firing order of these triggers is determined by their names, which generally sort in creation order since the triggers have auto-generated names following the convention
RI_ConstraintTrigger_NNNN . A proper fix would require modifying that convention, which we will do in 9.2, but it
seems risky to change it in existing releases. So this patch just changes the creation order of the triggers. Users encountering
this type of error should drop and re-create the foreign key constraint to get its triggers into the right order.

Avoid floating-point underflow while tracking buffer allocation rate (Greg Matthews)
While harmless in itself, on certain platforms this would result in annoying kernel log messages.

Preserve blank lines within commands in psql's command history (Robert Haas)
The former behavior could cause problems if an empty line was removed from within a string literal, for example.

Fix pg_dump to dump user-defined casts between auto-generated types, such as table rowtypes (Tom Lane)

Use the preferred version of xsubpp to build PL/Perl, not necessarily the operating system's main copy (David Wheeler and
1542

Notes de version

Alex Hunsaker)

Fix incorrect coding in contrib/dict_int and contrib/dict_xsyn (Tom Lane)


Some functions incorrectly assumed that memory returned by palloc() is guaranteed zeroed.

Honor query cancel interrupts promptly in pgstatindex() (Robert Haas)

Ensure VPATH builds properly install all server header files (Peter Eisentraut)

Shorten file names reported in verbose error messages (Peter Eisentraut)


Regular builds have always reported just the name of the C file containing the error message call, but VPATH builds formerly
reported an absolute path name.

Fix interpretation of Windows timezone names for Central America (Tom Lane)
Map Central America Standard Time to CST6, not CST6CDT, because DST is generally not observed anywhere in Central
America.

Update time zone data files to tzdata release 2011n for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa;
also historical corrections for Alaska and British East Africa.

E.65. Release 8.3.16


Release Date
2011-09-26
This release contains a variety of fixes from 8.3.15. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.65.1. Migration to Version 8.3.16


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.8, see Section E.73, Release 8.3.8 .

E.65.2. Changes

Fix bugs in indexing of in-doubt HOT-updated tuples (Tom Lane)


These bugs could result in index corruption after reindexing a system catalog. They are not believed to affect user indexes.

Fix multiple bugs in GiST index page split processing (Heikki Linnakangas)
The probability of occurrence was low, but these could lead to index corruption.

Fix possible buffer overrun in tsvector_concat() (Tom Lane)


The function could underestimate the amount of memory needed for its result, leading to server crashes.

Fix crash in xml_recv when processing a standalone parameter (Tom Lane)

Avoid possibly accessing off the end of memory in ANALYZE and in SJIS-2004 encoding conversion (Noah Misch)
This fixes some very-low-probability server crash scenarios.

Fix race condition in relcache init file invalidation (Tom Lane)


There was a window wherein a new backend process could read a stale init file but miss the inval messages that would tell it
the data is stale. The result would be bizarre failures in catalog accesses, typically could not read block 0 in file ... later during startup.

Fix memory leak at end of a GiST index scan (Tom Lane)


Commands that perform many separate GiST index scans, such as verification of a new GiST-based exclusion constraint on a
table already containing many rows, could transiently require large amounts of memory due to this leak.

Fix performance problem when constructing a large, lossy bitmap (Tom Lane)

Fix array- and path-creating functions to ensure padding bytes are zeroes (Tom Lane)
1543

Notes de version

This avoids some situations where the planner will think that semantically-equal constants are not equal, resulting in poor optimization.

Work around gcc 4.6.0 bug that breaks WAL replay (Tom Lane)
This could lead to loss of committed transactions after a server crash.

Fix dump bug for VALUES in a view (Tom Lane)

Disallow SELECT FOR UPDATE/SHARE on sequences (Tom Lane)


This operation doesn't work as expected and can lead to failures.

Defend against integer overflow when computing size of a hash table (Tom Lane)

Fix cases where CLUSTER might attempt to access already-removed TOAST data (Tom Lane)

Fix portability bugs in use of credentials control messages for peer authentication (Tom Lane)

Fix SSPI login when multiple roundtrips are required (Ahmed Shinwari, Magnus Hagander)
The typical symptom of this problem was The function requested is not supported errors during SSPI login.

Fix typo in pg_srand48 seed initialization (Andres Freund)


This led to failure to use all bits of the provided seed. This function is not used on most platforms (only those without srandom), and the potential security exposure from a less-random-than-expected seed seems minimal in any case.

Avoid integer overflow when the sum of LIMIT and OFFSET values exceeds 2^63 (Heikki Linnakangas)

Add overflow checks to int4 and int8 versions of generate_series() (Robert Haas)

Fix trailing-zero removal in to_char() (Marti Raudsepp)


In a format with FM and no digit positions after the decimal point, zeroes to the left of the decimal point could be removed incorrectly.

Fix pg_size_pretty() to avoid overflow for inputs close to 2^63 (Tom Lane)

In pg_ctl, support silent mode for service registrations on Windows (MauMau)

Fix psql's counting of script file line numbers during COPY from a different file (Tom Lane)

Fix pg_restore's direct-to-database mode for standard_conforming_strings (Tom Lane)


pg_restore could emit incorrect commands when restoring directly to a database server from an archive file that had been
made with standard_conforming_strings set to on.

Fix write-past-buffer-end and memory leak in libpq's LDAP service lookup code (Albe Laurenz)

In libpq, avoid failures when using nonblocking I/O and an SSL connection (Martin Pihlak, Tom Lane)

Improve libpq's handling of failures during connection startup (Tom Lane)


In particular, the response to a server report of fork() failure during SSL connection startup is now saner.

Improve libpq's error reporting for SSL failures (Tom Lane)

Make ecpglib write double values with 15 digits precision (Akira Kurosawa)

In ecpglib, be sure LC_NUMERIC setting is restored after an error (Michael Meskes)

Apply upstream fix for blowfish signed-character bug (CVE-2011-2483) (Tom Lane)
contrib/pg_crypto's blowfish encryption code could give wrong results on platforms where char is signed (which is
most), leading to encrypted passwords being weaker than they should be.

Fix memory leak in contrib/seg (Heikki Linnakangas)

Fix pgstatindex() to give consistent results for empty indexes (Tom Lane)

Allow building with perl 5.14 (Alex Hunsaker)

Update configure script's method for probing existence of system functions (Tom Lane)
The version of autoconf we used in 8.3 and 8.2 could be fooled by compilers that perform link-time optimization.

Fix assorted issues with build and install file paths containing spaces (Tom Lane)
1544

Notes de version

Update time zone data files to tzdata release 2011i for DST law changes in Canada, Egypt, Russia, Samoa, and South Sudan.

E.66. Release 8.3.15


Release Date
2011-04-18
This release contains a variety of fixes from 8.3.14. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.66.1. Migration to Version 8.3.15


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.8, see Section E.73, Release 8.3.8 .

E.66.2. Changes

Disallow including a composite type in itself (Tom Lane)


This prevents scenarios wherein the server could recurse infinitely while processing the composite type. While there are some
possible uses for such a structure, they don't seem compelling enough to justify the effort required to make sure it always
works safely.

Avoid potential deadlock during catalog cache initialization (Nikhil Sontakke)


In some cases the cache loading code would acquire share lock on a system index before locking the index's catalog. This
could deadlock against processes trying to acquire exclusive locks in the other, more standard order.

Fix dangling-pointer problem in BEFORE ROW UPDATE trigger handling when there was a concurrent update to the target
tuple (Tom Lane)
This bug has been observed to result in intermittent cannot extract system attribute from virtual tuple failures while trying
to do UPDATE RETURNING ctid. There is a very small probability of more serious errors, such as generating incorrect index entries for the updated tuple.

Disallow DROP TABLE when there are pending deferred trigger events for the table (Tom Lane)
Formerly the DROP would go through, leading to could not open relation with OID nnn errors when the triggers were
eventually fired.

Fix PL/Python memory leak involving array slices (Daniel Popowich)

Fix pg_restore to cope with long lines (over 1KB) in TOC files (Tom Lane)

Put in more safeguards against crashing due to division-by-zero with overly enthusiastic compiler optimization (Aurelien Jarno)

Support use of dlopen() in FreeBSD and OpenBSD on MIPS (Tom Lane)


There was a hard-wired assumption that this system function was not available on MIPS hardware on these systems. Use a
compile-time test instead, since more recent versions have it.

Fix compilation failures on HP-UX (Heikki Linnakangas)

Fix version-incompatibility problem with libintl on Windows (Hiroshi Inoue)

Fix usage of xcopy in Windows build scripts to work correctly under Windows 7 (Andrew Dunstan)
This affects the build scripts only, not installation or usage.

Fix path separator used by pg_regress on Cygwin (Andrew Dunstan)

Update time zone data files to tzdata release 2011f for DST law changes in Chile, Cuba, Falkland Islands, Morocco, Samoa,
and Turkey; also historical corrections for South Australia, Alaska, and Hawaii.

E.67. Release 8.3.14


1545

Notes de version

Release Date
2011-01-31
This release contains a variety of fixes from 8.3.13. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.67.1. Migration to Version 8.3.14


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.8, see Section E.73, Release 8.3.8 .

E.67.2. Changes

Avoid failures when EXPLAIN tries to display a simple-form CASE expression (Tom Lane)
If the CASE's test expression was a constant, the planner could simplify the CASE into a form that confused the expression-display code, resulting in unexpected CASE WHEN clause errors.

Fix assignment to an array slice that is before the existing range of subscripts (Tom Lane)
If there was a gap between the newly added subscripts and the first pre-existing subscript, the code miscalculated how many
entries needed to be copied from the old array's null bitmap, potentially leading to data corruption or crash.

Avoid unexpected conversion overflow in planner for very distant date values (Tom Lane)
The date type supports a wider range of dates than can be represented by the timestamp types, but the planner assumed it could
always convert a date to timestamp with impunity.

Fix pg_restore's text output for large objects (BLOBs) when standard_conforming_strings is on (Tom Lane)
Although restoring directly to a database worked correctly, string escaping was incorrect if pg_restore was asked for SQL text
output and standard_conforming_strings had been enabled in the source database.

Fix erroneous parsing of tsquery values containing ... & !(subexpression) | ... (Tom Lane)
Queries containing this combination of operators were not executed correctly. The same error existed in contrib/intarray's query_int type and contrib/ltree's ltxtquery type.

Fix buffer overrun in contrib/intarray's input function for the query_int type (Apple)
This bug is a security risk since the function's return address could be overwritten. Thanks to Apple Inc's security team for reporting this issue and supplying the fix. (CVE-2010-4015)

Fix bug in contrib/seg's GiST picksplit algorithm (Alexander Korotkov)


This could result in considerable inefficiency, though not actually incorrect answers, in a GiST index on a seg column. If you
have such an index, consider REINDEXing it after installing this update. (This is identical to the bug that was fixed in
contrib/cube in the previous update.)

E.68. Release 8.3.13


Release Date
2010-12-16
This release contains a variety of fixes from 8.3.12. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.68.1. Migration to Version 8.3.13


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.8, see Section E.73, Release 8.3.8 .

E.68.2. Changes
1546

Notes de version

Force the default wal_sync_method to be fdatasync on Linux (Tom Lane, Marti Raudsepp)
The default on Linux has actually been fdatasync for many years, but recent kernel changes caused PostgreSQL to
choose open_datasync instead. This choice did not result in any performance improvement, and caused outright failures
on certain filesystems, notably ext4 with the data=journal mount option.

Fix assorted bugs in WAL replay logic for GIN indexes (Tom Lane)
This could result in bad buffer id: 0 failures or corruption of index contents during replication.

Fix recovery from base backup when the starting checkpoint WAL record is not in the same WAL segment as its redo point
(Jeff Davis)

Fix persistent slowdown of autovacuum workers when multiple workers remain active for a long time (Tom Lane)
The effective vacuum_cost_limit for an autovacuum worker could drop to nearly zero if it processed enough tables, causing it to run extremely slowly.

Add support for detecting register-stack overrun on IA64 (Tom Lane)


The IA64 architecture has two hardware stacks. Full prevention of stack-overrun failures requires checking both.

Add a check for stack overflow in copyObject() (Tom Lane)


Certain code paths could crash due to stack overflow given a sufficiently complex query.

Fix detection of page splits in temporary GiST indexes (Heikki Linnakangas)


It is possible to have a concurrent page split in a temporary index, if for example there is an open cursor scanning the index
when an insertion is done. GiST failed to detect this case and hence could deliver wrong results when execution of the cursor
continued.

Avoid memory leakage while ANALYZE'ing complex index expressions (Tom Lane)

Ensure an index that uses a whole-row Var still depends on its table (Tom Lane)
An index declared like create index i on t (foo(t.*)) would not automatically get dropped when its table was
dropped.

Do not inline a SQL function with multiple OUT parameters (Tom Lane)
This avoids a possible crash due to loss of information about the expected result rowtype.

Behave correctly if ORDER BY, LIMIT, FOR UPDATE, or WITH is attached to the VALUES part of INSERT ... VALUES
(Tom Lane)

Fix constant-folding of COALESCE() expressions (Tom Lane)


The planner would sometimes attempt to evaluate sub-expressions that in fact could never be reached, possibly leading to
unexpected errors.

Fix postmaster crash when connection acceptance (accept() or one of the calls made immediately after it) fails, and the
postmaster was compiled with GSSAPI support (Alexander Chernikov)

Fix missed unlink of temporary files when log_temp_files is active (Tom Lane)
If an error occurred while attempting to emit the log message, the unlink was not done, resulting in accumulation of temp files.

Add print functionality for InhRelation nodes (Tom Lane)


This avoids a failure when debug_print_parse is enabled and certain types of query are executed.

Fix incorrect calculation of distance from a point to a horizontal line segment (Tom Lane)
This bug affected several different geometric distance-measurement operators.

Fix PL/pgSQL's handling of simple expressions to not fail in recursion or error-recovery cases (Tom Lane)

Fix PL/Python's handling of set-returning functions (Jan Urbanski)


Attempts to call SPI functions within the iterator generating a set result would fail.

Fix bug in contrib/cube's GiST picksplit algorithm (Alexander Korotkov)


This could result in considerable inefficiency, though not actually incorrect answers, in a GiST index on a cube column. If you
have such an index, consider REINDEXing it after installing this update.

1547

Notes de version

Don't emit identifier will be truncated notices in contrib/dblink except when creating new connections (Itagaki Takahiro)

Fix potential coredump on missing public key in contrib/pgcrypto (Marti Raudsepp)

Fix memory leak in contrib/xml2's XPath query functions (Tom Lane)

Update time zone data files to tzdata release 2010o for DST law changes in Fiji and Samoa; also historical corrections for
Hong Kong.

E.69. Release 8.3.12


Release Date
2010-10-04
This release contains a variety of fixes from 8.3.11. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.69.1. Migration to Version 8.3.12


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.8, see Section E.73, Release 8.3.8 .

E.69.2. Changes

Use a separate interpreter for each calling SQL userid in PL/Perl and PL/Tcl (Tom Lane)
This change prevents security problems that can be caused by subverting Perl or Tcl code that will be executed later in the
same session under another SQL user identity (for example, within a SECURITY DEFINER function). Most scripting languages offer numerous ways that that might be done, such as redefining standard functions or operators called by the target
function. Without this change, any SQL user with Perl or Tcl language usage rights can do essentially anything with the SQL
privileges of the target function's owner.
The cost of this change is that intentional communication among Perl and Tcl functions becomes more difficult. To provide an
escape hatch, PL/PerlU and PL/TclU functions continue to use only one interpreter per session. This is not considered a security issue since all such functions execute at the trust level of a database superuser already.
It is likely that third-party procedural languages that claim to offer trusted execution have similar security issues. We advise
contacting the authors of any PL you are depending on for security-critical purposes.
Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433).

Prevent possible crashes in pg_get_expr() by disallowing it from being called with an argument that is not one of the system catalog columns it's intended to be used with (Heikki Linnakangas, Tom Lane)

Treat exit code 128 (ERROR_WAIT_NO_CHILDREN) as non-fatal on Windows (Magnus Hagander)


Under high load, Windows processes will sometimes fail at startup with this error code. Formerly the postmaster treated this as
a panic condition and restarted the whole database, but that seems to be an overreaction.

Fix incorrect usage of non-strict OR joinclauses in Append indexscans (Tom Lane)


This is a back-patch of an 8.4 fix that was missed in the 8.3 branch. This corrects an error introduced in 8.3.8 that could cause
incorrect results for outer joins when the inner relation is an allance tree or UNION ALL subquery.

Fix possible duplicate scans of UNION ALL member relations (Tom Lane)

Fix cannot handle unplanned sub-select error (Tom Lane)


This occurred when a sub-select contains a join alias reference that expands into an expression containing another sub-select.

Fix failure to mark cached plans as transient (Tom Lane)


If a plan is prepared while CREATE INDEX CONCURRENTLY is in progress for one of the referenced tables, it is supposed to be re-planned once the index is ready for use. This was not happening reliably.

Reduce PANIC to ERROR in some occasionally-reported btree failure cases, and provide additional detail in the resulting error messages (Tom Lane)
1548

Notes de version

This should improve the system's robustness with corrupted indexes.

Prevent show_session_authorization() from crashing within autovacuum processes (Tom Lane)

Defend against functions returning setof record where not all the returned rows are actually of the same rowtype (Tom Lane)

Fix possible failure when hashing a pass-by-reference function result (Tao Ma, Tom Lane)

Improve merge join's handling of NULLs in the join columns (Tom Lane)
A merge join can now stop entirely upon reaching the first NULL, if the sort order is such that NULLs sort high.

Take care to fsync the contents of lockfiles (both postmaster.pid and the socket lockfile) while writing them (Tom Lane)
This omission could result in corrupted lockfile contents if the machine crashes shortly after postmaster start. That could in
turn prevent subsequent attempts to start the postmaster from succeeding, until the lockfile is manually removed.

Avoid recursion while assigning XIDs to heavily-nested subtransactions (Andres Freund, Robert Haas)
The original coding could result in a crash if there was limited stack space.

Avoid holding open old WAL segments in the walwriter process (Magnus Hagander, Heikki Linnakangas)
The previous coding would prevent removal of no-longer-needed segments.

Fix log_line_prefix's %i escape, which could produce junk early in backend startup (Tom Lane)

Fix possible data corruption in ALTER TABLE ... SET TABLESPACE when archiving is enabled (Jeff Davis)

Allow CREATE DATABASE and ALTER DATABASE ... SET TABLESPACE to be interrupted by query-cancel
(Guillaume Lelarge)

Fix REASSIGN OWNED to handle operator classes and families (Asko Tiidumaa)

Fix possible core dump when comparing two empty tsquery values (Tom Lane)

Fix LIKE's handling of patterns containing % followed by _ (Tom Lane)


We've fixed this before, but there were still some incorrectly-handled cases.

In PL/Python, defend against null pointer results from PyCObject_AsVoidPtr and PyCObject_FromVoidPtr (Peter
Eisentraut)

Make psql recognize DISCARD ALL as a command that should not be encased in a transaction block in autocommit-off
mode (Itagaki Takahiro)

Fix ecpg to process data from RETURNING clauses correctly (Michael Meskes)

Improve contrib/dblink's handling of tables containing dropped columns (Tom Lane)

Fix connection leak after duplicate connection name errors in contrib/dblink (Itagaki Takahiro)

Fix contrib/dblink to handle connection names longer than 62 bytes correctly (Itagaki Takahiro)

Add hstore(text, text) function to contrib/hstore (Robert Haas)


This function is the recommended substitute for the now-deprecated => operator. It was back-patched so that future-proofed
code can be used with older server versions. Note that the patch will be effective only after contrib/hstore is installed or
reinstalled in a particular database. Users might prefer to execute the CREATE FUNCTION command by hand, instead.

Update build infrastructure and documentation to reflect the source code repository's move from CVS to Git (Magnus Hagander and others)

Update time zone data files to tzdata release 2010l for DST law changes in Egypt and Palestine; also historical corrections for
Finland.
This change also adds new names for two Micronesian timezones: Pacific/Chuuk is now preferred over Pacific/Truk (and the
preferred abbreviation is CHUT not TRUT) and Pacific/Pohnpei is preferred over Pacific/Ponape.

Make Windows' N. Central Asia Standard Time timezone map to Asia/Novosibirsk, not Asia/Almaty (Magnus Hagander)
Microsoft changed the DST behavior of this zone in the timezone update from KB976098. Asia/Novosibirsk is a better match
to its new behavior.

E.70. Release 8.3.11


1549

Notes de version

Release Date
2010-05-17
This release contains a variety of fixes from 8.3.10. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.70.1. Migration to Version 8.3.11


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.8, see Section E.73, Release 8.3.8 .

E.70.2. Changes

Enforce restrictions in plperl using an opmask applied to the whole interpreter, instead of using Safe.pm (Tim Bunce,
Andrew Dunstan)
Recent developments have convinced us that Safe.pm is too insecure to rely on for making plperl trustable. This change
removes use of Safe.pm altogether, in favor of using a separate interpreter with an opcode mask that is always applied. Pleasant side effects of the change include that it is now possible to use Perl's strict pragma in a natural way in plperl, and
that Perl's $a and $b variables work as expected in sort routines, and that function compilation is significantly faster.
(CVE-2010-1169)

Prevent PL/Tcl from executing untrustworthy code from pltcl_modules (Tom)


PL/Tcl's feature for autoloading Tcl code from a database table could be exploited for trojan-horse attacks, because there was
no restriction on who could create or insert into that table. This change disables the feature unless pltcl_modules is owned by a
superuser. (However, the permissions on the table are not checked, so installations that really need a less-than-secure modules
table can still grant suitable privileges to trusted non-superusers.) Also, prevent loading code into the unrestricted normal
Tcl interpreter unless we are really going to execute a pltclu function. (CVE-2010-1170)

Fix possible crash if a cache reset message is received during rebuild of a relcache entry (Heikki)
This error was introduced in 8.3.10 while fixing a related failure.

Apply per-function GUC settings while running the language validator for the function (Itagaki Takahiro)
This avoids failures if the function's code is invalid without the setting; an example is that SQL functions may not parse if the
search_path is not correct.

Do not allow an unprivileged user to reset superuser-only parameter settings (Alvaro)


Previously, if an unprivileged user ran ALTER USER ... RESET ALL for himself, or ALTER DATABASE ... RESET
ALL for a database he owns, this would remove all special parameter settings for the user or database, even ones that are only
supposed to be changeable by a superuser. Now, the ALTER will only remove the parameters that the user has permission to
change.

Avoid possible crash during backend shutdown if shutdown occurs when a CONTEXT addition would be made to log entries
(Tom)
In some cases the context-printing function would fail because the current transaction had already been rolled back when it
came time to print a log message.

Ensure the archiver process responds to changes in archive_command as soon as possible (Tom)

Update pl/perl's ppport.h for modern Perl versions (Andrew)

Fix assorted memory leaks in pl/python (Andreas Freund, Tom)

Prevent infinite recursion in psql when expanding a variable that refers to itself (Tom)

Fix psql's \copy to not add spaces around a dot within \copy (select ...) (Tom)
Addition of spaces around the decimal point in a numeric literal would result in a syntax error.

Fix unnecessary GIN indexes do not support whole-index scans errors for unsatisfiable queries using contrib/intarray operators (Tom)

Ensure that contrib/pgstattuple functions respond to cancel interrupts promptly (Tatsuhito Kasahara)

Make server startup deal properly with the case that shmget() returns EINVAL for an existing shared memory segment
1550

Notes de version

(Tom)
This behavior has been observed on BSD-derived kernels including OS X. It resulted in an entirely-misleading startup failure
complaining that the shared memory request size was too large.

Avoid possible crashes in syslogger process on Windows (Heikki)

Deal more robustly with incomplete time zone information in the Windows registry (Magnus)

Update the set of known Windows time zone names (Magnus)

Update time zone data files to tzdata release 2010j for DST law changes in Argentina, Australian Antarctic, Bangladesh,
Mexico, Morocco, Pakistan, Palestine, Russia, Syria, Tunisia; also historical corrections for Taiwan.
Also, add PKST (Pakistan Summer Time) to the default set of timezone abbreviations.

E.71. Release 8.3.10


Release Date
2010-03-15
This release contains a variety of fixes from 8.3.9. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.71.1. Migration to Version 8.3.10


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.8, see Section E.73, Release 8.3.8 .

E.71.2. Changes

Add new configuration parameter ssl_renegotiation_limit to control how often we do session key renegotiation for
an SSL connection (Magnus)
This can be set to zero to disable renegotiation completely, which may be required if a broken SSL library is used. In particular, some vendors are shipping stopgap patches for CVE-2009-3555 that cause renegotiation attempts to fail.

Fix possible deadlock during backend startup (Tom)

Fix possible crashes due to not handling errors during relcache reload cleanly (Tom)

Fix possible crash due to use of dangling pointer to a cached plan (Tatsuo)

Fix possible crashes when trying to recover from a failure in subtransaction start (Tom)

Fix server memory leak associated with use of savepoints and a client encoding different from server's encoding (Tom)

Fix incorrect WAL data emitted during end-of-recovery cleanup of a GIST index page split (Yoichi Hirai)
This would result in index corruption, or even more likely an error during WAL replay, if we were unlucky enough to crash
during end-of-recovery cleanup after having completed an incomplete GIST insertion.

Make substring() for bit types treat any negative length as meaning all the rest of the string (Tom)
The previous coding treated only -1 that way, and would produce an invalid result value for other negative values, possibly
leading to a crash (CVE-2010-0442).

Fix integer-to-bit-string conversions to handle the first fractional byte correctly when the output bit width is wider than the given integer by something other than a multiple of 8 bits (Tom)

Fix some cases of pathologically slow regular expression matching (Tom)

Fix assorted crashes in xml processing caused by sloppy memory management (Tom)
This is a back-patch of changes first applied in 8.4. The 8.3 code was known buggy, but the new code was sufficiently different to not want to back-patch it until it had gotten some field testing.

Fix bug with trying to update a field of an element of a composite-type array column (Tom)

Fix the STOP WAL LOCATION entry in backup history files to report the next WAL segment's name when the end location
1551

Notes de version

is exactly at a segment boundary (Itagaki Takahiro)

Fix some more cases of temporary-file leakage (Heikki)


This corrects a problem introduced in the previous minor release. One case that failed is when a plpgsql function returning set
is called within another function's exception handler.

Improve constraint exclusion processing of boolean-variable cases, in particular make it possible to exclude a partition that has
a bool_column = false constraint (Tom)

When reading pg_hba.conf and related files, do not treat @something as a file inclusion request if the @ appears inside
quote marks; also, never treat @ by itself as a file inclusion request (Tom)
This prevents erratic behavior if a role or database name starts with @. If you need to include a file whose path name contains
spaces, you can still do so, but you must write @"/path to/file" rather than putting the quotes around the whole
construct.

Prevent infinite loop on some platforms if a directory is named as an inclusion target in pg_hba.conf and related files
(Tom)

Fix possible infinite loop if SSL_read or SSL_write fails without setting errno (Tom)
This is reportedly possible with some Windows versions of openssl.

Disallow GSSAPI authentication on local connections, since it requires a hostname to function correctly (Magnus)

Make ecpg report the proper SQLSTATE if the connection disappears (Michael)

Fix psql's numericlocale option to not format strings it shouldn't in latex and troff output formats (Heikki)

Make psql return the correct exit status (3) when ON_ERROR_STOP and --single-transaction are both specified and
an error occurs during the implied COMMIT (Bruce)

Fix plpgsql failure in one case where a composite column is set to NULL (Tom)

Fix possible failure when calling PL/Perl functions from PL/PerlU or vice versa (Tim Bunce)

Add volatile markings in PL/Python to avoid possible compiler-specific misbehavior (Zdenek Kotala)

Ensure PL/Tcl initializes the Tcl interpreter fully (Tom)


The only known symptom of this oversight is that the Tcl clock command misbehaves if using Tcl 8.5 or later.

Prevent crash in contrib/dblink when too many key columns are specified to a dblink_build_sql_* function
(Rushabh Lathia, Joe Conway)

Allow zero-dimensional arrays in contrib/ltree operations (Tom)


This case was formerly rejected as an error, but it's more convenient to treat it the same as a zero-element array. In particular
this avoids unnecessary failures when an ltree operation is applied to the result of ARRAY(SELECT ...) and the sub-select
returns no rows.

Fix assorted crashes in contrib/xml2 caused by sloppy memory management (Tom)

Make building of contrib/xml2 more robust on Windows (Andrew)

Fix race condition in Windows signal handling (Radu Ilie)


One known symptom of this bug is that rows in pg_listener could be dropped under heavy load.

Update time zone data files to tzdata release 2010e for DST law changes in Bangladesh, Chile, Fiji, Mexico, Paraguay, Samoa.

E.72. Release 8.3.9


Release Date
2009-12-14
This release contains a variety of fixes from 8.3.8. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.72.1. Migration to Version 8.3.9


1552

Notes de version

A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.8, see Section E.73, Release 8.3.8 .

E.72.2. Changes

Protect against indirect security threats caused by index functions changing session-local state (Gurjeet Singh, Tom)
This change prevents allegedly-immutable index functions from possibly subverting a superuser's session (CVE-2009-4136).

Reject SSL certificates containing an embedded null byte in the common name (CN) field (Magnus)
This prevents unintended matching of a certificate to a server or client name during SSL validation (CVE-2009-4034).

Fix possible crash during backend-startup-time cache initialization (Tom)

Avoid crash on empty thesaurus dictionary (Tom)

Prevent signals from interrupting VACUUM at unsafe times (Alvaro)


This fix prevents a PANIC if a VACUUM FULL is canceled after it's already committed its tuple movements, as well as transient errors if a plain VACUUM is interrupted after having truncated the table.

Fix possible crash due to integer overflow in hash table size calculation (Tom)
This could occur with extremely large planner estimates for the size of a hashjoin's result.

Fix very rare crash in inet/cidr comparisons (Chris Mikkelson)

Ensure that shared tuple-level locks held by prepared transactions are not ignored (Heikki)

Fix premature drop of temporary files used for a cursor that is accessed within a subtransaction (Heikki)

Fix memory leak in syslogger process when rotating to a new CSV logfile (Tom)

Fix Windows permission-downgrade logic (Jesse Morris)


This fixes some cases where the database failed to start on Windows, often with misleading error messages such as could not
locate matching postgres executable .

Fix incorrect logic for GiST index page splits, when the split depends on a non-first column of the index (Paul Ramsey)

Don't error out if recycling or removing an old WAL file fails at the end of checkpoint (Heikki)
It's better to treat the problem as non-fatal and allow the checkpoint to complete. Future checkpoints will retry the removal.
Such problems are not expected in normal operation, but have been seen to be caused by misdesigned Windows anti-virus and
backup software.

Ensure WAL files aren't repeatedly archived on Windows (Heikki)


This is another symptom that could happen if some other process interfered with deletion of a no-longer-needed file.

Fix PAM password processing to be more robust (Tom)


The previous code is known to fail with the combination of the Linux pam_krb5 PAM module with Microsoft Active Directory as the domain controller. It might have problems elsewhere too, since it was making unjustified assumptions about what
arguments the PAM stack would pass to it.

Raise the maximum authentication token (Kerberos ticket) size in GSSAPI and SSPI authentication methods (Ian Turner)
While the old 2000-byte limit was more than enough for Unix Kerberos implementations, tickets issued by Windows Domain
Controllers can be much larger.

Re-enable collection of access statistics for sequences (Akira Kurosawa)


This used to work but was broken in 8.3.

Fix processing of ownership dependencies during CREATE OR REPLACE FUNCTION (Tom)

Fix incorrect handling of WHERE x=x conditions (Tom)


In some cases these could get ignored as redundant, but they aren't -- they're equivalent to x IS NOT NULL.

Make text search parser accept underscores in XML attributes (Peter)

Fix encoding handling in xml binary input (Heikki)

1553

Notes de version

If the XML header doesn't specify an encoding, we now assume UTF-8 by default; the previous handling was inconsistent.

Fix bug with calling plperl from plperlu or vice versa (Tom)
An error exit from the inner function could result in crashes due to failure to re-select the correct Perl interpreter for the outer
function.

Fix session-lifespan memory leak when a PL/Perl function is redefined (Tom)

Ensure that Perl arrays are properly converted to PostgreSQL arrays when returned by a set-returning PL/Perl function
(Andrew Dunstan, Abhijit Menon-Sen)
This worked correctly already for non-set-returning functions.

Fix rare crash in exception processing in PL/Python (Peter)

In contrib/pg_standby, disable triggering failover with a signal on Windows (Fujii Masao)


This never did anything useful, because Windows doesn't have Unix-style signals, but recent changes made it actually crash.

Ensure psql's flex module is compiled with the correct system header definitions (Tom)
This fixes build failures on platforms where --enable-largefile causes incompatible changes in the generated code.

Make the postmaster ignore any application_name parameter in connection request packets, to improve compatibility
with future libpq versions (Tom)

Update the timezone abbreviation files to match current reality (Joachim Wieland)
This includes adding IDT and SGT to the default timezone abbreviation set.

Update time zone data files to tzdata release 2009s for DST law changes in Antarctica, Argentina, Bangladesh, Fiji, Novokuznetsk, Pakistan, Palestine, Samoa, Syria; also historical corrections for Hong Kong.

E.73. Release 8.3.8


Release Date
2009-09-09
This release contains a variety of fixes from 8.3.7. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.73.1. Migration to Version 8.3.8


A dump/restore is not required for those running 8.3.X. However, if you have any hash indexes on interval columns, you must
REINDEX them after updating to 8.3.8. Also, if you are upgrading from a version earlier than 8.3.5, see Section E.76, Release
8.3.5 .

E.73.2. Changes

Fix Windows shared-memory allocation code (Tsutomu Yamada, Magnus)


This bug led to the often-reported could not reattach to shared memory error message.

Force WAL segment switch during pg_start_backup() (Heikki)


This avoids corner cases that could render a base backup unusable.

Disallow RESET ROLE and RESET SESSION AUTHORIZATION inside security-definer functions (Tom, Heikki)
This covers a case that was missed in the previous patch that disallowed SET ROLE and SET SESSION AUTHORIZATION inside security-definer functions. (See CVE-2007-6600)

Make LOAD of an already-loaded loadable module into a no-op (Tom)


Formerly, LOAD would attempt to unload and re-load the module, but this is unsafe and not all that useful.

Disallow empty passwords during LDAP authentication (Magnus)

1554

Notes de version

Fix handling of sub-SELECTs appearing in the arguments of an outer-level aggregate function (Tom)

Fix bugs associated with fetching a whole-row value from the output of a Sort or Materialize plan node (Tom)

Prevent synchronize_seqscans from changing the results of scrollable and WITH HOLD cursors (Tom)

Revert planner change that disabled partial-index and constraint exclusion optimizations when there were more than 100
clauses in an AND or OR list (Tom)

Fix hash calculation for data type interval (Tom)


This corrects wrong results for hash joins on interval values. It also changes the contents of hash indexes on interval columns.
If you have any such indexes, you must REINDEX them after updating.

Treat to_char(..., 'TH') as an uppercase ordinal suffix with 'HH'/'HH12' (Heikki)


It was previously handled as 'th' (lowercase).

Fix overflow for INTERVAL 'x ms' when x is more than 2 million and integer datetimes are in use (Alex Hunsaker)

Fix calculation of distance between a point and a line segment (Tom)


This led to incorrect results from a number of geometric operators.

Fix money data type to work in locales where currency amounts have no fractional digits, e.g. Japan (Itagaki Takahiro)

Fix LIKE for case where pattern contains %_ (Tom)

Properly round datetime input like 00:12:57.9999999999999999999999999999 (Tom)

Fix memory leaks in XML operations (Tom)

Fix poor choice of page split point in GiST R-tree operator classes (Teodor)

Ensure that a fast shutdown request will forcibly terminate open sessions, even if a smart shutdown was already in progress (Fujii Masao)

Avoid performance degradation in bulk inserts into GIN indexes when the input values are (nearly) in sorted order (Tom)

Correctly enforce NOT NULL domain constraints in some contexts in PL/pgSQL (Tom)

Fix portability issues in plperl initialization (Andrew Dunstan)

Fix pg_ctl to not go into an infinite loop if postgresql.conf is empty (Jeff Davis)

Improve pg_dump's efficiency when there are many large objects (Tamas Vincze)

Use SIGUSR1, not SIGQUIT, as the failover signal for pg_standby (Heikki)

Make pg_standby's maxretries option behave as documented (Fujii Masao)

Make contrib/hstore throw an error when a key or value is too long to fit in its data structure, rather than silently truncating it (Andrew Gierth)

Fix contrib/xml2's xslt_process() to properly handle the maximum number of parameters (twenty) (Tom)

Improve robustness of libpq's code to recover from errors during COPY FROM STDIN (Tom)

Avoid including conflicting readline and editline header files when both libraries are installed (Zdenek Kotala)

Update time zone data files to tzdata release 2009l for DST law changes in Bangladesh, Egypt, Jordan, Pakistan, Argentina/
San_Luis, Cuba, Jordan (historical correction only), Mauritius, Morocco, Palestine, Syria, Tunisia.

E.74. Release 8.3.7


Release Date
2009-03-16
This release contains a variety of fixes from 8.3.6. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.74.1. Migration to Version 8.3.7


1555

Notes de version

A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.5, see Section E.76, Release 8.3.5 .

E.74.2. Changes

Prevent error recursion crashes when encoding conversion fails (Tom)


This change extends fixes made in the last two minor releases for related failure scenarios. The previous fixes were narrowly
tailored for the original problem reports, but we have now recognized that any error thrown by an encoding conversion function could potentially lead to infinite recursion while trying to report the error. The solution therefore is to disable translation
and encoding conversion and report the plain-ASCII form of any error message, if we find we have gotten into a recursive error reporting situation. (CVE-2009-0922)

Disallow CREATE CONVERSION with the wrong encodings for the specified conversion function (Heikki)
This prevents one possible scenario for encoding conversion failure. The previous change is a backstop to guard against other
kinds of failures in the same area.

Fix xpath() to not modify the path expression unless necessary, and to make a saner attempt at it when necessary (Andrew)
The SQL standard suggests that xpath should work on data that is a document fragment, but libxml doesn't support that, and
indeed it's not clear that this is sensible according to the XPath standard. xpath attempted to work around this mismatch by
modifying both the data and the path expression, but the modification was buggy and could cause valid searches to fail. Now,
xpath checks whether the data is in fact a well-formed document, and if so invokes libxml with no change to the data or path
expression. Otherwise, a different modification method that is somewhat less likely to fail is used.

Note
The new modification method is still not 100% satisfactory, and it seems likely that no real solution is possible.
This patch should therefore be viewed as a band-aid to keep from breaking existing applications unnecessarily.
It is likely that PostgreSQL 8.4 will simply reject use of xpath on data that is not a well-formed document.

Fix core dump when to_char() is given format codes that are inappropriate for the type of the data argument (Tom)

Fix possible failure in text search when C locale is used with a multi-byte encoding (Teodor)
Crashes were possible on platforms where wchar_t is narrower than int; Windows in particular.

Fix extreme inefficiency in text search parser's handling of an email-like string containing multiple @ characters (Heikki)

Fix planner problem with sub-SELECT in the output list of a larger subquery (Tom)
The known symptom of this bug is a failed to locate grouping columns error that is dependent on the datatype involved;
but there could be other issues as well.

Fix decompilation of CASE WHEN with an implicit coercion (Tom)


This mistake could lead to Assert failures in an Assert-enabled build, or an unexpected CASE WHEN clause error message
in other cases, when trying to examine or dump a view.

Fix possible misassignment of the owner of a TOAST table's rowtype (Tom)


If CLUSTER or a rewriting variant of ALTER TABLE were executed by someone other than the table owner, the pg_type
entry for the table's TOAST table would end up marked as owned by that someone. This caused no immediate problems, since
the permissions on the TOAST rowtype aren't examined by any ordinary database operation. However, it could lead to unexpected failures if one later tried to drop the role that issued the command (in 8.1 or 8.2), or owner of data type appears to be
invalid warnings from pg_dump after having done so (in 8.3).

Change UNLISTEN to exit quickly if the current session has never executed any LISTEN command (Tom)
Most of the time this is not a particularly useful optimization, but since DISCARD ALL invokes UNLISTEN, the previous
coding caused a substantial performance problem for applications that made heavy use of DISCARD ALL.

Fix PL/pgSQL to not treat INTO after INSERT as an INTO-variables clause anywhere in the string, not only at the start; in
particular, don't fail for INSERT INTO within CREATE RULE (Tom)

Clean up PL/pgSQL error status variables fully at block exit (Ashesh Vashi and Dave Page)
This is not a problem for PL/pgSQL itself, but the omission could cause the PL/pgSQL Debugger to crash while examining the
state of a function.
1556

Notes de version

Retry failed calls to CallNamedPipe() on Windows (Steve Marshall, Magnus)


It appears that this function can sometimes fail transiently; we previously treated any failure as a hard error, which could
confuse LISTEN/NOTIFY as well as other operations.

Add MUST (Mauritius Island Summer Time) to the default list of known timezone abbreviations (Xavier Bugaud)

E.75. Release 8.3.6


Release Date
2009-02-02
This release contains a variety of fixes from 8.3.5. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.75.1. Migration to Version 8.3.6


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.5, see Section E.76, Release 8.3.5 .

E.75.2. Changes

Make DISCARD ALL release advisory locks, in addition to everything it already did (Tom)
This was decided to be the most appropriate behavior. This could affect existing applications, however.

Fix whole-index GiST scans to work correctly (Teodor)


This error could cause rows to be lost if a table is clustered on a GiST index.

Fix crash of xmlconcat(NULL) (Peter)

Fix possible crash in ispell dictionary if high-bit-set characters are used as flags (Teodor)
This is known to be done by one widely available Norwegian dictionary, and the same condition may exist in others.

Fix misordering of pg_dump output for composite types (Tom)


The most likely problem was for user-defined operator classes to be dumped after indexes or views that needed them.

Improve handling of URLs in headline() function (Teodor)

Improve handling of overlength headlines in headline() function (Teodor)

Prevent possible Assert failure or misconversion if an encoding conversion is created with the wrong conversion function for
the specified pair of encodings (Tom, Heikki)

Fix possible Assert failure if a statement executed in PL/pgSQL is rewritten into another kind of statement, for example if an
INSERT is rewritten into an UPDATE (Heikki)

Ensure that a snapshot is available to datatype input functions (Tom)


This primarily affects domains that are declared with CHECK constraints involving user-defined stable or immutable functions.
Such functions typically fail if no snapshot has been set.

Make it safer for SPI-using functions to be used within datatype I/O; in particular, to be used in domain check constraints
(Tom)

Avoid unnecessary locking of small tables in VACUUM (Heikki)

Fix a problem that sometimes kept ALTER TABLE ENABLE/DISABLE RULE from being recognized by active sessions
(Tom)

Fix a problem that made UPDATE RETURNING tableoid return zero instead of the correct OID (Tom)

Allow functions declared as taking ANYARRAY to work on the pg_statistic columns of that type (Tom)
This used to work, but was unintentionally broken in 8.3.

Fix planner misestimation of selectivity when transitive equality is applied to an outer-join clause (Tom)
1557

Notes de version

This could result in bad plans for queries like ... from a left join b on a.a1 = b.b1 where a.a1 = 42
...

Improve optimizer's handling of long IN lists (Tom)


This change avoids wasting large amounts of time on such lists when constraint exclusion is enabled.

Prevent synchronous scan during GIN index build (Tom)


Because GIN is optimized for inserting tuples in increasing TID order, choosing to use a synchronous scan could slow the
build by a factor of three or more.

Ensure that the contents of a holdable cursor don't depend on the contents of TOAST tables (Tom)
Previously, large field values in a cursor result might be represented as TOAST pointers, which would fail if the referenced
table got dropped before the cursor is read, or if the large value is deleted and then vacuumed away. This cannot happen with
an ordinary cursor, but it could with a cursor that is held past its creating transaction.

Fix memory leak when a set-returning function is terminated without reading its whole result (Tom)

Fix encoding conversion problems in XML functions when the database encoding isn't UTF-8 (Tom)

Fix contrib/dblink's dblink_get_result(text,bool) function (Joe)

Fix possible garbage output from contrib/sslinfo functions (Tom)

Fix incorrect behavior of contrib/tsearch2 compatibility trigger when it's fired more than once in a command (Teodor)

Fix possible mis-signaling in autovacuum (Heikki)

Support running as a service on Windows 7 beta (Dave and Magnus)

Fix ecpg's handling of varchar structs (Michael)

Fix configure script to properly report failure when unable to obtain linkage information for PL/Perl (Andrew)

Make all documentation reference pgsql-bugs and/or pgsql-hackers as appropriate, instead of the nowdecommissioned pgsql-ports and pgsql-patches mailing lists (Tom)

Update time zone data files to tzdata release 2009a (for Kathmandu and historical DST corrections in Switzerland, Cuba)

E.76. Release 8.3.5


Release Date
2008-11-03
This release contains a variety of fixes from 8.3.4. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.76.1. Migration to Version 8.3.5


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.1, see Section E.80, Release 8.3.1 . Also, if you were running a previous 8.3.X release, it is recommended to REINDEX all GiST indexes after the upgrade.

E.76.2. Changes

Fix GiST index corruption due to marking the wrong index entry dead after a deletion (Teodor)
This would result in index searches failing to find rows they should have found. Corrupted indexes can be fixed with REINDEX.

Fix backend crash when the client encoding cannot represent a localized error message (Tom)
We have addressed similar issues before, but it would still fail if the character has no equivalent message itself couldn't be
converted. The fix is to disable localization and send the plain ASCII error message when we detect such a situation.

Fix possible crash in bytea-to-XML mapping (Michael McMaster)


1558

Notes de version

Fix possible crash when deeply nested functions are invoked from a trigger (Tom)

Improve optimization of expression IN (expression-list) queries (Tom, per an idea from Robert Haas)
Cases in which there are query variables on the right-hand side had been handled less efficiently in 8.2.x and 8.3.x than in
prior versions. The fix restores 8.1 behavior for such cases.

Fix mis-expansion of rule queries when a sub-SELECT appears in a function call in FROM, a multi-row VALUES list, or a RETURNING list (Tom)
The usual symptom of this problem is an unrecognized node type error.

Fix Assert failure during rescan of an IS NULL search of a GiST index (Teodor)

Fix memory leak during rescan of a hashed aggregation plan (Neil)

Ensure an error is reported when a newly-defined PL/pgSQL trigger function is invoked as a normal function (Tom)

Force a checkpoint before CREATE DATABASE starts to copy files (Heikki)


This prevents a possible failure if files had recently been deleted in the source database.

Prevent possible collision of relfilenode numbers when moving a table to another tablespace with ALTER SET TABLESPACE (Heikki)
The command tried to re-use the existing filename, instead of picking one that is known unused in the destination directory.

Fix incorrect text search headline generation when single query item matches first word of text (Sushant Sinha)

Fix improper display of fractional seconds in interval values when using a non-ISO datestyle in an -enable-integer-datetimes build (Ron Mayer)

Make ILIKE compare characters case-insensitively even when they're escaped (Andrew)

Ensure DISCARD is handled properly by statement logging (Tom)

Fix incorrect logging of last-completed-transaction time during PITR recovery (Tom)

Ensure SPI_getvalue and SPI_getbinval behave correctly when the passed tuple and tuple descriptor have different
numbers of columns (Tom)
This situation is normal when a table has had columns added or removed, but these two functions didn't handle it properly. The
only likely consequence is an incorrect error indication.

Mark SessionReplicationRole as PGDLLIMPORT so it can be used by Slony on Windows (Magnus)

Fix small memory leak when using libpq's gsslib parameter (Magnus)
The space used by the parameter string was not freed at connection close.

Ensure libgssapi is linked into libpq if needed (Markus Schaaf)

Fix ecpg's parsing of CREATE ROLE (Michael)

Fix recent breakage of pg_ctl restart (Tom)

Ensure pg_control is opened in binary mode (Itagaki Takahiro)


pg_controldata and pg_resetxlog did this incorrectly, and so could fail on Windows.

Update time zone data files to tzdata release 2008i (for DST law changes in Argentina, Brazil, Mauritius, Syria)

E.77. Release 8.3.4


Release Date
2008-09-22
This release contains a variety of fixes from 8.3.3. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.77.1. Migration to Version 8.3.4


1559

Notes de version

A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.1, see Section E.80, Release 8.3.1 .

E.77.2. Changes

Fix bug in btree WAL recovery code (Heikki)


Recovery failed if the WAL ended partway through a page split operation.

Fix potential use of wrong cutoff XID for HOT page pruning (Alvaro)
This error created a risk of corruption in system catalogs that are consulted by VACUUM: dead tuple versions might be removed too soon. The impact of this on actual database operations would be minimal, since the system doesn't follow MVCC rules
while examining catalogs, but it might result in transiently wrong output from pg_dump or other client programs.

Fix potential miscalculation of datfrozenxid (Alvaro)


This error may explain some recent reports of failure to remove old pg_clog data.

Fix incorrect HOT updates after pg_class is reindexed (Tom)


Corruption of pg_class could occur if REINDEX TABLE pg_class was followed in the same session by an ALTER
TABLE RENAME or ALTER TABLE SET SCHEMA command.

Fix missed combo cid case (Karl Schnaitter)


This error made rows incorrectly invisible to a transaction in which they had been deleted by multiple subtransactions that all
aborted.

Prevent autovacuum from crashing if the table it's currently checking is deleted at just the wrong time (Alvaro)

Widen local lock counters from 32 to 64 bits (Tom)


This responds to reports that the counters could overflow in sufficiently long transactions, leading to unexpected lock is already held errors.

Fix possible duplicate output of tuples during a GiST index scan (Teodor)

Regenerate foreign key checking queries from scratch when either table is modified (Tom)
Previously, 8.3 would attempt to replan the query, but would work from previously generated query text. This led to failures if
a table or column was renamed.

Fix missed permissions checks when a view contains a simple UNION ALL construct (Heikki)
Permissions for the referenced tables were checked properly, but not permissions for the view itself.

Add checks in executor startup to ensure that the tuples produced by an INSERT or UPDATE will match the target table's
current rowtype (Tom)
This situation is believed to be impossible in 8.3, but it can happen in prior releases, so a check seems prudent.

Fix possible repeated drops during DROP OWNED (Tom)


This would typically result in strange errors such as cache lookup failed for relation NNN .

Fix several memory leaks in XML operations (Kris Jurka, Tom)

Fix xmlserialize() to raise error properly for unacceptable target data type (Tom)

Fix a couple of places that mis-handled multibyte characters in text search configuration file parsing (Tom)
Certain characters occurring in configuration files would always cause invalid byte sequence for encoding failures.

Provide file name and line number location for all errors reported in text search configuration files (Tom)

Fix AT TIME ZONE to first try to interpret its timezone argument as a timezone abbreviation, and only try it as a full timezone name if that fails, rather than the other way around as formerly (Tom)
The timestamp input functions have always resolved ambiguous zone names in this order. Making AT TIME ZONE do so as
well improves consistency, and fixes a compatibility bug introduced in 8.1: in ambiguous cases we now behave the same as
8.0 and before did, since in the older versions AT TIME ZONE accepted only abbreviations.

Fix datetime input functions to correctly detect integer overflow when running on a 64-bit platform (Tom)

Prevent integer overflows during units conversion when displaying a configuration parameter that has units (Tom)
1560

Notes de version

Improve performance of writing very long log messages to syslog (Tom)

Allow spaces in the suffix part of an LDAP URL in pg_hba.conf (Tom)

Fix bug in backwards scanning of a cursor on a SELECT DISTINCT ON query (Tom)

Fix planner bug that could improperly push down IS NULL tests below an outer join (Tom)
This was triggered by occurrence of IS NULL tests for the same relation in all arms of an upper OR clause.

Fix planner bug with nested sub-select expressions (Tom)


If the outer sub-select has no direct dependency on the parent query, but the inner one does, the outer value might not get recalculated for new parent query rows.

Fix planner to estimate that GROUP BY expressions yielding boolean results always result in two groups, regardless of the expressions' contents (Tom)
This is very substantially more accurate than the regular GROUP BY estimate for certain boolean tests like col IS NULL.

Fix PL/pgSQL to not fail when a FOR loop's target variable is a record containing composite-type fields (Tom)

Fix PL/Tcl to behave correctly with Tcl 8.5, and to be more careful about the encoding of data sent to or from Tcl (Tom)

Improve performance of PQescapeBytea() (Rudolf Leitgeb)

On Windows, work around a Microsoft bug by preventing libpq from trying to send more than 64kB per system call (Magnus)

Fix ecpg to handle variables properly in SET commands (Michael)

Improve pg_dump and pg_restore's error reporting after failure to send a SQL command (Tom)

Fix pg_ctl to properly preserve postmaster command-line arguments across a restart (Bruce)

Fix erroneous WAL file cutoff point calculation in pg_standby (Simon)

Update time zone data files to tzdata release 2008f (for DST law changes in Argentina, Bahamas, Brazil, Mauritius, Morocco,
Pakistan, Palestine, and Paraguay)

E.78. Release 8.3.3


Release Date
2008-06-12
This release contains one serious and one minor bug fix over 8.3.2. For information about new features in the 8.3 major release,
see Section E.81, Release 8.3 .

E.78.1. Migration to Version 8.3.3


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.1, see Section E.80, Release 8.3.1 .

E.78.2. Changes

Make pg_get_ruledef() parenthesize negative constants (Tom)


Before this fix, a negative constant in a view or rule might be dumped as, say, -42::integer, which is subtly incorrect: it
should be (-42)::integer due to operator precedence rules. Usually this would make little difference, but it could interact with another recent patch to cause PostgreSQL to reject what had been a valid SELECT DISTINCT view query. Since
this could result in pg_dump output failing to reload, it is being treated as a high-priority fix. The only released versions in
which dump output is actually incorrect are 8.3.1 and 8.2.7.

Make ALTER AGGREGATE ... OWNER TO update pg_shdepend (Tom)


This oversight could lead to problems if the aggregate was later involved in a DROP OWNED or REASSIGN OWNED operation.

E.79. Release 8.3.2


1561

Notes de version

Release Date
never released
This release contains a variety of fixes from 8.3.1. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.79.1. Migration to Version 8.3.2


A dump/restore is not required for those running 8.3.X. However, if you are upgrading from a version earlier than 8.3.1, see Section E.80, Release 8.3.1 .

E.79.2. Changes

Fix ERRORDATA_STACK_SIZE exceeded crash that occurred on Windows when using UTF-8 database encoding and a
different client encoding (Tom)

Fix incorrect archive truncation point calculation for the %r macro in recovery_command parameters (Simon)
This could lead to data loss if a warm-standby script relied on %r to decide when to throw away WAL segment files.

Fix ALTER TABLE ADD COLUMN ... PRIMARY KEY so that the new column is correctly checked to see if it's been initialized to all non-nulls (Brendan Jurd)
Previous versions neglected to check this requirement at all.

Fix REASSIGN OWNED so that it works on procedural languages too (Alvaro)

Fix problems with SELECT FOR UPDATE/SHARE occurring as a subquery in a query with a non-SELECT top-level operation (Tom)

Fix possible CREATE TABLE failure when alling the same constraint from multiple parent relations that alled that
constraint from a common ancestor (Tom)

Fix pg_get_ruledef() to show the alias, if any, attached to the target table of an UPDATE or DELETE (Tom)

Restore the pre-8.3 behavior that an out-of-range block number in a TID being used in a TidScan plan results in silently not
matching any rows (Tom)
8.3.0 and 8.3.1 threw an error instead.

Fix GIN bug that could result in a too many LWLocks taken failure (Teodor)

Fix broken GiST comparison function for tsquery (Teodor)

Fix tsvector_update_trigger() and ts_stat() to accept domains over the types they expect to work with (Tom)

Fix failure to support enum data types as foreign keys (Tom)

Avoid possible crash when decompressing corrupted data (Zdenek Kotala)

Fix race conditions between delayed unlinks and DROP DATABASE (Heikki)
In the worst case this could result in deleting a newly created table in a new database that happened to get the same OID as the
recently-dropped one; but of course that is an extremely low-probability scenario.

Repair two places where SIGTERM exit of a backend could leave corrupted state in shared memory (Tom)
Neither case is very important if SIGTERM is used to shut down the whole database cluster together, but there was a problem
if someone tried to SIGTERM individual backends.

Fix possible crash due to incorrect plan generated for an x IN (SELECT y FROM ...) clause when x and y have different data types; and make sure the behavior is semantically correct when the conversion from y's type to x's type is lossy
(Tom)

Fix oversight that prevented the planner from substituting known Param values as if they were constants (Tom)
This mistake partially disabled optimization of unnamed extended-Query statements in 8.3.0 and 8.3.1: in particular the LIKEto-indexscan optimization would never be applied if the LIKE pattern was passed as a parameter, and constraint exclusion depending on a parameter value didn't work either.

Fix planner failure when an indexable MIN or MAX aggregate is used with DISTINCT or ORDER BY (Tom)
1562

Notes de version

Fix planner to ensure it never uses a physical tlist for a plan node that is feeding a Sort node (Tom)
This led to the sort having to push around more data than it really needed to, since unused column values were included in the
sorted data.

Avoid unnecessary copying of query strings (Tom)


This fixes a performance problem introduced in 8.3.0 when a very large number of commands are submitted as a single query
string.

Make TransactionIdIsCurrentTransactionId() use binary search instead of linear search when checking childtransaction XIDs (Heikki)
This fixes some cases in which 8.3.0 was significantly slower than earlier releases.

Fix conversions between ISO-8859-5 and other encodings to handle Cyrillic Yo characters (e and E with two dots)
(Sergey Burladyan)

Fix several datatype input functions, notably array_in(), that were allowing unused bytes in their results to contain uninitialized, unpredictable values (Tom)
This could lead to failures in which two apparently identical literal values were not seen as equal, resulting in the parser complaining about unmatched ORDER BY and DISTINCT expressions.

Fix a corner case in regular-expression substring matching (substring(string from pattern)) (Tom)
The problem occurs when there is a match to the pattern overall but the user has specified a parenthesized subexpression and
that subexpression hasn't got a match. An example is substring('foo' from 'foo(bar)?'). This should return
NULL, since (bar) isn't matched, but it was mistakenly returning the whole-pattern match instead (ie, foo).

Prevent cancellation of an auto-vacuum that was launched to prevent XID wraparound (Alvaro)

Improve ANALYZE's handling of in-doubt tuples (those inserted or deleted by a not-yet-committed transaction) so that the
counts it reports to the stats collector are more likely to be correct (Pavan Deolasee)

Fix initdb to reject a relative path for its --xlogdir (-X) option (Tom)

Make psql print tab characters as an appropriate number of spaces, rather than \x09 as was done in 8.3.0 and 8.3.1 (Bruce)

Update time zone data files to tzdata release 2008c (for DST law changes in Morocco, Iraq, Choibalsan, Pakistan, Syria, Cuba,
and Argentina/San_Luis)

Add ECPGget_PGconn() function to ecpglib (Michael)

Fix incorrect result from ecpg's PGTYPEStimestamp_sub() function (Michael)

Fix handling of continuation line markers in ecpg (Michael)

Fix possible crashes in contrib/cube functions (Tom)

Fix core dump in contrib/xml2's xpath_table() function when the input query returns a NULL value (Tom)

Fix contrib/xml2's makefile to not override CFLAGS, and make it auto-configure properly for libxslt present or not (Tom)

E.80. Release 8.3.1


Release Date
2008-03-17
This release contains a variety of fixes from 8.3.0. For information about new features in the 8.3 major release, see Section E.81,
Release 8.3 .

E.80.1. Migration to Version 8.3.1


A dump/restore is not required for those running 8.3.X. However, you might need to REINDEX indexes on textual columns after
updating, if you are affected by the Windows locale issue described below.

E.80.2. Changes
1563

Notes de version

Fix character string comparison for Windows locales that consider different character combinations as equal (Tom)
This fix applies only on Windows and only when using UTF-8 database encoding. The same fix was made for all other cases
over two years ago, but Windows with UTF-8 uses a separate code path that was not updated. If you are using a locale that
considers some non-identical strings as equal, you may need to REINDEX to fix existing indexes on textual columns.

Repair corner-case bugs in VACUUM FULL (Tom)


A potential deadlock between concurrent VACUUM FULL operations on different system catalogs was introduced in 8.2.
This has now been corrected. 8.3 made this worse because the deadlock could occur within a critical code section, making it a
PANIC rather than just ERROR condition.
Also, a VACUUM FULL that failed partway through vacuuming a system catalog could result in cache corruption in concurrent database sessions.
Another VACUUM FULL bug introduced in 8.3 could result in a crash or out-of-memory report when dealing with pages
containing no live tuples.

Fix misbehavior of foreign key checks involving character or bit columns (Tom)
If the referencing column were of a different but compatible type (for instance varchar), the constraint was enforced incorrectly.

Avoid needless deadlock failures in no-op foreign-key checks (Stephan Szabo, Tom)

Fix possible core dump when re-planning a prepared query (Tom)


This bug affected only protocol-level prepare operations, not SQL PREPARE, and so tended to be seen only with JDBC,
DBI, and other client-side drivers that use prepared statements heavily.

Fix possible failure when re-planning a query that calls an SPI-using function (Tom)

Fix failure in row-wise comparisons involving columns of different datatypes (Tom)

Fix longstanding LISTEN/NOTIFY race condition (Tom)


In rare cases a session that had just executed a LISTEN might not get a notification, even though one would be expected because the concurrent transaction executing NOTIFY was observed to commit later.
A side effect of the fix is that a transaction that has executed a not-yet-committed LISTEN command will not see any row in
pg_listener for the LISTEN, should it choose to look; formerly it would have. This behavior was never documented one way
or the other, but it is possible that some applications depend on the old behavior.

Disallow LISTEN and UNLISTEN within a prepared transaction (Tom)


This was formerly allowed but trying to do it had various unpleasant consequences, notably that the originating backend could
not exit as long as an UNLISTEN remained uncommitted.

Disallow dropping a temporary table within a prepared transaction (Heikki)


This was correctly disallowed by 8.1, but the check was inadvertently broken in 8.2 and 8.3.

Fix rare crash when an error occurs during a query using a hash index (Heikki)

Fix incorrect comparison of tsquery values (Teodor)

Fix incorrect behavior of LIKE with non-ASCII characters in single-byte encodings (Rolf Jentsch)

Disable xmlvalidate (Tom)


This function should have been removed before 8.3 release, but was inadvertently left in the source code. It poses a small security risk since unprivileged users could use it to read the first few characters of any file accessible to the server.

Fix memory leaks in certain usages of set-returning functions (Neil)

Make encode(bytea, 'escape') convert all high-bit-set byte values into \nnn octal escape sequences (Tom)
This is necessary to avoid encoding problems when the database encoding is multi-byte. This change could pose compatibility
issues for applications that are expecting specific results from encode.

Fix input of datetime values for February 29 in years BC (Tom)


The former coding was mistaken about which years were leap years.

Fix unrecognized node type error in some variants of ALTER OWNER (Tom)

1564

Notes de version

Avoid tablespace permissions errors in CREATE TABLE LIKE INCLUDING INDEXES (Tom)

Ensure pg_stat_activity.waiting flag is cleared when a lock wait is aborted (Tom)

Fix handling of process permissions on Windows Vista (Dave, Magnus)


In particular, this fix allows starting the server as the Administrator user.

Update time zone data files to tzdata release 2008a (in particular, recent Chile changes); adjust timezone abbreviation VET
(Venezuela) to mean UTC-4:30, not UTC-4:00 (Tom)

Fix ecpg problems with arrays (Michael)

Fix pg_ctl to correctly extract the postmaster's port number from command-line options (Itagaki Takahiro, Tom)
Previously, pg_ctl start -w could try to contact the postmaster on the wrong port, leading to bogus reports of startup
failure.

Use -fwrapv to defend against possible misoptimization in recent gcc versions (Tom)
This is known to be necessary when building PostgreSQL with gcc 4.3 or later.

Enable building contrib/uuid-ossp with MSVC (Hiroshi Saito)

E.81. Release 8.3


Release Date
2008-02-04

E.81.1. Overview
With significant new functionality and performance enhancements, this release represents a major leap forward for PostgreSQL.
This was made possible by a growing community that has dramatically accelerated the pace of development. This release adds the
following major features:

Full text search is integrated into the core database system

Support for the SQL/XML standard, including new operators and an XML data type

Enumerated data types (ENUM)

Arrays of composite types

Universally Unique Identifier (UUID) data type

Add control over whether NULLs sort first or last

Updatable cursors

Server configuration parameters can now be set on a per-function basis

User-defined types can now have type modifiers

Automatically re-plan cached queries when table definitions change or statistics are updated

Numerous improvements in logging and statistics collection

Support Security Service Provider Interface (SSPI) for authentication on Windows

Support multiple concurrent autovacuum processes, and other autovacuum improvements

Allow the whole PostgreSQL distribution to be compiled with Microsoft Visual C++

Major performance improvements are listed below. Most of these enhancements are automatic and do not require user changes or
tuning:

Asynchronous commit delays writes to WAL during transaction commit

Checkpoint writes can be spread over a longer time period to smooth the I/O spike during each checkpoint

Heap-Only Tuples (HOT) accelerate space reuse for most UPDATEs and DELETEs
1565

Notes de version

Just-in-time background writer strategy improves disk write efficiency

Using non-persistent transaction IDs for read-only transactions reduces overhead and VACUUM requirements

Per-field and per-row storage overhead has been reduced

Large sequential scans no longer force out frequently used cached pages

Concurrent large sequential scans can now share disk reads

ORDER BY ... LIMIT can be done without sorting

The above items are explained in more detail in the sections below.

E.81.2. Migration to Version 8.3


A dump/restore using pg_dump is required for those wishing to migrate data from any previous release.
Observe the following incompatibilities:

E.81.2.1. General

Non-character data types are no longer automatically cast to TEXT (Peter, Tom)
Previously, if a non-character value was supplied to an operator or function that requires text input, it was automatically cast to
text, for most (though not all) built-in data types. This no longer happens: an explicit cast to text is now required for all noncharacter-string types. For example, these expressions formerly worked:
substr(current_date, 1, 4)
23 LIKE '2%'
but will now draw function does not exist and operator does not exist errors respectively. Use an explicit cast instead:
substr(current_date::text, 1, 4)
23::text LIKE '2%'
(Of course, you can use the more verbose CAST() syntax too.) The reason for the change is that these automatic casts too often caused surprising behavior. An example is that in previous releases, this expression was accepted but did not do what was
expected:
current_date < 2017-11-17
This is actually comparing a date to an integer, which should be (and now is) rejected -- but in the presence of automatic casts
both sides were cast to text and a textual comparison was done, because the text < text operator was able to match the
expression when no other < operator could.
Types char(n) and varchar(n) still cast to text automatically. Also, automatic casting to text still works for inputs to the concatenation (||) operator, so long as least one input is a character-string type.

Full text search features from contrib/tsearch2 have been moved into the core server, with some minor syntax changes
contrib/tsearch2 now contains a compatibility interface.

ARRAY(SELECT ...), where the SELECT returns no rows, now returns an empty array, rather than NULL (Tom)

The array type name for a base data type is no longer always the base type's name with an underscore prefix
The old naming convention is still honored when possible, but application code should no longer depend on it. Instead use the
new pg_type.typarray column to identify the array data type associated with a given type.

ORDER BY ... USING operator must now use a less-than or greater-than operator that is defined in a btree operator
class
This restriction was added to prevent inconsistent results.

SET LOCAL changes now persist until the end of the outermost transaction, unless rolled back (Tom)
Previously SET LOCAL's effects were lost after subtransaction commit (RELEASE SAVEPOINT or exit from a PL/pgSQL
exception block).

Commands rejected in transaction blocks are now also rejected in multiple-statement query strings (Tom)
1566

Notes de version

For example, "BEGIN; DROP DATABASE; COMMIT" will now be rejected even if submitted as a single query message.

ROLLBACK outside a transaction block now issues NOTICE instead of WARNING (Bruce)

Prevent NOTIFY/LISTEN/UNLISTEN from accepting schema-qualified names (Bruce)


Formerly, these commands accepted schema.relation but ignored the schema part, which was confusing.

ALTER SEQUENCE no longer affects the sequence's currval() state (Tom)

Foreign keys now must match indexable conditions for cross-data-type references (Tom)
This improves semantic consistency and helps avoid performance problems.

Restrict object size functions to users who have reasonable permissions to view such information (Tom)
For example, pg_database_size() now requires CONNECT permission, which is granted to everyone by default.
pg_tablespace_size() requires CREATE permission in the tablespace, or is allowed if the tablespace is the default tablespace for the database.

Remove the undocumented !!= (not in) operator (Tom)


NOT IN (SELECT ...) is the proper way to perform this operation.

Internal hashing functions are now more uniformly-distributed (Tom)


If application code was computing and storing hash values using internal PostgreSQL hashing functions, the hash values
must be regenerated.

C-code conventions for handling variable-length data values have changed (Greg Stark, Tom)
The new SET_VARSIZE() macro must be used to set the length of generated varlena values. Also, it might be necessary to
expand ( de-TOAST ) input values in more cases.

Continuous archiving no longer reports each successful archive operation to the server logs unless DEBUG level is used
(Simon)

E.81.2.2. Configuration Parameters

Numerous changes in administrative server parameters


bgwriter_lru_percent, bgwriter_all_percent, bgwriter_all_maxpages,
stats_start_collector, and stats_reset_on_server_start are removed. redirect_stderr is renamed
to logging_collector. stats_command_string is renamed to track_activities. stats_block_level
and stats_row_level are merged into track_counts. A new boolean configuration parameter, archive_mode,
controls archiving. Autovacuum's default settings have changed.

Remove stats_start_collector parameter (Tom)


We now always start the collector process, unless UDP socket creation fails.

Remove stats_reset_on_server_start parameter (Tom)


This was removed because pg_stat_reset() can be used for this purpose.

Commenting out a parameter in postgresql.conf now causes it to revert to its default value (Joachim Wieland)
Previously, commenting out an entry left the parameter's value unchanged until the next server restart.

E.81.2.3. Character Encodings

Add more checks for invalidly-encoded data (Andrew)


This change plugs some holes that existed in literal backslash escape string processing and COPY escape processing. Now the
de-escaped string is rechecked to see if the result created an invalid multi-byte character.

Disallow database encodings that are inconsistent with the server's locale setting (Tom)
On most platforms, C locale is the only locale that will work with any database encoding. Other locale settings imply a specific
encoding and will misbehave if the database encoding is something different. (Typical symptoms include bogus textual sort order and wrong results from upper() or lower().) The server now rejects attempts to create databases that have an incompatible encoding.
1567

Notes de version

Ensure that chr() cannot create invalidly-encoded values (Andrew)


In UTF8-encoded databases the argument of chr() is now treated as a Unicode code point. In other multi-byte encodings
chr()'s argument must designate a 7-bit ASCII character. Zero is no longer accepted. ascii() has been adjusted to match.

Adjust convert() behavior to ensure encoding validity (Andrew)


The two argument form of convert() has been removed. The three argument form now takes a bytea first argument and returns a bytea. To cover the loss of functionality, three new functions have been added:

convert_from(bytea, name) returns text -- converts the first argument from the named encoding to the database
encoding

convert_to(text, name) returns bytea -- converts the first argument from the database encoding to the named encoding

length(bytea, name) returns integer -- gives the length of the first argument in characters in the named encoding

Remove convert(argument USING conversion_name) (Andrew)


Its behavior did not match the SQL standard.

Make JOHAB encoding client-only (Tatsuo)


JOHAB is not safe as a server-side encoding.

E.81.3. Changes
Below you will find a detailed account of the changes between PostgreSQL 8.3 and the previous major release.

E.81.3.1. Performance

Asynchronous commit delays writes to WAL during transaction commit (Simon)


This feature dramatically increases performance for short data-modifying transactions. The disadvantage is that because disk
writes are delayed, if the database or operating system crashes before data is written to the disk, committed data will be lost.
This feature is useful for applications that can accept some data loss. Unlike turning off fsync, using asynchronous commit
does not put database consistency at risk; the worst case is that after a crash the last few reportedly-committed transactions
might not be committed after all. This feature is enabled by turning off synchronous_commit (which can be done persession or per-transaction, if some transactions are critical and others are not). wal_writer_delay can be adjusted to
control the maximum delay before transactions actually reach disk.

Checkpoint writes can be spread over a longer time period to smooth the I/O spike during each checkpoint (Itagaki Takahiro
and Heikki Linnakangas)
Previously all modified buffers were forced to disk as quickly as possible during a checkpoint, causing an I/O spike that decreased server performance. This new approach spreads out disk writes during checkpoints, reducing peak I/O usage.
(User-requested and shutdown checkpoints are still written as quickly as possible.)

Heap-Only Tuples (HOT) accelerate space reuse for most UPDATEs and DELETEs (Pavan Deolasee, with ideas from many
others)
UPDATEs and DELETEs leave dead tuples behind, as do failed INSERTs. Previously only VACUUM could reclaim space
taken by dead tuples. With HOT dead tuple space can be automatically reclaimed at the time of INSERT or UPDATE if no
changes are made to indexed columns. This allows for more consistent performance. Also, HOT avoids adding duplicate index
entries.

Just-in-time background writer strategy improves disk write efficiency (Greg Smith, Itagaki Takahiro)
This greatly reduces the need for manual tuning of the background writer.

Per-field and per-row storage overhead have been reduced (Greg Stark, Heikki Linnakangas)
Variable-length data types with data values less than 128 bytes long will see a storage decrease of 3 to 6 bytes. For example,
two adjacent char(1) fields now use 4 bytes instead of 16. Row headers are also 4 bytes shorter than before.

Using non-persistent transaction IDs for read-only transactions reduces overhead and VACUUM requirements (Florian Pflug)
Non-persistent transaction IDs do not increment the global transaction counter. Therefore, they reduce the load on pg_clog and
increase the time between forced vacuums to prevent transaction ID wraparound. Other performance improvements were also
1568

Notes de version

made that should improve concurrency.

Avoid incrementing the command counter after a read-only command (Tom)


There was formerly a hard limit of 232 (4 billion) commands per transaction. Now only commands that actually changed the
database count, so while this limit still exists, it should be significantly less annoying.

Create a dedicated WAL writer process to off-load work from backends (Simon)

Skip unnecessary WAL writes for CLUSTER and COPY (Simon)


Unless WAL archiving is enabled, the system now avoids WAL writes for CLUSTER and just fsync()s the table at the end
of the command. It also does the same for COPY if the table was created in the same transaction.

Large sequential scans no longer force out frequently used cached pages (Simon, Heikki, Tom)

Concurrent large sequential scans can now share disk reads (Jeff Davis)
This is accomplished by starting the new sequential scan in the middle of the table (where another sequential scan is already
in-progress) and wrapping around to the beginning to finish. This can affect the order of returned rows in a query that does not
specify ORDER BY. The synchronize_seqscans configuration parameter can be used to disable this if necessary.

ORDER BY ... LIMIT can be done without sorting (Greg Stark)


This is done by sequentially scanning the table and tracking just the top N candidate rows, rather than performing a full
sort of the entire table. This is useful when there is no matching index and the LIMIT is not large.

Put a rate limit on messages sent to the statistics collector by backends (Tom)
This reduces overhead for short transactions, but might sometimes increase the delay before statistics are tallied.

Improve hash join performance for cases with many NULLs (Tom)

Speed up operator lookup for cases with non-exact datatype matches (Tom)

E.81.3.2. Server

Autovacuum is now enabled by default (Alvaro)


Several changes were made to eliminate disadvantages of having autovacuum enabled, thereby justifying the change in default. Several other autovacuum parameter defaults were also modified.

Support multiple concurrent autovacuum processes (Alvaro, Itagaki Takahiro)


This allows multiple vacuums to run concurrently. This prevents vacuuming of a large table from delaying vacuuming of
smaller tables.

Automatically re-plan cached queries when table definitions change or statistics are updated (Tom)
Previously PL/pgSQL functions that referenced temporary tables would fail if the temporary table was dropped and recreated
between function invocations, unless EXECUTE was used. This improvement fixes that problem and many related issues.

Add a temp_tablespaces parameter to control the tablespaces for temporary tables and files (Jaime Casanova, Albert
Cervera, Bernd Helmle)
This parameter defines a list of tablespaces to be used. This enables spreading the I/O load across multiple tablespaces. A random tablespace is chosen each time a temporary object is created. Temporary files are no longer stored in per-database pgsql_tmp/ directories but in per-tablespace directories.

Place temporary tables' TOAST tables in special schemas named pg_toast_temp_nnn (Tom)
This allows low-level code to recognize these tables as temporary, which enables various optimizations such as not WALlogging changes and using local rather than shared buffers for access. This also fixes a bug wherein backends unexpectedly
held open file references to temporary TOAST tables.

Fix problem that a constant flow of new connection requests could indefinitely delay the postmaster from completing a shutdown or a crash restart (Tom)

Guard against a very-low-probability data loss scenario by preventing re-use of a deleted table's relfilenode until after the next
checkpoint (Heikki)

Fix CREATE CONSTRAINT TRIGGER to convert old-style foreign key trigger definitions into regular foreign key
constraints (Tom)
1569

Notes de version

This will ease porting of foreign key constraints carried forward from pre-7.3 databases, if they were never converted using
contrib/adddepend.

Fix DEFAULT NULL to override alled defaults (Tom)


DEFAULT NULL was formerly considered a noise phrase, but it should (and now does) override non-null defaults that would
otherwise be alled from a parent table or domain.

Add new encodings EUC_JIS_2004 and SHIFT_JIS_2004 (Tatsuo)


These new encodings can be converted to and from UTF-8.

Change server startup log message from database system is ready to database system is ready to accept connections ,
and adjust its timing
The message now appears only when the postmaster is really ready to accept connections.

E.81.3.3. Monitoring

Add log_autovacuum_min_duration parameter to support configurable logging of autovacuum activity (Simon, Alvaro)

Add log_lock_waits parameter to log lock waiting (Simon)

Add log_temp_files parameter to log temporary file usage (Bill Moran)

Add log_checkpoints parameter to improve logging of checkpoints (Greg Smith, Heikki)

log_line_prefix now supports %s and %c escapes in all processes (Andrew)


Previously these escapes worked only for user sessions, not for background database processes.

Add log_restartpoints to control logging of point-in-time recovery restart points (Simon)

Last transaction end time is now logged at end of recovery and at each logged restart point (Simon)

Autovacuum now reports its activity start time in pg_stat_activity (Tom)

Allow server log output in comma-separated value (CSV) format (Arul Shaji, Greg Smith, Andrew Dunstan)
CSV-format log files can easily be loaded into a database table for subsequent analysis.

Use PostgreSQL-supplied timezone support for formatting timestamps displayed in the server log (Tom)
This avoids Windows-specific problems with localized time zone names that are in the wrong encoding. There is a new
log_timezone parameter that controls the timezone used in log messages, independently of the client-visible timezone
parameter.

New system view pg_stat_bgwriter displays statistics about background writer activity (Magnus)

Add new columns for database-wide tuple statistics to pg_stat_database (Magnus)

Add an xact_start (transaction start time) column to pg_stat_activity (Neil)


This makes it easier to identify long-running transactions.

Add n_live_tuples and n_dead_tuples columns to pg_stat_all_tables and related views (Glen Parker)

Merge stats_block_level and stats_row_level parameters into a single parameter track_counts, which
controls all messages sent to the statistics collector process (Tom)

Rename stats_command_string parameter to track_activities (Tom)

Fix statistical counting of live and dead tuples to recognize that committed and aborted transactions have different effects
(Tom)

E.81.3.4. Authentication

Support Security Service Provider Interface (SSPI) for authentication on Windows (Magnus)

Support GSSAPI authentication (Henry Hotz, Magnus)


This should be preferred to native Kerberos authentication because GSSAPI is an industry standard.
1570

Notes de version

Support a global SSL configuration file (Victor Wagner)

Add ssl_ciphers parameter to control accepted SSL ciphers (Victor Wagner)

Add a Kerberos realm parameter, krb_realm (Magnus)

E.81.3.5. Write-Ahead Log (WAL) and Continuous Archiving

Change the timestamps recorded in transaction WAL records from time_t to TimestampTz representation (Tom)
This provides sub-second resolution in WAL, which can be useful for point-in-time recovery.

Reduce WAL disk space needed by warm standby servers (Simon)


This change allows a warm standby server to pass the name of the earliest still-needed WAL file to the recovery script, allowing automatic removal of no-longer-needed WAL files. This is done using %r in the restore_command parameter of
recovery.conf.

New boolean configuration parameter, archive_mode, controls archiving (Simon)


Previously setting archive_command to an empty string turned off archiving. Now archive_mode turns archiving on
and off, independently of archive_command. This is useful for stopping archiving temporarily.

E.81.3.6. Queries

Full text search is integrated into the core database system (Teodor, Oleg)
Text search has been improved, moved into the core code, and is now installed by default. contrib/tsearch2 now
contains a compatibility interface.

Add control over whether NULLs sort first or last (Teodor, Tom)
The syntax is ORDER BY ... NULLS FIRST/LAST.

Allow per-column ascending/descending (ASC/DESC) ordering options for indexes (Teodor, Tom)
Previously a query using ORDER BY with mixed ASC/DESC specifiers could not fully use an index. Now an index can be fully used in such cases if the index was created with matching ASC/DESC specifications. NULL sort order within an index can be
controlled, too.

Allow col IS NULL to use an index (Teodor)

Updatable cursors (Arul Shaji, Tom)


This eliminates the need to reference a primary key to UPDATE or DELETE rows returned by a cursor. The syntax is UPDATE/DELETE WHERE CURRENT OF.

Allow FOR UPDATE in cursors (Arul Shaji, Tom)

Create a general mechanism that supports casts to and from the standard string types (TEXT, VARCHAR, CHAR) for every
datatype, by invoking the datatype's I/O functions (Tom)
Previously, such casts were available only for types that had specialized function(s) for the purpose. These new casts are assignment-only in the to-string direction, explicit-only in the other direction, and therefore should create no surprising behavior.

Allow UNION and related constructs to return a domain type, when all inputs are of that domain type (Tom)
Formerly, the output would be considered to be of the domain's base type.

Allow limited hashing when using two different data types (Tom)
This allows hash joins, hash indexes, hashed subplans, and hash aggregation to be used in situations involving cross-data-type
comparisons, if the data types have compatible hash functions. Currently, cross-data-type hashing support exists for smallint/integer/bigint, and for float4/float8.

Improve optimizer logic for detecting when variables are equal in a WHERE clause (Tom)
This allows mergejoins to work with descending sort orders, and improves recognition of redundant sort columns.

Improve performance when planning large allance trees in cases where most tables are excluded by constraints (Tom)

E.81.3.7. Object Manipulation


1571

Notes de version

Arrays of composite types (David Fetter, Andrew, Tom)


In addition to arrays of explicitly-declared composite types, arrays of the rowtypes of regular tables and views are now supported, except for rowtypes of system catalogs, sequences, and TOAST tables.

Server configuration parameters can now be set on a per-function basis (Tom)


For example, functions can now set their own search_path to prevent unexpected behavior if a different search_path
exists at run-time. Security definer functions should set search_path to avoid security loopholes.

CREATE/ALTER FUNCTION now supports COST and ROWS options (Tom)


COST allows specification of the cost of a function call. ROWS allows specification of the average number or rows returned by
a set-returning function. These values are used by the optimizer in choosing the best plan.

Implement CREATE TABLE LIKE ... INCLUDING INDEXES (Trevor Hardcastle, Nikhil Sontakke, Neil)

Allow CREATE INDEX CONCURRENTLY to ignore transactions in other databases (Simon)

Add ALTER VIEW ... RENAME TO and ALTER SEQUENCE ... RENAME TO (David Fetter, Neil)
Previously this could only be done via ALTER TABLE ... RENAME TO.

Make CREATE/DROP/RENAME DATABASE wait briefly for conflicting backends to exit before failing (Tom)
This increases the likelihood that these commands will succeed.

Allow triggers and rules to be deactivated in groups using a configuration parameter, for replication purposes (Jan)
This allows replication systems to disable triggers and rewrite rules as a group without modifying the system catalogs directly.
The behavior is controlled by ALTER TABLE and a new parameter session_replication_role.

User-defined types can now have type modifiers (Teodor, Tom)


This allows a user-defined type to take a modifier, like ssnum(7). Previously only built-in data types could have modifiers.

E.81.3.8. Utility Commands

Non-superuser database owners now are able to add trusted procedural languages to their databases by default (Jeremy Drake)
While this is reasonably safe, some administrators might wish to revoke the privilege. It is controlled by pg_pltemplate.tmpldbacreate.

Allow a session's current parameter setting to be used as the default for future sessions (Tom)
This is done with SET ... FROM CURRENT in CREATE/ALTER FUNCTION, ALTER DATABASE, or ALTER
ROLE.

Implement new commands DISCARD ALL, DISCARD PLANS, DISCARD TEMPORARY, CLOSE ALL, and DEALLOCATE ALL (Marko Kreen, Neil)
These commands simplify resetting a database session to its initial state, and are particularly useful for connection-pooling
software.

Make CLUSTER MVCC-safe (Heikki Linnakangas)


Formerly, CLUSTER would discard all tuples that were committed dead, even if there were still transactions that should be
able to see them under MVCC visibility rules.

Add new CLUSTER syntax: CLUSTER table USING index (Holger Schurig)
The old CLUSTER syntax is still supported, but the new form is considered more logical.

Fix EXPLAIN so it can show complex plans more accurately (Tom)


References to subplan outputs are now always shown correctly, instead of using ?columnN? for complicated cases.

Limit the amount of information reported when a user is dropped (Alvaro)


Previously, dropping (or attempting to drop) a user who owned many objects could result in large NOTICE or ERROR messages listing all these objects; this caused problems for some client applications. The length of the message is now limited, although a full list is still sent to the server log.

E.81.3.9. Data Types


1572

Notes de version

Support for the SQL/XML standard, including new operators and an XML data type (Nikolay Samokhvalov, Pavel Stehule,
Peter)

Enumerated data types (ENUM) (Tom Dunstan)


This feature provides convenient support for fields that have a small, fixed set of allowed values. An example of creating an
ENUM type is CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy').

Universally Unique Identifier (UUID) data type (Gevik Babakhani, Neil)


This closely matches RFC 4122.

Widen the MONEY data type to 64 bits (D'Arcy Cain)


This greatly increases the range of supported MONEY values.

Fix float4/float8 to handle Infinity and NAN (Not A Number) consistently (Bruce)
The code formerly was not consistent about distinguishing Infinity from overflow conditions.

Allow leading and trailing whitespace during input of boolean values (Neil)

Prevent COPY from using digits and lowercase letters as delimiters (Tom)

E.81.3.10. Functions

Add new regular expression functions regexp_matches(), regexp_split_to_array(), and regexp_split_to_table() (Jeremy Drake, Neil)
These functions provide extraction of regular expression subexpressions and allow splitting a string using a POSIX regular expression.

Add lo_truncate() for large object truncation (Kris Jurka)

Implement width_bucket() for the float8 data type (Neil)

Add pg_stat_clear_snapshot() to discard statistics snapshots collected during the current transaction (Tom)
The first request for statistics in a transaction takes a statistics snapshot that does not change during the transaction. This function allows the snapshot to be discarded and a new snapshot loaded during the next statistics query. This is particularly useful
for PL/pgSQL functions, which are confined to a single transaction.

Add isodow option to EXTRACT() and date_part() (Bruce)


This returns the day of the week, with Sunday as seven. (dow returns Sunday as zero.)

Add ID (ISO day of week) and IDDD (ISO day of year) format codes for to_char(), to_date(), and
to_timestamp() (Brendan Jurd)

Make to_timestamp() and to_date() assume TM (trim) option for potentially variable-width fields (Bruce)
This matches Oracle's behavior.

Fix off-by-one conversion error in to_date()/to_timestamp() D (non-ISO day of week) fields (Bruce)

Make setseed() return void, rather than a useless integer value (Neil)

Add a hash function for NUMERIC (Neil)


This allows hash indexes and hash-based plans to be used with NUMERIC columns.

Improve efficiency of LIKE/ILIKE, especially for multi-byte character sets like UTF-8 (Andrew, Itagaki Takahiro)

Make currtid() functions require SELECT privileges on the target table (Tom)

Add several txid_*() functions to query active transaction IDs (Jan)


This is useful for various replication solutions.

E.81.3.11. PL/pgSQL Server-Side Language

Add scrollable cursor support, including directional control in FETCH (Pavel Stehule)

Allow IN as an alternative to FROM in PL/pgSQL's FETCH statement, for consistency with the backend's FETCH command
1573

Notes de version

(Pavel Stehule)

Add MOVE to PL/pgSQL (Magnus, Pavel Stehule, Neil)

Implement RETURN QUERY (Pavel Stehule, Neil)


This adds convenient syntax for PL/pgSQL set-returning functions that want to return the result of a query. RETURN QUERY is easier and more efficient than a loop around RETURN NEXT.

Allow function parameter names to be qualified with the function's name (Tom)
For example, myfunc.myvar. This is particularly useful for specifying variables in a query where the variable name might
match a column name.

Make qualification of variables with block labels work properly (Tom)


Formerly, outer-level block labels could unexpectedly interfere with recognition of inner-level record or row references.

Tighten requirements for FOR loop STEP values (Tom)


Prevent non-positive STEP values, and handle loop overflows.

Improve accuracy when reporting syntax error locations (Tom)

E.81.3.12. Other Server-Side Languages

Allow type-name arguments to PL/Perl spi_prepare() to be data type aliases in addition to names found in pg_type
(Andrew)

Allow type-name arguments to PL/Python plpy.prepare() to be data type aliases in addition to names found in
pg_type (Andrew)

Allow type-name arguments to PL/Tcl spi_prepare to be data type aliases in addition to names found in pg_type
(Andrew)

Enable PL/PythonU to compile on Python 2.5 (Marko Kreen)

Support a true PL/Python boolean type in compatible Python versions (Python 2.3 and later) (Marko Kreen)

Fix PL/Tcl problems with thread-enabled libtcl spawning multiple threads within the backend (Steve Marshall, Paul Bayer,
Doug Knight)
This caused all sorts of unpleasantness.

E.81.3.13. psql

List disabled triggers separately in \d output (Brendan Jurd)

In \d patterns, always match $ literally (Tom)

Show aggregate return types in \da output (Greg Sabino Mullane)

Add the function's volatility status to the output of \df+ (Neil)

Add \prompt capability (Chad Wagner)

Allow \pset, \t, and \x to specify on or off, rather than just toggling (Chad Wagner)

Add \sleep capability (Jan)

Enable \timing output for \copy (Andrew)

Improve \timing resolution on Windows (Itagaki Takahiro)

Flush \o output after each backslash command (Tom)

Correctly detect and report errors while reading a -f input file (Peter)

Remove -u option (this option has long been deprecated) (Tom)

E.81.3.14. pg_dump

1574

Notes de version

Add --tablespaces-only and --roles-only options to pg_dumpall (Dave Page)

Add an output file option to pg_dumpall (Dave Page)


This is primarily useful on Windows, where output redirection of child pg_dump processes does not work.

Allow pg_dumpall to accept an initial-connection database name rather than the default template1 (Dave Page)

In -n and -t switches, always match $ literally (Tom)

Improve performance when a database has thousands of objects (Tom)

Remove -u option (this option has long been deprecated) (Tom)

E.81.3.15. Other Client Applications

In initdb, allow the location of the pg_xlog directory to be specified (Euler Taveira de Oliveira)

Enable server core dump generation in pg_regress on supported operating systems (Andrew)

Add a -t (timeout) parameter to pg_ctl (Bruce)


This controls how long pg_ctl will wait when waiting for server startup or shutdown. Formerly the timeout was hard-wired as
60 seconds.

Add a pg_ctl option to control generation of server core dumps (Andrew)

Allow Control-C to cancel clusterdb, reindexdb, and vacuumdb (Itagaki Takahiro, Magnus)

Suppress command tag output for createdb, createuser, dropdb, and dropuser (Peter)
The --quiet option is ignored and will be removed in 8.4. Progress messages when acting on all databases now go to stdout
instead of stderr because they are not actually errors.

E.81.3.16. libpq

Interpret the dbName parameter of PQsetdbLogin() as a conninfo string if it contains an equals sign (Andrew)
This allows use of conninfo strings in client programs that still use PQsetdbLogin().

Support a global SSL configuration file (Victor Wagner)

Add environment variable PGSSLKEY to control SSL hardware keys (Victor Wagner)

Add lo_truncate() for large object truncation (Kris Jurka)

Add PQconnectionNeedsPassword() that returns true if the server required a password but none was supplied (Joe
Conway, Tom)
If this returns true after a failed connection attempt, a client application should prompt the user for a password. In the past applications have had to check for a specific error message string to decide whether a password is needed; that approach is now
deprecated.

Add PQconnectionUsedPassword() that returns true if the supplied password was actually used (Joe Conway, Tom)
This is useful in some security contexts where it is important to know whether a user-supplied password is actually valid.

E.81.3.17. ecpg

Use V3 frontend/backend protocol (Michael)


This adds support for server-side prepared statements.

Use native threads, instead of pthreads, on Windows (Magnus)

Improve thread-safety of ecpglib (Itagaki Takahiro)

Make the ecpg libraries export only necessary API symbols (Michael)

E.81.3.18. Windows Port


1575

Notes de version

Allow the whole PostgreSQL distribution to be compiled with Microsoft Visual C++ (Magnus and others)
This allows Windows-based developers to use familiar development and debugging tools. Windows executables made with
Visual C++ might also have better stability and performance than those made with other tool sets. The client-only Visual C++
build scripts have been removed.

Drastically reduce postmaster's memory usage when it has many child processes (Magnus)

Allow regression tests to be started by an administrative user (Magnus)

Add native shared memory implementation (Magnus)

E.81.3.19. Server Programming Interface (SPI)

Add cursor-related functionality in SPI (Pavel Stehule)


Allow access to the cursor-related planning options, and add FETCH/MOVE routines.

Allow execution of cursor commands through SPI_execute (Tom)


The macro SPI_ERROR_CURSOR still exists but will never be returned.

SPI plan pointers are now declared as SPIPlanPtr instead of void * (Tom)
This does not break application code, but switching is recommended to help catch simple programming mistakes.

E.81.3.20. Build Options

Add configure option --enable-profiling to enable code profiling (works only with gcc) (Korry Douglas and Nikhil
Sontakke)

Add configure option --with-system-tzdata to use the operating system's time zone database (Peter)

Fix PGXS so extensions can be built against PostgreSQL installations whose pg_config program does not appear first in the
PATH (Tom)

Support gmake draft when building the SGML documentation (Bruce)


Unless draft is used, the documentation build will now be repeated if necessary to ensure the index is up-to-date.

E.81.3.21. Source Code

Rename macro DLLIMPORT to PGDLLIMPORT to avoid conflicting with third party includes (like Tcl) that define DLLIMPORT (Magnus)

Create operator families to improve planning of queries involving cross-data-type comparisons (Tom)

Update GIN extractQuery() API to allow signalling that nothing can satisfy the query (Teodor)

Move NAMEDATALEN definition from postgres_ext.h to pg_config_manual.h (Peter)

Provide strlcpy() and strlcat() on all platforms, and replace error-prone uses of strncpy(), strncat(), etc
(Peter)

Create hooks to let an external plugin monitor (or even replace) the planner and create plans for hypothetical situations
(Gurjeet Singh, Tom)

Create a function variable join_search_hook to let plugins override the join search order portion of the planner (Julius
Stroffek)

Add tas() support for Renesas' M32R processor (Kazuhiro Inaoka)

quote_identifier() and pg_dump no longer quote keywords that are unreserved according to the grammar (Tom)

Change the on-disk representation of the NUMERIC data type so that the sign_dscale word comes before the weight
(Tom)

Use SYSV semaphores rather than POSIX on Darwin >= 6.0, i.e., OS X 10.2 and up (Chris Marcellino)

Add acronym and NFS documentation sections (Bruce)

"Postgres" is now documented as an accepted alias for "PostgreSQL" (Peter)


1576

Notes de version

Add documentation about preventing database server spoofing when the server is down (Bruce)

E.81.3.22. Contrib

Move contrib README content into the main PostgreSQL documentation (Albert Cervera i Areny)

Add contrib/pageinspect module for low-level page inspection (Simon, Heikki)

Add contrib/pg_standby module for controlling warm standby operation (Simon)

Add contrib/uuid-ossp module for generating UUID values using the OSSP UUID library (Peter)
Use configure --with-ossp-uuid to activate. This takes advantage of the new UUID builtin type.

Add contrib/dict_int, contrib/dict_xsyn, and contrib/test_parser modules to provide sample add-on


text search dictionary templates and parsers (Sergey Karpov)

Allow contrib/pgbench to set the fillfactor (Pavan Deolasee)

Add timestamps to contrib/pgbench -l (Greg Smith)

Add usage count statistics to contrib/pgbuffercache (Greg Smith)

Add GIN support for contrib/hstore (Teodor)

Add GIN support for contrib/pg_trgm (Guillaume Smet, Teodor)

Update OS/X startup scripts in contrib/start-scripts (Mark Cotner, David Fetter)

Restrict pgrowlocks() and dblink_get_pkey() to users who have SELECT privilege on the target table (Tom)

Restrict contrib/pgstattuple functions to superusers (Tom)

contrib/xml2 is deprecated and planned for removal in 8.4 (Peter)


The new XML support in core PostgreSQL supersedes this module.

E.82. Release 8.2.23


Release Date
2011-12-05
This release contains a variety of fixes from 8.2.22. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .
This is expected to be the last PostgreSQL release in the 8.2.X series. Users are encouraged to update to a newer release branch
soon.

E.82.1. Migration to Version 8.2.23


A dump/restore is not required for those running 8.2.X.
However,
a
longstanding
error
was
discovered
in
the
definition
of
the
information_schema.referential_constraints view. If you rely on correct results from that view, you should replace its definition as explained in the first changelog item below.
Also, if you are upgrading from a version earlier than 8.2.14, see Section E.91, Release 8.2.14 .

E.82.2. Changes

Fix bugs in information_schema.referential_constraints view (Tom Lane)


This view was being insufficiently careful about matching the foreign-key constraint to the depended-on primary or unique
key constraint. That could result in failure to show a foreign key constraint at all, or showing it multiple times, or claiming that
it depends on a different constraint than the one it really does.
Since the view definition is installed by initdb, merely upgrading will not fix the problem. If you need to fix this in an existing
installation, you can (as a superuser) drop the information_schema schema then re-create it by sourcing SHAREDIR/
1577

Notes de version

information_schema.sql. (Run pg_config --sharedir if you're uncertain where SHAREDIR is.) This must be
repeated in each database to be fixed.

Fix TOAST-related data corruption during CREATE TABLE dest AS SELECT * FROM src or INSERT INTO
dest SELECT * FROM src (Tom Lane)
If a table has been modified by ALTER TABLE ADD COLUMN, attempts to copy its data verbatim to another table could
produce corrupt results in certain corner cases. The problem can only manifest in this precise form in 8.4 and later, but we patched earlier versions as well in case there are other code paths that could trigger the same bug.

Fix race condition during toast table access from stale syscache entries (Tom Lane)
The typical symptom was transient errors like missing chunk number 0 for toast value NNNNN in pg_toast_2619 , where
the cited toast table would always belong to a system catalog.

Improve locale support in money type's input and output (Tom Lane)
Aside from not supporting all standard lc_monetary formatting options, the input and output functions were inconsistent,
meaning there were locales in which dumped money values could not be re-read.

Don't let transform_null_equals affect CASE foo WHEN NULL ... constructs (Heikki Linnakangas)
transform_null_equals is only supposed to affect foo = NULL expressions written directly by the user, not equality
checks generated internally by this form of CASE.

Change foreign-key trigger creation order to better support self-referential foreign keys (Tom Lane)
For a cascading foreign key that references its own table, a row update will fire both the ON UPDATE trigger and the CHECK
trigger as one event. The ON UPDATE trigger must execute first, else the CHECK will check a non-final state of the row and
possibly throw an inappropriate error. However, the firing order of these triggers is determined by their names, which generally sort in creation order since the triggers have auto-generated names following the convention
RI_ConstraintTrigger_NNNN . A proper fix would require modifying that convention, which we will do in 9.2, but it
seems risky to change it in existing releases. So this patch just changes the creation order of the triggers. Users encountering
this type of error should drop and re-create the foreign key constraint to get its triggers into the right order.

Preserve blank lines within commands in psql's command history (Robert Haas)
The former behavior could cause problems if an empty line was removed from within a string literal, for example.

Use the preferred version of xsubpp to build PL/Perl, not necessarily the operating system's main copy (David Wheeler and
Alex Hunsaker)

Honor query cancel interrupts promptly in pgstatindex() (Robert Haas)

Ensure VPATH builds properly install all server header files (Peter Eisentraut)

Shorten file names reported in verbose error messages (Peter Eisentraut)


Regular builds have always reported just the name of the C file containing the error message call, but VPATH builds formerly
reported an absolute path name.

Fix interpretation of Windows timezone names for Central America (Tom Lane)
Map Central America Standard Time to CST6, not CST6CDT, because DST is generally not observed anywhere in Central
America.

Update time zone data files to tzdata release 2011n for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa;
also historical corrections for Alaska and British East Africa.

E.83. Release 8.2.22


Release Date
2011-09-26
This release contains a variety of fixes from 8.2.21. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .
The PostgreSQL community will stop releasing updates for the 8.2.X release series in December 2011. Users are encouraged to
update to a newer release branch soon.
1578

Notes de version

E.83.1. Migration to Version 8.2.22


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.14, see Section E.91, Release 8.2.14 .

E.83.2. Changes

Fix multiple bugs in GiST index page split processing (Heikki Linnakangas)
The probability of occurrence was low, but these could lead to index corruption.

Avoid possibly accessing off the end of memory in ANALYZE (Noah Misch)
This fixes a very-low-probability server crash scenario.

Fix race condition in relcache init file invalidation (Tom Lane)


There was a window wherein a new backend process could read a stale init file but miss the inval messages that would tell it
the data is stale. The result would be bizarre failures in catalog accesses, typically could not read block 0 in file ... later during startup.

Fix memory leak at end of a GiST index scan (Tom Lane)


Commands that perform many separate GiST index scans, such as verification of a new GiST-based exclusion constraint on a
table already containing many rows, could transiently require large amounts of memory due to this leak.

Fix performance problem when constructing a large, lossy bitmap (Tom Lane)

Fix array- and path-creating functions to ensure padding bytes are zeroes (Tom Lane)
This avoids some situations where the planner will think that semantically-equal constants are not equal, resulting in poor optimization.

Work around gcc 4.6.0 bug that breaks WAL replay (Tom Lane)
This could lead to loss of committed transactions after a server crash.

Fix dump bug for VALUES in a view (Tom Lane)

Disallow SELECT FOR UPDATE/SHARE on sequences (Tom Lane)


This operation doesn't work as expected and can lead to failures.

Defend against integer overflow when computing size of a hash table (Tom Lane)

Fix portability bugs in use of credentials control messages for peer authentication (Tom Lane)

Fix typo in pg_srand48 seed initialization (Andres Freund)


This led to failure to use all bits of the provided seed. This function is not used on most platforms (only those without srandom), and the potential security exposure from a less-random-than-expected seed seems minimal in any case.

Avoid integer overflow when the sum of LIMIT and OFFSET values exceeds 2^63 (Heikki Linnakangas)

Add overflow checks to int4 and int8 versions of generate_series() (Robert Haas)

Fix trailing-zero removal in to_char() (Marti Raudsepp)


In a format with FM and no digit positions after the decimal point, zeroes to the left of the decimal point could be removed incorrectly.

Fix pg_size_pretty() to avoid overflow for inputs close to 2^63 (Tom Lane)

Fix psql's counting of script file line numbers during COPY from a different file (Tom Lane)

Fix pg_restore's direct-to-database mode for standard_conforming_strings (Tom Lane)


pg_restore could emit incorrect commands when restoring directly to a database server from an archive file that had been
made with standard_conforming_strings set to on.

Fix write-past-buffer-end and memory leak in libpq's LDAP service lookup code (Albe Laurenz)

In libpq, avoid failures when using nonblocking I/O and an SSL connection (Martin Pihlak, Tom Lane)

Improve libpq's handling of failures during connection startup (Tom Lane)


In particular, the response to a server report of fork() failure during SSL connection startup is now saner.
1579

Notes de version

Make ecpglib write double values with 15 digits precision (Akira Kurosawa)

Apply upstream fix for blowfish signed-character bug (CVE-2011-2483) (Tom Lane)
contrib/pg_crypto's blowfish encryption code could give wrong results on platforms where char is signed (which is
most), leading to encrypted passwords being weaker than they should be.

Fix memory leak in contrib/seg (Heikki Linnakangas)

Fix pgstatindex() to give consistent results for empty indexes (Tom Lane)

Allow building with perl 5.14 (Alex Hunsaker)

Update configure script's method for probing existence of system functions (Tom Lane)
The version of autoconf we used in 8.3 and 8.2 could be fooled by compilers that perform link-time optimization.

Fix assorted issues with build and install file paths containing spaces (Tom Lane)

Update time zone data files to tzdata release 2011i for DST law changes in Canada, Egypt, Russia, Samoa, and South Sudan.

E.84. Release 8.2.21


Release Date
2011-04-18
This release contains a variety of fixes from 8.2.20. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.84.1. Migration to Version 8.2.21


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.14, see Section E.91, Release 8.2.14 .

E.84.2. Changes

Avoid potential deadlock during catalog cache initialization (Nikhil Sontakke)


In some cases the cache loading code would acquire share lock on a system index before locking the index's catalog. This
could deadlock against processes trying to acquire exclusive locks in the other, more standard order.

Fix dangling-pointer problem in BEFORE ROW UPDATE trigger handling when there was a concurrent update to the target
tuple (Tom Lane)
This bug has been observed to result in intermittent cannot extract system attribute from virtual tuple failures while trying
to do UPDATE RETURNING ctid. There is a very small probability of more serious errors, such as generating incorrect index entries for the updated tuple.

Disallow DROP TABLE when there are pending deferred trigger events for the table (Tom Lane)
Formerly the DROP would go through, leading to could not open relation with OID nnn errors when the triggers were
eventually fired.

Fix PL/Python memory leak involving array slices (Daniel Popowich)

Fix pg_restore to cope with long lines (over 1KB) in TOC files (Tom Lane)

Put in more safeguards against crashing due to division-by-zero with overly enthusiastic compiler optimization (Aurelien Jarno)

Support use of dlopen() in FreeBSD and OpenBSD on MIPS (Tom Lane)


There was a hard-wired assumption that this system function was not available on MIPS hardware on these systems. Use a
compile-time test instead, since more recent versions have it.

Fix compilation failures on HP-UX (Heikki Linnakangas)

Fix path separator used by pg_regress on Cygwin (Andrew Dunstan)

Update time zone data files to tzdata release 2011f for DST law changes in Chile, Cuba, Falkland Islands, Morocco, Samoa,
1580

Notes de version

and Turkey; also historical corrections for South Australia, Alaska, and Hawaii.

E.85. Release 8.2.20


Release Date
2011-01-31
This release contains a variety of fixes from 8.2.19. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.85.1. Migration to Version 8.2.20


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.14, see Section E.91, Release 8.2.14 .

E.85.2. Changes

Avoid failures when EXPLAIN tries to display a simple-form CASE expression (Tom Lane)
If the CASE's test expression was a constant, the planner could simplify the CASE into a form that confused the expression-display code, resulting in unexpected CASE WHEN clause errors.

Fix assignment to an array slice that is before the existing range of subscripts (Tom Lane)
If there was a gap between the newly added subscripts and the first pre-existing subscript, the code miscalculated how many
entries needed to be copied from the old array's null bitmap, potentially leading to data corruption or crash.

Avoid unexpected conversion overflow in planner for very distant date values (Tom Lane)
The date type supports a wider range of dates than can be represented by the timestamp types, but the planner assumed it could
always convert a date to timestamp with impunity.

Fix pg_restore's text output for large objects (BLOBs) when standard_conforming_strings is on (Tom Lane)
Although restoring directly to a database worked correctly, string escaping was incorrect if pg_restore was asked for SQL text
output and standard_conforming_strings had been enabled in the source database.

Fix erroneous parsing of tsquery values containing ... & !(subexpression) | ... (Tom Lane)
Queries containing this combination of operators were not executed correctly. The same error existed in contrib/intarray's query_int type and contrib/ltree's ltxtquery type.

Fix buffer overrun in contrib/intarray's input function for the query_int type (Apple)
This bug is a security risk since the function's return address could be overwritten. Thanks to Apple Inc's security team for reporting this issue and supplying the fix. (CVE-2010-4015)

Fix bug in contrib/seg's GiST picksplit algorithm (Alexander Korotkov)


This could result in considerable inefficiency, though not actually incorrect answers, in a GiST index on a seg column. If you
have such an index, consider REINDEXing it after installing this update. (This is identical to the bug that was fixed in
contrib/cube in the previous update.)

E.86. Release 8.2.19


Release Date
2010-12-16
This release contains a variety of fixes from 8.2.18. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.86.1. Migration to Version 8.2.19


1581

Notes de version

A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.14, see Section E.91, Release 8.2.14 .

E.86.2. Changes

Force the default wal_sync_method to be fdatasync on Linux (Tom Lane, Marti Raudsepp)
The default on Linux has actually been fdatasync for many years, but recent kernel changes caused PostgreSQL to
choose open_datasync instead. This choice did not result in any performance improvement, and caused outright failures
on certain filesystems, notably ext4 with the data=journal mount option.

Fix assorted bugs in WAL replay logic for GIN indexes (Tom Lane)
This could result in bad buffer id: 0 failures or corruption of index contents during replication.

Fix recovery from base backup when the starting checkpoint WAL record is not in the same WAL segment as its redo point
(Jeff Davis)

Add support for detecting register-stack overrun on IA64 (Tom Lane)


The IA64 architecture has two hardware stacks. Full prevention of stack-overrun failures requires checking both.

Add a check for stack overflow in copyObject() (Tom Lane)


Certain code paths could crash due to stack overflow given a sufficiently complex query.

Fix detection of page splits in temporary GiST indexes (Heikki Linnakangas)


It is possible to have a concurrent page split in a temporary index, if for example there is an open cursor scanning the index
when an insertion is done. GiST failed to detect this case and hence could deliver wrong results when execution of the cursor
continued.

Avoid memory leakage while ANALYZE'ing complex index expressions (Tom Lane)

Ensure an index that uses a whole-row Var still depends on its table (Tom Lane)
An index declared like create index i on t (foo(t.*)) would not automatically get dropped when its table was
dropped.

Do not inline a SQL function with multiple OUT parameters (Tom Lane)
This avoids a possible crash due to loss of information about the expected result rowtype.

Behave correctly if ORDER BY, LIMIT, FOR UPDATE, or WITH is attached to the VALUES part of INSERT ... VALUES
(Tom Lane)

Fix constant-folding of COALESCE() expressions (Tom Lane)


The planner would sometimes attempt to evaluate sub-expressions that in fact could never be reached, possibly leading to
unexpected errors.

Add print functionality for InhRelation nodes (Tom Lane)


This avoids a failure when debug_print_parse is enabled and certain types of query are executed.

Fix incorrect calculation of distance from a point to a horizontal line segment (Tom Lane)
This bug affected several different geometric distance-measurement operators.

Fix PL/pgSQL's handling of simple expressions to not fail in recursion or error-recovery cases (Tom Lane)

Fix PL/Python's handling of set-returning functions (Jan Urbanski)


Attempts to call SPI functions within the iterator generating a set result would fail.

Fix bug in contrib/cube's GiST picksplit algorithm (Alexander Korotkov)


This could result in considerable inefficiency, though not actually incorrect answers, in a GiST index on a cube column. If you
have such an index, consider REINDEXing it after installing this update.

Don't emit identifier will be truncated notices in contrib/dblink except when creating new connections (Itagaki Takahiro)

Fix potential coredump on missing public key in contrib/pgcrypto (Marti Raudsepp)

Fix memory leak in contrib/xml2's XPath query functions (Tom Lane)


1582

Notes de version

Update time zone data files to tzdata release 2010o for DST law changes in Fiji and Samoa; also historical corrections for
Hong Kong.

E.87. Release 8.2.18


Release Date
2010-10-04
This release contains a variety of fixes from 8.2.17. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.87.1. Migration to Version 8.2.18


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.14, see Section E.91, Release 8.2.14 .

E.87.2. Changes

Use a separate interpreter for each calling SQL userid in PL/Perl and PL/Tcl (Tom Lane)
This change prevents security problems that can be caused by subverting Perl or Tcl code that will be executed later in the
same session under another SQL user identity (for example, within a SECURITY DEFINER function). Most scripting languages offer numerous ways that that might be done, such as redefining standard functions or operators called by the target
function. Without this change, any SQL user with Perl or Tcl language usage rights can do essentially anything with the SQL
privileges of the target function's owner.
The cost of this change is that intentional communication among Perl and Tcl functions becomes more difficult. To provide an
escape hatch, PL/PerlU and PL/TclU functions continue to use only one interpreter per session. This is not considered a security issue since all such functions execute at the trust level of a database superuser already.
It is likely that third-party procedural languages that claim to offer trusted execution have similar security issues. We advise
contacting the authors of any PL you are depending on for security-critical purposes.
Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433).

Prevent possible crashes in pg_get_expr() by disallowing it from being called with an argument that is not one of the system catalog columns it's intended to be used with (Heikki Linnakangas, Tom Lane)

Fix Windows shared-memory allocation code (Tsutomu Yamada, Magnus Hagander)


This bug led to the often-reported could not reattach to shared memory error message. This is a back-patch of a fix that
was applied to newer branches some time ago.

Treat exit code 128 (ERROR_WAIT_NO_CHILDREN) as non-fatal on Windows (Magnus Hagander)


Under high load, Windows processes will sometimes fail at startup with this error code. Formerly the postmaster treated this as
a panic condition and restarted the whole database, but that seems to be an overreaction.

Fix possible duplicate scans of UNION ALL member relations (Tom Lane)

Fix cannot handle unplanned sub-select error (Tom Lane)


This occurred when a sub-select contains a join alias reference that expands into an expression containing another sub-select.

Reduce PANIC to ERROR in some occasionally-reported btree failure cases, and provide additional detail in the resulting error messages (Tom Lane)
This should improve the system's robustness with corrupted indexes.

Prevent show_session_authorization() from crashing within autovacuum processes (Tom Lane)

Defend against functions returning setof record where not all the returned rows are actually of the same rowtype (Tom Lane)

Fix possible failure when hashing a pass-by-reference function result (Tao Ma, Tom Lane)

Take care to fsync the contents of lockfiles (both postmaster.pid and the socket lockfile) while writing them (Tom Lane)
This omission could result in corrupted lockfile contents if the machine crashes shortly after postmaster start. That could in
1583

Notes de version

turn prevent subsequent attempts to start the postmaster from succeeding, until the lockfile is manually removed.

Avoid recursion while assigning XIDs to heavily-nested subtransactions (Andres Freund, Robert Haas)
The original coding could result in a crash if there was limited stack space.

Fix log_line_prefix's %i escape, which could produce junk early in backend startup (Tom Lane)

Fix possible data corruption in ALTER TABLE ... SET TABLESPACE when archiving is enabled (Jeff Davis)

Allow CREATE DATABASE and ALTER DATABASE ... SET TABLESPACE to be interrupted by query-cancel
(Guillaume Lelarge)

In PL/Python, defend against null pointer results from PyCObject_AsVoidPtr and PyCObject_FromVoidPtr (Peter
Eisentraut)

Improve contrib/dblink's handling of tables containing dropped columns (Tom Lane)

Fix connection leak after duplicate connection name errors in contrib/dblink (Itagaki Takahiro)

Fix contrib/dblink to handle connection names longer than 62 bytes correctly (Itagaki Takahiro)

Add hstore(text, text) function to contrib/hstore (Robert Haas)


This function is the recommended substitute for the now-deprecated => operator. It was back-patched so that future-proofed
code can be used with older server versions. Note that the patch will be effective only after contrib/hstore is installed or
reinstalled in a particular database. Users might prefer to execute the CREATE FUNCTION command by hand, instead.

Update build infrastructure and documentation to reflect the source code repository's move from CVS to Git (Magnus Hagander and others)

Update time zone data files to tzdata release 2010l for DST law changes in Egypt and Palestine; also historical corrections for
Finland.
This change also adds new names for two Micronesian timezones: Pacific/Chuuk is now preferred over Pacific/Truk (and the
preferred abbreviation is CHUT not TRUT) and Pacific/Pohnpei is preferred over Pacific/Ponape.

Make Windows' N. Central Asia Standard Time timezone map to Asia/Novosibirsk, not Asia/Almaty (Magnus Hagander)
Microsoft changed the DST behavior of this zone in the timezone update from KB976098. Asia/Novosibirsk is a better match
to its new behavior.

E.88. Release 8.2.17


Release Date
2010-05-17
This release contains a variety of fixes from 8.2.16. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.88.1. Migration to Version 8.2.17


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.14, see Section E.91, Release 8.2.14 .

E.88.2. Changes

Enforce restrictions in plperl using an opmask applied to the whole interpreter, instead of using Safe.pm (Tim Bunce,
Andrew Dunstan)
Recent developments have convinced us that Safe.pm is too insecure to rely on for making plperl trustable. This change
removes use of Safe.pm altogether, in favor of using a separate interpreter with an opcode mask that is always applied. Pleasant side effects of the change include that it is now possible to use Perl's strict pragma in a natural way in plperl, and
that Perl's $a and $b variables work as expected in sort routines, and that function compilation is significantly faster.
(CVE-2010-1169)

Prevent PL/Tcl from executing untrustworthy code from pltcl_modules (Tom)


1584

Notes de version

PL/Tcl's feature for autoloading Tcl code from a database table could be exploited for trojan-horse attacks, because there was
no restriction on who could create or insert into that table. This change disables the feature unless pltcl_modules is owned by a
superuser. (However, the permissions on the table are not checked, so installations that really need a less-than-secure modules
table can still grant suitable privileges to trusted non-superusers.) Also, prevent loading code into the unrestricted normal
Tcl interpreter unless we are really going to execute a pltclu function. (CVE-2010-1170)

Fix possible crash if a cache reset message is received during rebuild of a relcache entry (Heikki)
This error was introduced in 8.2.16 while fixing a related failure.

Do not allow an unprivileged user to reset superuser-only parameter settings (Alvaro)


Previously, if an unprivileged user ran ALTER USER ... RESET ALL for himself, or ALTER DATABASE ... RESET
ALL for a database he owns, this would remove all special parameter settings for the user or database, even ones that are only
supposed to be changeable by a superuser. Now, the ALTER will only remove the parameters that the user has permission to
change.

Avoid possible crash during backend shutdown if shutdown occurs when a CONTEXT addition would be made to log entries
(Tom)
In some cases the context-printing function would fail because the current transaction had already been rolled back when it
came time to print a log message.

Update pl/perl's ppport.h for modern Perl versions (Andrew)

Fix assorted memory leaks in pl/python (Andreas Freund, Tom)

Prevent infinite recursion in psql when expanding a variable that refers to itself (Tom)

Fix psql's \copy to not add spaces around a dot within \copy (select ...) (Tom)
Addition of spaces around the decimal point in a numeric literal would result in a syntax error.

Ensure that contrib/pgstattuple functions respond to cancel interrupts promptly (Tatsuhito Kasahara)

Make server startup deal properly with the case that shmget() returns EINVAL for an existing shared memory segment
(Tom)
This behavior has been observed on BSD-derived kernels including OS X. It resulted in an entirely-misleading startup failure
complaining that the shared memory request size was too large.

Avoid possible crashes in syslogger process on Windows (Heikki)

Deal more robustly with incomplete time zone information in the Windows registry (Magnus)

Update the set of known Windows time zone names (Magnus)

Update time zone data files to tzdata release 2010j for DST law changes in Argentina, Australian Antarctic, Bangladesh,
Mexico, Morocco, Pakistan, Palestine, Russia, Syria, Tunisia; also historical corrections for Taiwan.
Also, add PKST (Pakistan Summer Time) to the default set of timezone abbreviations.

E.89. Release 8.2.16


Release Date
2010-03-15
This release contains a variety of fixes from 8.2.15. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.89.1. Migration to Version 8.2.16


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.14, see Section E.91, Release 8.2.14 .

E.89.2. Changes

Add new configuration parameter ssl_renegotiation_limit to control how often we do session key renegotiation for
1585

Notes de version

an SSL connection (Magnus)


This can be set to zero to disable renegotiation completely, which may be required if a broken SSL library is used. In particular, some vendors are shipping stopgap patches for CVE-2009-3555 that cause renegotiation attempts to fail.

Fix possible deadlock during backend startup (Tom)

Fix possible crashes due to not handling errors during relcache reload cleanly (Tom)

Fix possible crashes when trying to recover from a failure in subtransaction start (Tom)

Fix server memory leak associated with use of savepoints and a client encoding different from server's encoding (Tom)

Fix incorrect WAL data emitted during end-of-recovery cleanup of a GIST index page split (Yoichi Hirai)
This would result in index corruption, or even more likely an error during WAL replay, if we were unlucky enough to crash
during end-of-recovery cleanup after having completed an incomplete GIST insertion.

Make substring() for bit types treat any negative length as meaning all the rest of the string (Tom)
The previous coding treated only -1 that way, and would produce an invalid result value for other negative values, possibly
leading to a crash (CVE-2010-0442).

Fix integer-to-bit-string conversions to handle the first fractional byte correctly when the output bit width is wider than the given integer by something other than a multiple of 8 bits (Tom)

Fix some cases of pathologically slow regular expression matching (Tom)

Fix the STOP WAL LOCATION entry in backup history files to report the next WAL segment's name when the end location
is exactly at a segment boundary (Itagaki Takahiro)

Fix some more cases of temporary-file leakage (Heikki)


This corrects a problem introduced in the previous minor release. One case that failed is when a plpgsql function returning set
is called within another function's exception handler.

Improve constraint exclusion processing of boolean-variable cases, in particular make it possible to exclude a partition that has
a bool_column = false constraint (Tom)

When reading pg_hba.conf and related files, do not treat @something as a file inclusion request if the @ appears inside
quote marks; also, never treat @ by itself as a file inclusion request (Tom)
This prevents erratic behavior if a role or database name starts with @. If you need to include a file whose path name contains
spaces, you can still do so, but you must write @"/path to/file" rather than putting the quotes around the whole
construct.

Prevent infinite loop on some platforms if a directory is named as an inclusion target in pg_hba.conf and related files
(Tom)

Fix possible infinite loop if SSL_read or SSL_write fails without setting errno (Tom)
This is reportedly possible with some Windows versions of openssl.

Fix psql's numericlocale option to not format strings it shouldn't in latex and troff output formats (Heikki)

Make psql return the correct exit status (3) when ON_ERROR_STOP and --single-transaction are both specified and
an error occurs during the implied COMMIT (Bruce)

Fix plpgsql failure in one case where a composite column is set to NULL (Tom)

Fix possible failure when calling PL/Perl functions from PL/PerlU or vice versa (Tim Bunce)

Add volatile markings in PL/Python to avoid possible compiler-specific misbehavior (Zdenek Kotala)

Ensure PL/Tcl initializes the Tcl interpreter fully (Tom)


The only known symptom of this oversight is that the Tcl clock command misbehaves if using Tcl 8.5 or later.

Prevent crash in contrib/dblink when too many key columns are specified to a dblink_build_sql_* function
(Rushabh Lathia, Joe Conway)

Fix assorted crashes in contrib/xml2 caused by sloppy memory management (Tom)

Make building of contrib/xml2 more robust on Windows (Andrew)

Fix race condition in Windows signal handling (Radu Ilie)


1586

Notes de version

One known symptom of this bug is that rows in pg_listener could be dropped under heavy load.

Update time zone data files to tzdata release 2010e for DST law changes in Bangladesh, Chile, Fiji, Mexico, Paraguay, Samoa.

E.90. Release 8.2.15


Release Date
2009-12-14
This release contains a variety of fixes from 8.2.14. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.90.1. Migration to Version 8.2.15


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.14, see Section E.91, Release 8.2.14 .

E.90.2. Changes

Protect against indirect security threats caused by index functions changing session-local state (Gurjeet Singh, Tom)
This change prevents allegedly-immutable index functions from possibly subverting a superuser's session (CVE-2009-4136).

Reject SSL certificates containing an embedded null byte in the common name (CN) field (Magnus)
This prevents unintended matching of a certificate to a server or client name during SSL validation (CVE-2009-4034).

Fix possible crash during backend-startup-time cache initialization (Tom)

Prevent signals from interrupting VACUUM at unsafe times (Alvaro)


This fix prevents a PANIC if a VACUUM FULL is canceled after it's already committed its tuple movements, as well as transient errors if a plain VACUUM is interrupted after having truncated the table.

Fix possible crash due to integer overflow in hash table size calculation (Tom)
This could occur with extremely large planner estimates for the size of a hashjoin's result.

Fix very rare crash in inet/cidr comparisons (Chris Mikkelson)

Ensure that shared tuple-level locks held by prepared transactions are not ignored (Heikki)

Fix premature drop of temporary files used for a cursor that is accessed within a subtransaction (Heikki)

Fix incorrect logic for GiST index page splits, when the split depends on a non-first column of the index (Paul Ramsey)

Don't error out if recycling or removing an old WAL file fails at the end of checkpoint (Heikki)
It's better to treat the problem as non-fatal and allow the checkpoint to complete. Future checkpoints will retry the removal.
Such problems are not expected in normal operation, but have been seen to be caused by misdesigned Windows anti-virus and
backup software.

Ensure WAL files aren't repeatedly archived on Windows (Heikki)


This is another symptom that could happen if some other process interfered with deletion of a no-longer-needed file.

Fix PAM password processing to be more robust (Tom)


The previous code is known to fail with the combination of the Linux pam_krb5 PAM module with Microsoft Active Directory as the domain controller. It might have problems elsewhere too, since it was making unjustified assumptions about what
arguments the PAM stack would pass to it.

Fix processing of ownership dependencies during CREATE OR REPLACE FUNCTION (Tom)

Fix bug with calling plperl from plperlu or vice versa (Tom)
An error exit from the inner function could result in crashes due to failure to re-select the correct Perl interpreter for the outer
function.

1587

Notes de version

Fix session-lifespan memory leak when a PL/Perl function is redefined (Tom)

Ensure that Perl arrays are properly converted to PostgreSQL arrays when returned by a set-returning PL/Perl function
(Andrew Dunstan, Abhijit Menon-Sen)
This worked correctly already for non-set-returning functions.

Fix rare crash in exception processing in PL/Python (Peter)

Ensure psql's flex module is compiled with the correct system header definitions (Tom)
This fixes build failures on platforms where --enable-largefile causes incompatible changes in the generated code.

Make the postmaster ignore any application_name parameter in connection request packets, to improve compatibility
with future libpq versions (Tom)

Update the timezone abbreviation files to match current reality (Joachim Wieland)
This includes adding IDT and SGT to the default timezone abbreviation set.

Update time zone data files to tzdata release 2009s for DST law changes in Antarctica, Argentina, Bangladesh, Fiji, Novokuznetsk, Pakistan, Palestine, Samoa, Syria; also historical corrections for Hong Kong.

E.91. Release 8.2.14


Release Date
2009-09-09
This release contains a variety of fixes from 8.2.13. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.91.1. Migration to Version 8.2.14


A dump/restore is not required for those running 8.2.X. However, if you have any hash indexes on interval columns, you must
REINDEX them after updating to 8.2.14. Also, if you are upgrading from a version earlier than 8.2.11, see Section E.94,
Release 8.2.11 .

E.91.2. Changes

Force WAL segment switch during pg_start_backup() (Heikki)


This avoids corner cases that could render a base backup unusable.

Disallow RESET ROLE and RESET SESSION AUTHORIZATION inside security-definer functions (Tom, Heikki)
This covers a case that was missed in the previous patch that disallowed SET ROLE and SET SESSION AUTHORIZATION inside security-definer functions. (See CVE-2007-6600)

Make LOAD of an already-loaded loadable module into a no-op (Tom)


Formerly, LOAD would attempt to unload and re-load the module, but this is unsafe and not all that useful.

Disallow empty passwords during LDAP authentication (Magnus)

Fix handling of sub-SELECTs appearing in the arguments of an outer-level aggregate function (Tom)

Fix bugs associated with fetching a whole-row value from the output of a Sort or Materialize plan node (Tom)

Revert planner change that disabled partial-index and constraint exclusion optimizations when there were more than 100
clauses in an AND or OR list (Tom)

Fix hash calculation for data type interval (Tom)


This corrects wrong results for hash joins on interval values. It also changes the contents of hash indexes on interval columns.
If you have any such indexes, you must REINDEX them after updating.

Treat to_char(..., 'TH') as an uppercase ordinal suffix with 'HH'/'HH12' (Heikki)


It was previously handled as 'th' (lowercase).
1588

Notes de version

Fix overflow for INTERVAL 'x ms' when x is more than 2 million and integer datetimes are in use (Alex Hunsaker)

Fix calculation of distance between a point and a line segment (Tom)


This led to incorrect results from a number of geometric operators.

Fix money data type to work in locales where currency amounts have no fractional digits, e.g. Japan (Itagaki Takahiro)

Properly round datetime input like 00:12:57.9999999999999999999999999999 (Tom)

Fix poor choice of page split point in GiST R-tree operator classes (Teodor)

Avoid performance degradation in bulk inserts into GIN indexes when the input values are (nearly) in sorted order (Tom)

Correctly enforce NOT NULL domain constraints in some contexts in PL/pgSQL (Tom)

Fix portability issues in plperl initialization (Andrew Dunstan)

Fix pg_ctl to not go into an infinite loop if postgresql.conf is empty (Jeff Davis)

Make contrib/hstore throw an error when a key or value is too long to fit in its data structure, rather than silently truncating it (Andrew Gierth)

Fix contrib/xml2's xslt_process() to properly handle the maximum number of parameters (twenty) (Tom)

Improve robustness of libpq's code to recover from errors during COPY FROM STDIN (Tom)

Avoid including conflicting readline and editline header files when both libraries are installed (Zdenek Kotala)

Update time zone data files to tzdata release 2009l for DST law changes in Bangladesh, Egypt, Jordan, Pakistan, Argentina/
San_Luis, Cuba, Jordan (historical correction only), Mauritius, Morocco, Palestine, Syria, Tunisia.

E.92. Release 8.2.13


Release Date
2009-03-16
This release contains a variety of fixes from 8.2.12. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.92.1. Migration to Version 8.2.13


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.11, see Section E.94, Release 8.2.11 .

E.92.2. Changes

Prevent error recursion crashes when encoding conversion fails (Tom)


This change extends fixes made in the last two minor releases for related failure scenarios. The previous fixes were narrowly
tailored for the original problem reports, but we have now recognized that any error thrown by an encoding conversion function could potentially lead to infinite recursion while trying to report the error. The solution therefore is to disable translation
and encoding conversion and report the plain-ASCII form of any error message, if we find we have gotten into a recursive error reporting situation. (CVE-2009-0922)

Disallow CREATE CONVERSION with the wrong encodings for the specified conversion function (Heikki)
This prevents one possible scenario for encoding conversion failure. The previous change is a backstop to guard against other
kinds of failures in the same area.

Fix core dump when to_char() is given format codes that are inappropriate for the type of the data argument (Tom)

Fix possible failure in contrib/tsearch2 when C locale is used with a multi-byte encoding (Teodor)
Crashes were possible on platforms where wchar_t is narrower than int; Windows in particular.

Fix extreme inefficiency in contrib/tsearch2 parser's handling of an email-like string containing multiple @ characters
(Heikki)

Fix decompilation of CASE WHEN with an implicit coercion (Tom)


1589

Notes de version

This mistake could lead to Assert failures in an Assert-enabled build, or an unexpected CASE WHEN clause error message
in other cases, when trying to examine or dump a view.

Fix possible misassignment of the owner of a TOAST table's rowtype (Tom)


If CLUSTER or a rewriting variant of ALTER TABLE were executed by someone other than the table owner, the pg_type
entry for the table's TOAST table would end up marked as owned by that someone. This caused no immediate problems, since
the permissions on the TOAST rowtype aren't examined by any ordinary database operation. However, it could lead to unexpected failures if one later tried to drop the role that issued the command (in 8.1 or 8.2), or owner of data type appears to be
invalid warnings from pg_dump after having done so (in 8.3).

Fix PL/pgSQL to not treat INTO after INSERT as an INTO-variables clause anywhere in the string, not only at the start; in
particular, don't fail for INSERT INTO within CREATE RULE (Tom)

Clean up PL/pgSQL error status variables fully at block exit (Ashesh Vashi and Dave Page)
This is not a problem for PL/pgSQL itself, but the omission could cause the PL/pgSQL Debugger to crash while examining the
state of a function.

Retry failed calls to CallNamedPipe() on Windows (Steve Marshall, Magnus)


It appears that this function can sometimes fail transiently; we previously treated any failure as a hard error, which could
confuse LISTEN/NOTIFY as well as other operations.

Add MUST (Mauritius Island Summer Time) to the default list of known timezone abbreviations (Xavier Bugaud)

E.93. Release 8.2.12


Release Date
2009-02-02
This release contains a variety of fixes from 8.2.11. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.93.1. Migration to Version 8.2.12


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.11, see Section E.94, Release 8.2.11 .

E.93.2. Changes

Improve handling of URLs in headline() function (Teodor)

Improve handling of overlength headlines in headline() function (Teodor)

Prevent possible Assert failure or misconversion if an encoding conversion is created with the wrong conversion function for
the specified pair of encodings (Tom, Heikki)

Fix possible Assert failure if a statement executed in PL/pgSQL is rewritten into another kind of statement, for example if an
INSERT is rewritten into an UPDATE (Heikki)

Ensure that a snapshot is available to datatype input functions (Tom)


This primarily affects domains that are declared with CHECK constraints involving user-defined stable or immutable functions.
Such functions typically fail if no snapshot has been set.

Make it safer for SPI-using functions to be used within datatype I/O; in particular, to be used in domain check constraints
(Tom)

Avoid unnecessary locking of small tables in VACUUM (Heikki)

Fix a problem that made UPDATE RETURNING tableoid return zero instead of the correct OID (Tom)

Fix planner misestimation of selectivity when transitive equality is applied to an outer-join clause (Tom)
This could result in bad plans for queries like ... from a left join b on a.a1 = b.b1 where a.a1 = 42
...
1590

Notes de version

Improve optimizer's handling of long IN lists (Tom)


This change avoids wasting large amounts of time on such lists when constraint exclusion is enabled.

Ensure that the contents of a holdable cursor don't depend on the contents of TOAST tables (Tom)
Previously, large field values in a cursor result might be represented as TOAST pointers, which would fail if the referenced
table got dropped before the cursor is read, or if the large value is deleted and then vacuumed away. This cannot happen with
an ordinary cursor, but it could with a cursor that is held past its creating transaction.

Fix memory leak when a set-returning function is terminated without reading its whole result (Tom)

Fix contrib/dblink's dblink_get_result(text,bool) function (Joe)

Fix possible garbage output from contrib/sslinfo functions (Tom)

Fix configure script to properly report failure when unable to obtain linkage information for PL/Perl (Andrew)

Make all documentation reference pgsql-bugs and/or pgsql-hackers as appropriate, instead of the nowdecommissioned pgsql-ports and pgsql-patches mailing lists (Tom)

Update time zone data files to tzdata release 2009a (for Kathmandu and historical DST corrections in Switzerland, Cuba)

E.94. Release 8.2.11


Release Date
2008-11-03
This release contains a variety of fixes from 8.2.10. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.94.1. Migration to Version 8.2.11


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.7, see Section E.98, Release 8.2.7 . Also, if you were running a previous 8.2.X release, it is recommended to REINDEX all GiST indexes after the upgrade.

E.94.2. Changes

Fix GiST index corruption due to marking the wrong index entry dead after a deletion (Teodor)
This would result in index searches failing to find rows they should have found. Corrupted indexes can be fixed with REINDEX.

Fix backend crash when the client encoding cannot represent a localized error message (Tom)
We have addressed similar issues before, but it would still fail if the character has no equivalent message itself couldn't be
converted. The fix is to disable localization and send the plain ASCII error message when we detect such a situation.

Fix possible crash when deeply nested functions are invoked from a trigger (Tom)

Improve optimization of expression IN (expression-list) queries (Tom, per an idea from Robert Haas)
Cases in which there are query variables on the right-hand side had been handled less efficiently in 8.2.x and 8.3.x than in
prior versions. The fix restores 8.1 behavior for such cases.

Fix mis-expansion of rule queries when a sub-SELECT appears in a function call in FROM, a multi-row VALUES list, or a RETURNING list (Tom)
The usual symptom of this problem is an unrecognized node type error.

Fix memory leak during rescan of a hashed aggregation plan (Neil)

Ensure an error is reported when a newly-defined PL/pgSQL trigger function is invoked as a normal function (Tom)

Prevent possible collision of relfilenode numbers when moving a table to another tablespace with ALTER SET TABLESPACE (Heikki)
The command tried to re-use the existing filename, instead of picking one that is known unused in the destination directory.
1591

Notes de version

Fix incorrect tsearch2 headline generation when single query item matches first word of text (Sushant Sinha)

Fix improper display of fractional seconds in interval values when using a non-ISO datestyle in an -enable-integer-datetimes build (Ron Mayer)

Ensure SPI_getvalue and SPI_getbinval behave correctly when the passed tuple and tuple descriptor have different
numbers of columns (Tom)
This situation is normal when a table has had columns added or removed, but these two functions didn't handle it properly. The
only likely consequence is an incorrect error indication.

Fix ecpg's parsing of CREATE ROLE (Michael)

Fix recent breakage of pg_ctl restart (Tom)

Ensure pg_control is opened in binary mode (Itagaki Takahiro)


pg_controldata and pg_resetxlog did this incorrectly, and so could fail on Windows.

Update time zone data files to tzdata release 2008i (for DST law changes in Argentina, Brazil, Mauritius, Syria)

E.95. Release 8.2.10


Release Date
2008-09-22
This release contains a variety of fixes from 8.2.9. For information about new features in the 8.2 major release, see Section E.105,
Release 8.2 .

E.95.1. Migration to Version 8.2.10


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.7, see Section E.98, Release 8.2.7 .

E.95.2. Changes

Fix bug in btree WAL recovery code (Heikki)


Recovery failed if the WAL ended partway through a page split operation.

Fix potential miscalculation of datfrozenxid (Alvaro)


This error may explain some recent reports of failure to remove old pg_clog data.

Widen local lock counters from 32 to 64 bits (Tom)


This responds to reports that the counters could overflow in sufficiently long transactions, leading to unexpected lock is already held errors.

Fix possible duplicate output of tuples during a GiST index scan (Teodor)

Fix missed permissions checks when a view contains a simple UNION ALL construct (Heikki)
Permissions for the referenced tables were checked properly, but not permissions for the view itself.

Add checks in executor startup to ensure that the tuples produced by an INSERT or UPDATE will match the target table's
current rowtype (Tom)
ALTER COLUMN TYPE, followed by re-use of a previously cached plan, could produce this type of situation. The check
protects against data corruption and/or crashes that could ensue.

Fix possible repeated drops during DROP OWNED (Tom)


This would typically result in strange errors such as cache lookup failed for relation NNN .

Fix AT TIME ZONE to first try to interpret its timezone argument as a timezone abbreviation, and only try it as a full timezone name if that fails, rather than the other way around as formerly (Tom)
The timestamp input functions have always resolved ambiguous zone names in this order. Making AT TIME ZONE do so as
well improves consistency, and fixes a compatibility bug introduced in 8.1: in ambiguous cases we now behave the same as
1592

Notes de version

8.0 and before did, since in the older versions AT TIME ZONE accepted only abbreviations.

Fix datetime input functions to correctly detect integer overflow when running on a 64-bit platform (Tom)

Prevent integer overflows during units conversion when displaying a configuration parameter that has units (Tom)

Improve performance of writing very long log messages to syslog (Tom)

Allow spaces in the suffix part of an LDAP URL in pg_hba.conf (Tom)

Fix bug in backwards scanning of a cursor on a SELECT DISTINCT ON query (Tom)

Fix planner bug with nested sub-select expressions (Tom)


If the outer sub-select has no direct dependency on the parent query, but the inner one does, the outer value might not get recalculated for new parent query rows.

Fix planner to estimate that GROUP BY expressions yielding boolean results always result in two groups, regardless of the expressions' contents (Tom)
This is very substantially more accurate than the regular GROUP BY estimate for certain boolean tests like col IS NULL.

Fix PL/pgSQL to not fail when a FOR loop's target variable is a record containing composite-type fields (Tom)

Fix PL/Tcl to behave correctly with Tcl 8.5, and to be more careful about the encoding of data sent to or from Tcl (Tom)

On Windows, work around a Microsoft bug by preventing libpq from trying to send more than 64kB per system call (Magnus)

Improve pg_dump and pg_restore's error reporting after failure to send a SQL command (Tom)

Fix pg_ctl to properly preserve postmaster command-line arguments across a restart (Bruce)

Update time zone data files to tzdata release 2008f (for DST law changes in Argentina, Bahamas, Brazil, Mauritius, Morocco,
Pakistan, Palestine, and Paraguay)

E.96. Release 8.2.9


Release Date
2008-06-12
This release contains one serious and one minor bug fix over 8.2.8. For information about new features in the 8.2 major release,
see Section E.105, Release 8.2 .

E.96.1. Migration to Version 8.2.9


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.7, see Section E.98, Release 8.2.7 .

E.96.2. Changes

Make pg_get_ruledef() parenthesize negative constants (Tom)


Before this fix, a negative constant in a view or rule might be dumped as, say, -42::integer, which is subtly incorrect: it
should be (-42)::integer due to operator precedence rules. Usually this would make little difference, but it could interact with another recent patch to cause PostgreSQL to reject what had been a valid SELECT DISTINCT view query. Since
this could result in pg_dump output failing to reload, it is being treated as a high-priority fix. The only released versions in
which dump output is actually incorrect are 8.3.1 and 8.2.7.

Make ALTER AGGREGATE ... OWNER TO update pg_shdepend (Tom)


This oversight could lead to problems if the aggregate was later involved in a DROP OWNED or REASSIGN OWNED operation.

E.97. Release 8.2.8


Release Date
1593

Notes de version

never released
This release contains a variety of fixes from 8.2.7. For information about new features in the 8.2 major release, see Section E.105,
Release 8.2 .

E.97.1. Migration to Version 8.2.8


A dump/restore is not required for those running 8.2.X. However, if you are upgrading from a version earlier than 8.2.7, see Section E.98, Release 8.2.7 .

E.97.2. Changes

Fix ERRORDATA_STACK_SIZE exceeded crash that occurred on Windows when using UTF-8 database encoding and a
different client encoding (Tom)

Fix ALTER TABLE ADD COLUMN ... PRIMARY KEY so that the new column is correctly checked to see if it's been initialized to all non-nulls (Brendan Jurd)
Previous versions neglected to check this requirement at all.

Fix possible CREATE TABLE failure when alling the same constraint from multiple parent relations that alled that
constraint from a common ancestor (Tom)

Fix pg_get_ruledef() to show the alias, if any, attached to the target table of an UPDATE or DELETE (Tom)

Fix GIN bug that could result in a too many LWLocks taken failure (Teodor)

Avoid possible crash when decompressing corrupted data (Zdenek Kotala)

Repair two places where SIGTERM exit of a backend could leave corrupted state in shared memory (Tom)
Neither case is very important if SIGTERM is used to shut down the whole database cluster together, but there was a problem
if someone tried to SIGTERM individual backends.

Fix conversions between ISO-8859-5 and other encodings to handle Cyrillic Yo characters (e and E with two dots)
(Sergey Burladyan)

Fix several datatype input functions, notably array_in(), that were allowing unused bytes in their results to contain uninitialized, unpredictable values (Tom)
This could lead to failures in which two apparently identical literal values were not seen as equal, resulting in the parser complaining about unmatched ORDER BY and DISTINCT expressions.

Fix a corner case in regular-expression substring matching (substring(string from pattern)) (Tom)
The problem occurs when there is a match to the pattern overall but the user has specified a parenthesized subexpression and
that subexpression hasn't got a match. An example is substring('foo' from 'foo(bar)?'). This should return
NULL, since (bar) isn't matched, but it was mistakenly returning the whole-pattern match instead (ie, foo).

Update time zone data files to tzdata release 2008c (for DST law changes in Morocco, Iraq, Choibalsan, Pakistan, Syria, Cuba,
and Argentina/San_Luis)

Fix incorrect result from ecpg's PGTYPEStimestamp_sub() function (Michael)

Fix broken GiST comparison function for contrib/tsearch2's tsquery type (Teodor)

Fix possible crashes in contrib/cube functions (Tom)

Fix core dump in contrib/xml2's xpath_table() function when the input query returns a NULL value (Tom)

Fix contrib/xml2's makefile to not override CFLAGS (Tom)

Fix DatumGetBool macro to not fail with gcc 4.3 (Tom)


This problem affects old style (V0) C functions that return boolean. The fix is already in 8.3, but the need to back-patch it
was not realized at the time.

E.98. Release 8.2.7


1594

Notes de version

Release Date
2008-03-17
This release contains a variety of fixes from 8.2.6. For information about new features in the 8.2 major release, see Section E.105,
Release 8.2 .

E.98.1. Migration to Version 8.2.7


A dump/restore is not required for those running 8.2.X. However, you might need to REINDEX indexes on textual columns after
updating, if you are affected by the Windows locale issue described below.

E.98.2. Changes

Fix character string comparison for Windows locales that consider different character combinations as equal (Tom)
This fix applies only on Windows and only when using UTF-8 database encoding. The same fix was made for all other cases
over two years ago, but Windows with UTF-8 uses a separate code path that was not updated. If you are using a locale that
considers some non-identical strings as equal, you may need to REINDEX to fix existing indexes on textual columns.

Repair potential deadlock between concurrent VACUUM FULL operations on different system catalogs (Tom)

Fix longstanding LISTEN/NOTIFY race condition (Tom)


In rare cases a session that had just executed a LISTEN might not get a notification, even though one would be expected because the concurrent transaction executing NOTIFY was observed to commit later.
A side effect of the fix is that a transaction that has executed a not-yet-committed LISTEN command will not see any row in
pg_listener for the LISTEN, should it choose to look; formerly it would have. This behavior was never documented one way
or the other, but it is possible that some applications depend on the old behavior.

Disallow LISTEN and UNLISTEN within a prepared transaction (Tom)


This was formerly allowed but trying to do it had various unpleasant consequences, notably that the originating backend could
not exit as long as an UNLISTEN remained uncommitted.

Disallow dropping a temporary table within a prepared transaction (Heikki)


This was correctly disallowed by 8.1, but the check was inadvertently broken in 8.2.

Fix rare crash when an error occurs during a query using a hash index (Heikki)

Fix memory leaks in certain usages of set-returning functions (Neil)

Fix input of datetime values for February 29 in years BC (Tom)


The former coding was mistaken about which years were leap years.

Fix unrecognized node type error in some variants of ALTER OWNER (Tom)

Ensure pg_stat_activity.waiting flag is cleared when a lock wait is aborted (Tom)

Fix handling of process permissions on Windows Vista (Dave, Magnus)


In particular, this fix allows starting the server as the Administrator user.

Update time zone data files to tzdata release 2008a (in particular, recent Chile changes); adjust timezone abbreviation VET
(Venezuela) to mean UTC-4:30, not UTC-4:00 (Tom)

Fix pg_ctl to correctly extract the postmaster's port number from command-line options (Itagaki Takahiro, Tom)
Previously, pg_ctl start -w could try to contact the postmaster on the wrong port, leading to bogus reports of startup
failure.

Use -fwrapv to defend against possible misoptimization in recent gcc versions (Tom)
This is known to be necessary when building PostgreSQL with gcc 4.3 or later.

Correctly enforce statement_timeout values longer than INT_MAX microseconds (about 35 minutes) (Tom)
This bug affects only builds with --enable-integer-datetimes.

Fix unexpected PARAM_SUBLINK ID planner error when constant-folding simplifies a sub-select (Tom)
1595

Notes de version

Fix logical errors in constraint-exclusion handling of IS NULL and NOT expressions (Tom)
The planner would sometimes exclude partitions that should not have been excluded because of the possibility of NULL results.

Fix another cause of failed to build any N-way joins planner errors (Tom)
This could happen in cases where a clauseless join needed to be forced before a join clause could be exploited.

Fix incorrect constant propagation in outer-join planning (Tom)


The planner could sometimes incorrectly conclude that a variable could be constrained to be equal to a constant, leading to
wrong query results.

Fix display of constant expressions in ORDER BY and GROUP BY (Tom)


An explicitly casted constant would be shown incorrectly. This could for example lead to corruption of a view definition during dump and reload.

Fix libpq to handle NOTICE messages correctly during COPY OUT (Tom)
This failure has only been observed to occur when a user-defined datatype's output routine issues a NOTICE, but there is no
guarantee it couldn't happen due to other causes.

E.99. Release 8.2.6


Release Date
2008-01-07
This release contains a variety of fixes from 8.2.5, including fixes for significant security issues. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.99.1. Migration to Version 8.2.6


A dump/restore is not required for those running 8.2.X.

E.99.2. Changes

Prevent functions in indexes from executing with the privileges of the user running VACUUM, ANALYZE, etc (Tom)
Functions used in index expressions and partial-index predicates are evaluated whenever a new table entry is made. It has long
been understood that this poses a risk of trojan-horse code execution if one modifies a table owned by an untrustworthy user.
(Note that triggers, defaults, check constraints, etc. pose the same type of risk.) But functions in indexes pose extra danger because they will be executed by routine maintenance operations such as VACUUM FULL, which are commonly performed automatically under a superuser account. For example, a nefarious user can execute code with superuser privileges by setting up
a trojan-horse index definition and waiting for the next routine vacuum. The fix arranges for standard maintenance operations
(including VACUUM, ANALYZE, REINDEX, and CLUSTER) to execute as the table owner rather than the calling user,
using the same privilege-switching mechanism already used for SECURITY DEFINER functions. To prevent bypassing this
security measure, execution of SET SESSION AUTHORIZATION and SET ROLE is now forbidden within a SECURITY
DEFINER context. (CVE-2007-6600)

Repair assorted bugs in the regular-expression package (Tom, Will Drewry)


Suitably crafted regular-expression patterns could cause crashes, infinite or near-infinite looping, and/or massive memory
consumption, all of which pose denial-of-service hazards for applications that accept regex search patterns from untrustworthy
sources. (CVE-2007-4769, CVE-2007-4772, CVE-2007-6067)

Require non-superusers who use /contrib/dblink to use only password authentication, as a security measure (Joe)
The fix that appeared for this in 8.2.5 was incomplete, as it plugged the hole for only some dblink functions.
(CVE-2007-6601, CVE-2007-3278)

Fix bugs in WAL replay for GIN indexes (Teodor)

Fix GIN index build to work properly when maintenance_work_mem is 4GB or more (Tom)

Update time zone data files to tzdata release 2007k (in particular, recent Argentina changes) (Tom)
1596

Notes de version

Improve planner's handling of LIKE/regex estimation in non-C locales (Tom)

Fix planning-speed problem for deep outer-join nests, as well as possible poor choice of join order (Tom)

Fix planner failure in some cases of WHERE false AND var IN (SELECT ...) (Tom)

Make CREATE TABLE ... SERIAL and ALTER SEQUENCE ... OWNED BY not change the currval() state of the
sequence (Tom)

Preserve the tablespace and storage parameters of indexes that are rebuilt by ALTER TABLE ... ALTER COLUMN TYPE
(Tom)

Make archive recovery always start a new WAL timeline, rather than only when a recovery stop time was used (Simon)
This avoids a corner-case risk of trying to overwrite an existing archived copy of the last WAL segment, and seems simpler
and cleaner than the original definition.

Make VACUUM not use all of maintenance_work_mem when the table is too small for it to be useful (Alvaro)

Fix potential crash in translate() when using a multibyte database encoding (Tom)

Make corr() return the correct result for negative correlation values (Neil)

Fix overflow in extract(epoch from interval) for intervals exceeding 68 years (Tom)

Fix PL/Perl to not fail when a UTF-8 regular expression is used in a trusted function (Andrew)

Fix PL/Perl to cope when platform's Perl defines type bool as int rather than char (Tom)
While this could theoretically happen anywhere, no standard build of Perl did things this way ... until Mac OS X 10.5.

Fix PL/Python to work correctly with Python 2.5 on 64-bit machines (Marko Kreen)

Fix PL/Python to not crash on long exception messages (Alvaro)

Fix pg_dump to correctly handle allance child tables that have default expressions different from their parent's (Tom)

Fix libpq crash when PGPASSFILE refers to a file that is not a plain file (Martin Pitt)

ecpg parser fixes (Michael)

Make contrib/pgcrypto defend against OpenSSL libraries that fail on keys longer than 128 bits; which is the case at
least on some Solaris versions (Marko Kreen)

Make contrib/tablefunc's crosstab() handle NULL rowid as a category in its own right, rather than crashing (Joe)

Fix tsvector and tsquery output routines to escape backslashes correctly (Teodor, Bruce)

Fix crash of to_tsvector() on huge input strings (Teodor)

Require a specific version of Autoconf to be used when re-generating the configure script (Peter)
This affects developers and packagers only. The change was made to prevent accidental use of untested combinations of Autoconf and PostgreSQL versions. You can remove the version check if you really want to use a different Autoconf version, but it's your responsibility whether the result works or not.

Update gettimeofday configuration check so that PostgreSQL can be built on newer versions of MinGW (Magnus)

E.100. Release 8.2.5


Release Date
2007-09-17
This release contains a variety of fixes from 8.2.4. For information about new features in the 8.2 major release, see Section E.105,
Release 8.2 .

E.100.1. Migration to Version 8.2.5


A dump/restore is not required for those running 8.2.X.

E.100.2. Changes
1597

Notes de version

Prevent index corruption when a transaction inserts rows and then aborts close to the end of a concurrent VACUUM on the
same table (Tom)

Fix ALTER DOMAIN ADD CONSTRAINT for cases involving domains over domains (Tom)

Make CREATE DOMAIN ... DEFAULT NULL work properly (Tom)

Fix some planner problems with outer joins, notably poor size estimation for t1 LEFT JOIN t2 WHERE t2.col IS
NULL (Tom)

Allow the interval data type to accept input consisting only of milliseconds or microseconds (Neil)

Allow timezone name to appear before the year in timestamp input (Tom)

Fixes for GIN indexes used by /contrib/tsearch2 (Teodor)

Speed up rtree index insertion (Teodor)

Fix excessive logging of SSL error messages (Tom)

Fix logging so that log messages are never interleaved when using the syslogger process (Andrew)

Fix crash when log_min_error_statement logging runs out of memory (Tom)

Fix incorrect handling of some foreign-key corner cases (Tom)

Fix stddev_pop(numeric) and var_pop(numeric) (Tom)

Prevent REINDEX and CLUSTER from failing due to attempting to process temporary tables of other sessions (Alvaro)

Update the time zone database rules, particularly New Zealand's upcoming changes (Tom)

Windows socket and semaphore improvements (Magnus)

Make pg_ctl -w work properly in Windows service mode (Dave Page)

Fix memory allocation bug when using MIT Kerberos on Windows (Magnus)

Suppress timezone name (%Z) in log timestamps on Windows because of possible encoding mismatches (Tom)

Require non-superusers who use /contrib/dblink to use only password authentication, as a security measure (Joe)

Restrict /contrib/pgstattuple functions to superusers, for security reasons (Tom)

Do not let /contrib/intarray try to make its GIN opclass the default (this caused problems at dump/restore) (Tom)

E.101. Release 8.2.4


Release Date
2007-04-23
This release contains a variety of fixes from 8.2.3, including a security fix. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.101.1. Migration to Version 8.2.4


A dump/restore is not required for those running 8.2.X.

E.101.2. Changes

Support explicit placement of the temporary-table schema within search_path, and disable searching it for functions and
operators (Tom)
This is needed to allow a security-definer function to set a truly secure value of search_path. Without it, an unprivileged
SQL user can use temporary objects to execute code with the privileges of the security-definer function (CVE-2007-2138). See
CREATE FUNCTION for more information.

Fix shared_preload_libraries for Windows by forcing reload in each backend (Korry Douglas)

Fix to_char() so it properly upper/lower cases localized day or month names (Pavel Stehule)
1598

Notes de version

/contrib/tsearch2 crash fixes (Teodor)

Require COMMIT PREPARED to be executed in the same database as the transaction was prepared in (Heikki)

Allow pg_dump to do binary backups larger than two gigabytes on Windows (Magnus)

New traditional (Taiwan) Chinese FAQ (Zhou Daojing)

Prevent the statistics collector from writing to disk too frequently (Tom)

Fix potential-data-corruption bug in how VACUUM FULL handles UPDATE chains (Tom, Pavan Deolasee)

Fix bug in domains that use array types (Tom)

Fix pg_dump so it can dump a serial column's sequence using -t when not also dumping the owning table (Tom)

Planner fixes, including improving outer join and bitmap scan selection logic (Tom)

Fix possible wrong answers or crash when a PL/pgSQL function tries to RETURN from within an EXCEPTION block (Tom)

Fix PANIC during enlargement of a hash index (Tom)

Fix POSIX-style timezone specs to follow new USA DST rules (Tom)

E.102. Release 8.2.3


Release Date
2007-02-07
This release contains two fixes from 8.2.2. For information about new features in the 8.2 major release, see Section E.105,
Release 8.2 .

E.102.1. Migration to Version 8.2.3


A dump/restore is not required for those running 8.2.X.

E.102.2. Changes

Remove overly-restrictive check for type length in constraints and functional indexes(Tom)

Fix optimization so MIN/MAX in subqueries can again use indexes (Tom)

E.103. Release 8.2.2


Release Date
2007-02-05
This release contains a variety of fixes from 8.2.1, including a security fix. For information about new features in the 8.2 major release, see Section E.105, Release 8.2 .

E.103.1. Migration to Version 8.2.2


A dump/restore is not required for those running 8.2.X.

E.103.2. Changes

Remove security vulnerabilities that allowed connected users to read backend memory (Tom)
The vulnerabilities involve suppressing the normal check that a SQL function returns the data type it's declared to, and changing the data type of a table column (CVE-2007-0555, CVE-2007-0556). These errors can easily be exploited to cause a backend crash, and in principle might be used to read database content that the user should not be able to access.

Fix not-so-rare-anymore bug wherein btree index page splits could fail due to choosing an infeasible split point (Heikki Linna1599

Notes de version

kangas)

Fix Borland C compile scripts (L Bayuk)

Properly handle to_char('CC') for years ending in 00 (Tom)


Year 2000 is in the twentieth century, not the twenty-first.

/contrib/tsearch2 localization improvements (Tatsuo, Teodor)

Fix incorrect permission check in information_schema.key_column_usage view (Tom)


The symptom is relation with OID nnnnn does not exist errors. To get this fix without using initdb, use CREATE OR
REPLACE VIEW to install the corrected definition found in share/information_schema.sql. Note you will need
to do this in each database.

Improve VACUUM performance for databases with many tables (Tom)

Fix for rare Assert() crash triggered by UNION (Tom)

Fix potentially incorrect results from index searches using ROW inequality conditions (Tom)

Tighten security of multi-byte character processing for UTF8 sequences over three bytes long (Tom)

Fix bogus permission denied failures occurring on Windows due to attempts to fsync already-deleted files (Magnus, Tom)

Fix bug that could cause the statistics collector to hang on Windows (Magnus)
This would in turn lead to autovacuum not working.

Fix possible crashes when an already-in-use PL/pgSQL function is updated (Tom)

Improve PL/pgSQL handling of domain types (Sergiy Vyshnevetskiy, Tom)

Fix possible errors in processing PL/pgSQL exception blocks (Tom)

E.104. Release 8.2.1


Release Date
2007-01-08
This release contains a variety of fixes from 8.2. For information about new features in the 8.2 major release, see Section E.105,
Release 8.2 .

E.104.1. Migration to Version 8.2.1


A dump/restore is not required for those running 8.2.

E.104.2. Changes

Fix crash with SELECT ... LIMIT ALL (also LIMIT NULL) (Tom)

Several /contrib/tsearch2 fixes (Teodor)

On Windows, make log messages coming from the operating system use ASCII encoding (Hiroshi Saito)
This fixes a conversion problem when there is a mismatch between the encoding of the operating system and database server.

Fix Windows linking of pg_dump using win32.mak (Hiroshi Saito)

Fix planner mistakes for outer join queries (Tom)

Fix several problems in queries involving sub-SELECTs (Tom)

Fix potential crash in SPI during subtransaction abort (Tom)


This affects all PL functions since they all use SPI.

Improve build speed of PDF documentation (Peter)

Re-add JST (Japan) timezone abbreviation (Tom)


1600

Notes de version

Improve optimization decisions related to index scans (Tom)

Have psql print multi-byte combining characters as before, rather than output as \u (Tom)

Improve index usage of regular expressions that use parentheses (Tom)


This improves psql \d performance also.

Make pg_dumpall assume that databases have public CONNECT privilege, when dumping from a pre-8.2 server (Tom)
This preserves the previous behavior that anyone can connect to a database if allowed by pg_hba.conf.

E.105. Release 8.2


Release Date
2006-12-05

E.105.1. Overview
This release adds many functionality and performance improvements that were requested by users, including:

Query language enhancements including INSERT/UPDATE/DELETE RETURNING, multirow VALUES lists, and optional
target-table alias in UPDATE/DELETE

Index creation without blocking concurrent INSERT/UPDATE/DELETE operations

Many query optimization improvements, including support for reordering outer joins

Improved sorting performance with lower memory usage

More efficient locking with better concurrency

More efficient vacuuming

Easier administration of warm standby servers

New FILLFACTOR support for tables and indexes

Monitoring, logging, and performance tuning additions

More control over creating and dropping objects

Table allance relationships can be defined for and removed from pre-existing tables

COPY TO can copy the output of an arbitrary SELECT statement

Array improvements, including nulls in arrays

Aggregate-function improvements, including multiple-input aggregates and SQL:2003 statistical functions

Many contrib/ improvements

E.105.2. Migration to Version 8.2


A dump/restore using pg_dump is required for those wishing to migrate data from any previous release.
Observe the following incompatibilities:

Set escape_string_warning to on by default (Bruce)


This issues a warning if backslash escapes are used in non-escape (non-E'') strings.

Change the row constructor syntax (ROW(...)) so that list elements foo.* will be expanded to a list of their member fields,
rather than creating a nested row type field as formerly (Tom)
The new behavior is substantially more useful since it allows, for example, triggers to check for data changes with IF
row(new.*) IS DISTINCT FROM row(old.*). The old behavior is still available by omitting .*.

Make row comparisons follow SQL standard semantics and allow them to be used in index scans (Tom)

1601

Notes de version

Previously, row = and <> comparisons followed the standard but < <= > >= did not. A row comparison can now be used as an
index constraint for a multicolumn index matching the row value.

Make row IS [NOT] NULL tests follow SQL standard semantics (Tom)
The former behavior conformed to the standard for simple cases with IS NULL, but IS NOT NULL would return true if any
row field was non-null, whereas the standard says it should return true only when all fields are non-null.

Make SET CONSTRAINT affect only one constraint (Kris Jurka)


In previous releases, SET CONSTRAINT modified all constraints with a matching name. In this release, the schema search
path is used to modify only the first matching constraint. A schema specification is also supported. This more nearly conforms
to the SQL standard.

Remove RULE permission for tables, for security reasons (Tom)


As of this release, only a table's owner can create or modify rules for the table. For backwards compatibility, GRANT/REVOKE RULE is still accepted, but it does nothing.

Array comparison improvements (Tom)


Now array dimensions are also compared.

Change array concatenation to match documented behavior (Tom)


This changes the previous behavior where concatenation would modify the array lower bound.

Make command-line options of postmaster and postgres identical (Peter)


This allows the postmaster to pass arguments to each backend without using -o. Note that some options are now only available as long-form options, because there were conflicting single-letter options.

Deprecate use of postmaster symbolic link (Peter)


postmaster and postgres commands now act identically, with the behavior determined by command-line options. The postmaster symbolic link is kept for compatibility, but is not really needed.

Change log_duration to output even if the query is not output (Tom)


In prior releases, log_duration only printed if the query appeared earlier in the log.

Make to_char(time) and to_char(interval) treat HH and HH12 as 12-hour intervals


Most applications should use HH24 unless they want a 12-hour display.

Zero unmasked bits in conversion from INET to CIDR (Tom)


This ensures that the converted value is actually valid for CIDR.

Remove australian_timezones configuration variable (Joachim Wieland)


This variable has been superseded by a more general facility for configuring timezone abbreviations.

Improve cost estimation for nested-loop index scans (Tom)


This might eliminate the need to set unrealistically small values of random_page_cost. If you have been using a very
small random_page_cost, please recheck your test cases.

Change behavior of pg_dump -n and -t options. (Greg Sabino Mullane)


See the pg_dump manual page for details.

Change libpq PQdsplen() to return a useful value (Martijn van Oosterhout)

Declare libpq PQgetssl() as returning void *, rather than SSL * (Martijn van Oosterhout)
This allows applications to use the function without including the OpenSSL headers.

C-language loadable modules must now include a PG_MODULE_MAGIC macro call for version compatibility checking
(Martijn van Oosterhout)

For security's sake, modules used by a PL/PerlU function are no longer available to PL/Perl functions (Andrew)

Note
This also implies that data can no longer be shared between a PL/Perl function and a PL/PerlU function. Some
1602

Notes de version

Perl installations have not been compiled with the correct flags to allow multiple interpreters to exist within a
single process. In this situation PL/Perl and PL/PerlU cannot both be used in a single backend. The solution is
to get a Perl installation which supports multiple interpreters.

In contrib/xml2/, rename xml_valid() to xml_is_well_formed() (Tom)


xml_valid() will remain for backward compatibility, but its behavior will change to do schema checking in a future release.

Remove contrib/ora2pg/, now at http://www.samse.fr/gpl/ora2pg

Remove contrib modules that have been migrated to PgFoundry: adddepend, dbase, dbmirror, fulltextindex,
mac, userlock

Remove abandoned contrib modules: mSQL-interface, tips

Remove QNX and BEOS ports (Bruce)


These ports no longer had active maintainers.

E.105.3. Changes
Below you will find a detailed account of the changes between PostgreSQL 8.2 and the previous major release.

E.105.3.1. Performance Improvements

Allow the planner to reorder outer joins in some circumstances (Tom)


In previous releases, outer joins would always be evaluated in the order written in the query. This change allows the query optimizer to consider reordering outer joins, in cases where it can determine that the join order can be changed without altering
the meaning of the query. This can make a considerable performance difference for queries involving multiple outer joins or
mixed inner and outer joins.

Improve efficiency of IN (list-of-expressions) clauses (Tom)

Improve sorting speed and reduce memory usage (Simon, Tom)

Improve subtransaction performance (Alvaro, Itagaki Takahiro, Tom)

Add FILLFACTOR to table and index creation (ITAGAKI Takahiro)


This leaves extra free space in each table or index page, allowing improved performance as the database grows. This is particularly valuable to maintain clustering.

Increase default values for shared_buffers and max_fsm_pages (Andrew)

Improve locking performance by breaking the lock manager tables into sections (Tom)
This allows locking to be more fine-grained, reducing contention.

Reduce locking requirements of sequential scans (Qingqing Zhou)

Reduce locking required for database creation and destruction (Tom)

Improve the optimizer's selectivity estimates for LIKE, ILIKE, and regular expression operations (Tom)

Improve planning of joins to inherited tables and UNION ALL views (Tom)

Allow constraint exclusion to be applied to inherited UPDATE and DELETE queries (Tom)
SELECT already honored constraint exclusion.

Improve planning of constant WHERE clauses, such as a condition that depends only on variables alled from an outer query level (Tom)

Protocol-level unnamed prepared statements are re-planned for each set of BIND values (Tom)
This improves performance because the exact parameter values can be used in the plan.

Speed up vacuuming of B-Tree indexes (Heikki Linnakangas, Tom)

Avoid extra scan of tables without indexes during VACUUM (Greg Stark)
1603

Notes de version

Improve multicolumn GiST indexing (Oleg, Teodor)

Remove dead index entries before B-Tree page split (Junji Teramoto)

E.105.3.2. Server Changes

Allow a forced switch to a new transaction log file (Simon, Tom)


This is valuable for keeping warm standby slave servers in sync with the master. Transaction log file switching now also happens automatically during pg_stop_backup(). This ensures that all transaction log files needed for recovery can be archived immediately.

Add WAL informational functions (Simon)


Add functions for interrogating the current transaction log insertion point and determining WAL filenames from the hex WAL
locations displayed by pg_stop_backup() and related functions.

Improve recovery from a crash during WAL replay (Simon)


The server now does periodic checkpoints during WAL recovery, so if there is a crash, future WAL recovery is shortened.
This also eliminates the need for warm standby servers to replay the entire log since the base backup if they crash.

Improve reliability of long-term WAL replay (Heikki, Simon, Tom)


Formerly, trying to roll forward through more than 2 billion transactions would not work due to XID wraparound. This meant
warm standby servers had to be reloaded from fresh base backups periodically.

Add archive_timeout to force transaction log file switches at a given interval (Simon)
This enforces a maximum replication delay for warm standby servers.

Add native LDAP authentication (Magnus Hagander)


This is particularly useful for platforms that do not support PAM, such as Windows.

Add GRANT CONNECT ON DATABASE (Gevik Babakhani)


This gives SQL-level control over database access. It works as an additional filter on top of the existing pg_hba.conf
controls.

Add support for SSL Certificate Revocation List (CRL) files (Libor Hoho)
The server and libpq both recognize CRL files now.

GiST indexes are now clusterable (Teodor)

Remove routine autovacuum server log entries (Bruce)


pg_stat_activity now shows autovacuum activity.

Track maximum XID age within individual tables, instead of whole databases (Alvaro)
This reduces the overhead involved in preventing transaction ID wraparound, by avoiding unnecessary VACUUMs.

Add last vacuum and analyze timestamp columns to the stats collector (Larry Rosenman)
These values now appear in the pg_stat_*_tables system views.

Improve performance of statistics monitoring, especially stats_command_string (Tom, Bruce)


This release enables stats_command_string by default, now that its overhead is minimal. This means
pg_stat_activity will now show all active queries by default.

Add a waiting column to pg_stat_activity (Tom)


This allows pg_stat_activity to show all the information included in the ps display.

Add configuration parameter update_process_title to control whether the ps display is updated for every command
(Bruce)
On platforms where it is expensive to update the ps display, it might be worthwhile to turn this off and rely solely on
pg_stat_activity for status information.

Allow units to be specified in configuration settings (Peter)


For example, you can now set shared_buffers to 32MB rather than mentally converting sizes.
1604

Notes de version

Add support for include directives in postgresql.conf (Joachim Wieland)

Improve logging of protocol-level prepare/bind/execute messages (Bruce, Tom)


Such logging now shows statement names, bind parameter values, and the text of the query being executed. Also, the query
text is properly included in logged error messages when enabled by log_min_error_statement.

Prevent max_stack_depth from being set to unsafe values


On platforms where we can determine the actual kernel stack depth limit (which is most), make sure that the initial default value of max_stack_depth is safe, and reject attempts to set it to unsafely large values.

Enable highlighting of error location in query in more cases (Tom)


The server is now able to report a specific error location for some semantic errors (such as unrecognized column name), rather
than just for basic syntax errors as before.

Fix failed to re-find parent key errors in VACUUM (Tom)

Clean out pg_internal.init cache files during server restart (Simon)


This avoids a hazard that the cache files might contain stale data after PITR recovery.

Fix race condition for truncation of a large relation across a gigabyte boundary by VACUUM (Tom)

Fix bug causing needless deadlock errors on row-level locks (Tom)

Fix bugs affecting multi-gigabyte hash indexes (Tom)

Each backend process is now its own process group leader (Tom)
This allows query cancel to abort subprocesses invoked from a backend or archive/recovery process.

E.105.3.3. Query Changes

Add INSERT/UPDATE/DELETE RETURNING (Jonah Harris, Tom)


This allows these commands to return values, such as the computed serial key for a new row. In the UPDATE case, values
from the updated version of the row are returned.

Add support for multiple-row VALUES clauses, per SQL standard (Joe, Tom)
This allows INSERT to insert multiple rows of constants, or queries to generate result sets using constants. For example, INSERT ... VALUES (...), (...), ...., and SELECT * FROM (VALUES (...), (...), ....) AS
alias(f1, ...).

Allow UPDATE and DELETE to use an alias for the target table (Atsushi Ogawa)
The SQL standard does not permit an alias in these commands, but many database systems allow one anyway for notational
convenience.

Allow UPDATE to set multiple columns with a list of values (Susanne Ebrecht)
This is basically a short-hand for assigning the columns and values in pairs. The syntax is UPDATE tab SET (column,
...) = (val, ...).

Make row comparisons work per standard (Tom)


The forms <, <=, >, >= now compare rows lexicographically, that is, compare the first elements, if equal compare the second
elements, and so on. Formerly they expanded to an AND condition across all the elements, which was neither standard nor very useful.

Add CASCADE option to TRUNCATE (Joachim Wieland)


This causes TRUNCATE to automatically include all tables that reference the specified table(s) via foreign keys. While
convenient, this is a dangerous tool -- use with caution!

Support FOR UPDATE and FOR SHARE in the same SELECT command (Tom)

Add IS NOT DISTINCT FROM (Pavel Stehule)


This operator is similar to equality (=), but evaluates to true when both left and right operands are NULL, and to false when
just one is, rather than yielding NULL in these cases.

Improve the length output used by UNION/INTERSECT/EXCEPT (Tom)


1605

Notes de version

When all corresponding columns are of the same defined length, that length is used for the result, rather than a generic length.

Allow ILIKE to work for multi-byte encodings (Tom)


Internally, ILIKE now calls lower() and then uses LIKE. Locale-specific regular expression patterns still do not work in
these encodings.

Enable standard_conforming_strings to be turned on (Kevin Grittner)


This allows backslash escaping in strings to be disabled, making PostgreSQL more standards-compliant. The default is off
for backwards compatibility, but future releases will default this to on.

Do not flatten subqueries that contain volatile functions in their target lists (Jaime Casanova)
This prevents surprising behavior due to multiple evaluation of a volatile function (such as random() or nextval()).
It might cause performance degradation in the presence of functions that are unnecessarily marked as volatile.

Add system views pg_prepared_statements and pg_cursors to show prepared statements and open cursors
(Joachim Wieland, Neil)
These are very useful in pooled connection setups.

Support portal parameters in EXPLAIN and EXECUTE (Tom)


This allows, for example, JDBC ? parameters to work in these commands.

If SQL-level PREPARE parameters are unspecified, infer their types from the content of the query (Neil)
Protocol-level PREPARE already did this.

Allow LIMIT and OFFSET to exceed two billion (Dhanaraj M)

E.105.3.4. Object Manipulation Changes

Add TABLESPACE clause to CREATE TABLE AS (Neil)


This allows a tablespace to be specified for the new table.

Add ON COMMIT clause to CREATE TABLE AS (Neil)


This allows temporary tables to be truncated or dropped on transaction commit. The default behavior is for the table to remain
until the session ends.

Add INCLUDING CONSTRAINTS to CREATE TABLE LIKE (Greg Stark)


This allows easy copying of CHECK constraints to a new table.

Allow the creation of placeholder (shell) types (Martijn van Oosterhout)


A shell type declaration creates a type name, without specifying any of the details of the type. Making a shell type is useful because it allows cleaner declaration of the type's input/output functions, which must exist before the type can be defined for
real . The syntax is CREATE TYPE typename.

Aggregate functions now support multiple input parameters (Sergey Koposov, Tom)

Add new aggregate creation syntax (Tom)


The new syntax is CREATE AGGREGATE aggname (input_type) (parameter_list). This more naturally supports the new multi-parameter aggregate functionality. The previous syntax is still supported.

Add ALTER ROLE PASSWORD NULL to remove a previously set role password (Peter)

Add DROP object IF EXISTS for many object types (Andrew)


This allows DROP operations on non-existent objects without generating an error.

Add DROP OWNED to drop all objects owned by a role (Alvaro)

Add REASSIGN OWNED to reassign ownership of all objects owned by a role (Alvaro)
This, and DROP OWNED above, facilitate dropping roles.

Add GRANT ON SEQUENCE syntax (Bruce)


This was added for setting sequence-specific permissions. GRANT ON TABLE for sequences is still supported for backward
1606

Notes de version

compatibility.

Add USAGE permission for sequences that allows only currval() and nextval(), not setval() (Bruce)
USAGE permission allows more fine-grained control over sequence access. Granting USAGE allows users to increment a sequence, but prevents them from setting the sequence to an arbitrary value using setval().

Add ALTER TABLE [ NO ] INHERIT (Greg Stark)


This allows allance to be adjusted dynamically, rather than just at table creation and destruction. This is very valuable when
using allance to implement table partitioning.

Allow comments on global objects to be stored globally (Kris Jurka)


Previously, comments attached to databases were stored in individual databases, making them ineffective, and there was no
provision at all for comments on roles or tablespaces. This change adds a new shared catalog pg_shdescription and stores comments on databases, roles, and tablespaces therein.

E.105.3.5. Utility Command Changes

Add option to allow indexes to be created without blocking concurrent writes to the table (Greg Stark, Tom)
The new syntax is CREATE INDEX CONCURRENTLY. The default behavior is still to block table modification while a
index is being created.

Provide advisory locking functionality (Abhijit Menon-Sen, Tom)


This is a new locking API designed to replace what used to be in /contrib/userlock. The userlock code is now on pgfoundry.

Allow COPY to dump a SELECT query (Zoltan Boszormenyi, Karel Zak)


This allows COPY to dump arbitrary SQL queries. The syntax is COPY (SELECT ...) TO.

Make the COPY command return a command tag that includes the number of rows copied (Volkan YAZICI)

Allow VACUUM to expire rows without being affected by other concurrent VACUUM operations (Hannu Krossing, Alvaro,
Tom)

Make initdb detect the operating system locale and set the default DateStyle accordingly (Peter)
This makes it more likely that the installed postgresql.conf DateStyle value will be as desired.

Reduce number of progress messages displayed by initdb (Tom)

E.105.3.6. Date/Time Changes

Allow full timezone names in timestamp input values (Joachim Wieland)


For example, '2006-05-24 21:11 America/New_York'::timestamptz.

Support configurable timezone abbreviations (Joachim Wieland)


A desired set of timezone abbreviations can be chosen via the configuration parameter timezone_abbreviations.

Add pg_timezone_abbrevs and pg_timezone_names views to show supported timezones (Magnus Hagander)

Add clock_timestamp(), statement_timestamp(), and transaction_timestamp() (Bruce)


clock_timestamp() is the current wall-clock time, statement_timestamp() is the time the current statement arrived at the server, and transaction_timestamp() is an alias for now().

Allow to_char() to print localized month and day names (Euler Taveira de Oliveira)

Allow to_char(time) and to_char(interval) to output AM/PM specifications (Bruce)


Intervals and times are treated as 24-hour periods, e.g. 25 hours is considered AM.

Add new function justify_interval() to adjust interval units (Mark Dilger)

Allow timezone offsets up to 14:59 away from GMT


Kiribati uses GMT+14, so we'd better accept that.

Interval computation improvements (Michael Glaesemann, Bruce)


1607

Notes de version

E.105.3.7. Other Data Type and Function Changes

Allow arrays to contain NULL elements (Tom)

Allow assignment to array elements not contiguous with the existing entries (Tom)
The intervening array positions will be filled with nulls. This is per SQL standard.

New built-in operators for array-subset comparisons (@>, <@, &&) (Teodor, Tom)
These operators can be indexed for many data types using GiST or GIN indexes.

Add convenient arithmetic operations on INET/CIDR values (Stephen R. van den Berg)
The new operators are & (and), | (or), ~ (not), inet + int8, inet - int8, and inet - inet.

Add new aggregate functions from SQL:2003 (Neil)


The new functions are var_pop(), var_samp(), stddev_pop(), and stddev_samp(). var_samp() and stddev_samp() are merely renamings of the existing aggregates variance() and stddev(). The latter names remain available for backward compatibility.

Add SQL:2003 statistical aggregates (Sergey Koposov)


New functions: regr_intercept(), regr_slope(), regr_r2(), corr(), covar_samp(), covar_pop(), regr_avgx(), regr_avgy(), regr_sxy(), regr_sxx(), regr_syy(), regr_count().

Allow domains to be based on other domains (Tom)

Properly enforce domain CHECK constraints everywhere (Neil, Tom)


For example, the result of a user-defined function that is declared to return a domain type is now checked against the domain's
constraints. This closes a significant hole in the domain implementation.

Fix problems with dumping renamed SERIAL columns (Tom)


The fix is to dump a SERIAL column by explicitly specifying its DEFAULT and sequence elements, and reconstructing the
SERIAL column on reload using a new ALTER SEQUENCE OWNED BY command. This also allows dropping a SERIAL
column specification.

Add a server-side sleep function pg_sleep() (Joachim Wieland)

Add all comparison operators for the tid (tuple id) data type (Mark Kirkwood, Greg Stark, Tom)

E.105.3.8. PL/pgSQL Server-Side Language Changes

Add TG_table_name and TG_table_schema to trigger parameters (Andrew)


TG_relname is now deprecated. Comparable changes have been made in the trigger parameters for the other PLs as well.

Allow FOR statements to return values to scalars as well as records and row types (Pavel Stehule)

Add a BY clause to the FOR loop, to control the iteration increment (Jaime Casanova)

Add STRICT to SELECT INTO (Matt Miller)


STRICT mode throws an exception if more or less than one row is returned by the SELECT, for Oracle PL/SQL compatibility.

E.105.3.9. PL/Perl Server-Side Language Changes

Add table_name and table_schema to trigger parameters (Adam Sjgren)

Add prepared queries (Dmitry Karasik)

Make $_TD trigger data a global variable (Andrew)


Previously, it was lexical, which caused unexpected sharing violations.

Run PL/Perl and PL/PerlU in separate interpreters, for security reasons (Andrew)
In consequence, they can no longer share data nor loaded modules. Also, if Perl has not been compiled with the requisite flags
to allow multiple interpreters, only one of these languages can be used in any given backend process.
1608

Notes de version

E.105.3.10. PL/Python Server-Side Language Changes

Named parameters are passed as ordinary variables, as well as in the args[] array (Sven Suursoho)

Add table_name and table_schema to trigger parameters (Andrew)

Allow returning of composite types and result sets (Sven Suursoho)

Return result-set as list, iterator, or generator (Sven Suursoho)

Allow functions to return void (Neil)

Python 2.5 is now supported (Tom)

E.105.3.11. psql Changes

Add new command \password for changing role password with client-side password encryption (Peter)

Allow \c to connect to a new host and port number (David, Volkan YAZICI)

Add tablespace display to \l+ (Philip Yarra)

Improve \df slash command to include the argument names and modes (OUT or INOUT) of the function (David Fetter)

Support binary COPY (Andreas Pflug)

Add option to run the entire session in a single transaction (Simon)


Use option -1 or --single-transaction.

Support for automatically retrieving SELECT results in batches using a cursor (Chris Mair)
This is enabled using \set FETCH_COUNT n. This feature allows large result sets to be retrieved in psql without attempting
to buffer the entire result set in memory.

Make multi-line values align in the proper column (Martijn van Oosterhout)
Field values containing newlines are now displayed in a more readable fashion.

Save multi-line statements as a single entry, rather than one line at a time (Sergey E. Koposov)
This makes up-arrow recall of queries easier. (This is not available on Windows, because that platform uses the native command-line editing present in the operating system.)

Make the line counter 64-bit so it can handle files with more than two billion lines (David Fetter)

Report both the returned data and the command status tag for INSERT/UPDATE/DELETE RETURNING (Tom)

E.105.3.12. pg_dump Changes

Allow complex selection of objects to be included or excluded by pg_dump (Greg Sabino Mullane)
pg_dump now supports multiple -n (schema) and -t (table) options, and adds -N and -T options to exclude objects. Also,
the arguments of these switches can now be wild-card expressions rather than single object names, for example -t 'foo*',
and a schema can be part of a -t or -T switch, for example -t schema1.table1.

Add pg_restore --no-data-for-failed-tables option to suppress loading data if table creation failed (i.e., the table
already exists) (Martin Pitt)

Add pg_restore option to run the entire session in a single transaction (Simon)
Use option -1 or --single-transaction.

E.105.3.13. libpq Changes

Add PQencryptPassword() to encrypt passwords (Tom)


This allows passwords to be sent pre-encrypted for commands like ALTER ROLE ... PASSWORD.

Add function PQisthreadsafe() (Bruce)

1609

Notes de version

This allows applications to query the thread-safety status of the library.

Add PQdescribePrepared(), PQdescribePortal(), and related functions to return information about previously
prepared statements and open cursors (Volkan YAZICI)

Allow LDAP lookups from pg_service.conf (Laurenz Albe)

Allow a hostname in ~/.pgpass to match the default socket directory (Bruce)


A blank hostname continues to match any Unix-socket connection, but this addition allows entries that are specific to one of
several postmasters on the machine.

E.105.3.14. ecpg Changes

Allow SHOW to put its result into a variable (Joachim Wieland)

Add COPY TO STDOUT (Joachim Wieland)

Add regression tests (Joachim Wieland, Michael)

Major source code cleanups (Joachim Wieland, Michael)

E.105.3.15. Windows Port

Allow MSVC to compile the PostgreSQL server (Magnus, Hiroshi Saito)

Add MSVC support for utility commands and pg_dump (Hiroshi Saito)

Add support for Windows code pages 1253, 1254, 1255, and 1257 (Kris Jurka)

Drop privileges on startup, so that the server can be started from an administrative account (Magnus)

Stability fixes (Qingqing Zhou, Magnus)

Add native semaphore implementation (Qingqing Zhou)


The previous code mimicked SysV semaphores.

E.105.3.16. Source Code Changes

Add GIN (Generalized Inverted iNdex) index access method (Teodor, Oleg)

Remove R-tree indexing (Tom)


Rtree has been re-implemented using GiST. Among other differences, this means that rtree indexes now have support for crash
recovery via write-ahead logging (WAL).

Reduce libraries needlessly linked into the backend (Martijn van Oosterhout, Tom)

Add a configure flag to allow libedit to be preferred over GNU readline (Bruce)
Use configure --with-libedit-preferred.

Allow installation into directories containing spaces (Peter)

Improve ability to relocate installation directories (Tom)

Add support for Solaris x86_64 using the Solaris compiler (Pierre Girard, Theo Schlossnagle, Bruce)

Add DTrace support (Robert Lor)

Add PG_VERSION_NUM for use by third-party applications wanting to test the backend version in C using > and < comparisons (Bruce)

Add XLOG_BLCKSZ as independent from BLCKSZ (Mark Wong)

Add LWLOCK_STATS define to report locking activity (Tom)

Emit warnings for unknown configure options (Martijn van Oosterhout)

Add server support for plugin libraries that can be used for add-on tasks such as debugging and performance measurement
(Korry Douglas)
1610

Notes de version

This consists of two features: a table of rendezvous variables that allows separately-loaded shared libraries to communicate, and a new configuration parameter local_preload_libraries that allows libraries to be loaded into specific sessions without explicit cooperation from the client application. This allows external add-ons to implement features such as a
PL/pgSQL debugger.

Rename existing configuration parameter preload_libraries to shared_preload_libraries (Tom)


This was done for clarity in comparison to local_preload_libraries.

Add new configuration parameter server_version_num (Greg Sabino Mullane)


This is like server_version, but is an integer, e.g. 80200. This allows applications to make version checks more easily.

Add a configuration parameter seq_page_cost (Tom)

Re-implement the regression test script as a C program (Magnus, Tom)

Allow loadable modules to allocate shared memory and lightweight locks (Marc Munro)

Add automatic initialization and finalization of dynamically loaded libraries (Ralf Engelschall, Tom)
New functions _PG_init() and _PG_fini() are called if the library defines such symbols. Hence we no longer need to
specify an initialization function in shared_preload_libraries; we can assume that the library used the
_PG_init() convention instead.

Add PG_MODULE_MAGIC header block to all shared object files (Martijn van Oosterhout)
The magic block prevents version mismatches between loadable object files and servers.

Add shared library support for AIX (Laurenz Albe)

New XML documentation section (Bruce)

E.105.3.17. Contrib Changes

Major tsearch2 improvements (Oleg, Teodor)

multibyte encoding support, including UTF8

query rewriting support

improved ranking functions

thesaurus dictionary support

Ispell dictionaries now recognize MySpell format, used by OpenOffice

GIN support

Add adminpack module containing Pgadmin administration functions (Dave)


These functions provide additional file system access routines not present in the default PostgreSQL server.

Add sslinfo module (Victor Wagner)


Reports information about the current connection's SSL certificate.

Add pgrowlocks module (Tatsuo)


This shows row locking information for a specified table.

Add hstore module (Oleg, Teodor)

Add isn module, replacing isbn_issn (Jeremy Kronuz)


This new implementation supports EAN13, UPC, ISBN (books), ISMN (music), and ISSN (serials).

Add index information functions to pgstattuple (ITAGAKI Takahiro, Satoshi Nagayasu)

Add pg_freespacemap module to display free space map information (Mark Kirkwood)

pgcrypto now has all planned functionality (Marko Kreen)

Include iMath library in pgcrypto to have the public-key encryption functions always available.
1611

Notes de version

Add SHA224 algorithm that was missing in OpenBSD code.

Activate builtin code for SHA224/256/384/512 hashes on older OpenSSL to have those algorithms always available.

New function gen_random_bytes() that returns cryptographically strong randomness. Useful for generating encryption
keys.

Remove digest_exists(), hmac_exists() and cipher_exists() functions.

Improvements to cube module (Joshua Reich)


New functions are cube(float[]), cube(float[], float[]), and cube_subset(cube, int4[]).

Add async query capability to dblink (Kai Londenberg, Joe Conway)

New operators for array-subset comparisons (@>, <@, &&) (Tom)


Various contrib packages already had these operators for their datatypes, but the naming wasn't consistent. We have now added consistently named array-subset comparison operators to the core code and all the contrib packages that have such functionality. (The old names remain available, but are deprecated.)

Add uninstall scripts for all contrib packages that have install scripts (David, Josh Drake)

E.106. Release 8.1.23


Release Date
2010-12-16
This release contains a variety of fixes from 8.1.22. For information about new features in the 8.1 major release, see Section E.129, Release 8.1 .
This is expected to be the last PostgreSQL release in the 8.1.X series. Users are encouraged to update to a newer release branch
soon.

E.106.1. Migration to Version 8.1.23


A dump/restore is not required for those running 8.1.X. However, if you are upgrading from a version earlier than 8.1.18, see Section E.111, Release 8.1.18 .

E.106.2. Changes

Force the default wal_sync_method to be fdatasync on Linux (Tom Lane, Marti Raudsepp)
The default on Linux has actually been fdatasync for many years, but recent kernel changes caused PostgreSQL to
choose open_datasync instead. This choice did not result in any performance improvement, and caused outright failures
on certain filesystems, notably ext4 with the data=journal mount option.

Fix recovery from base backup when the starting checkpoint WAL record is not in the same WAL segment as its redo point
(Jeff Davis)

Add support for detecting register-stack overrun on IA64 (Tom Lane)


The IA64 architecture has two hardware stacks. Full prevention of stack-overrun failures requires checking both.

Add a check for stack overflow in copyObject() (Tom Lane)


Certain code paths could crash due to stack overflow given a sufficiently complex query.

Fix detection of page splits in temporary GiST indexes (Heikki Linnakangas)


It is possible to have a concurrent page split in a temporary index, if for example there is an open cursor scanning the index
when an insertion is done. GiST failed to detect this case and hence could deliver wrong results when execution of the cursor
continued.

Avoid memory leakage while ANALYZE'ing complex index expressions (Tom Lane)

Ensure an index that uses a whole-row Var still depends on its table (Tom Lane)
1612

Notes de version

An index declared like create index i on t (foo(t.*)) would not automatically get dropped when its table was
dropped.

Do not inline a SQL function with multiple OUT parameters (Tom Lane)
This avoids a possible crash due to loss of information about the expected result rowtype.

Fix constant-folding of COALESCE() expressions (Tom Lane)


The planner would sometimes attempt to evaluate sub-expressions that in fact could never be reached, possibly leading to
unexpected errors.

Add print functionality for InhRelation nodes (Tom Lane)


This avoids a failure when debug_print_parse is enabled and certain types of query are executed.

Fix incorrect calculation of distance from a point to a horizontal line segment (Tom Lane)
This bug affected several different geometric distance-measurement operators.

Fix PL/pgSQL's handling of simple expressions to not fail in recursion or error-recovery cases (Tom Lane)

Fix bug in contrib/cube's GiST picksplit algorithm (Alexander Korotkov)


This could result in considerable inefficiency, though not actually incorrect answers, in a GiST index on a cube column. If you
have such an index, consider REINDEXing it after installing this update.

Don't emit identifier will be truncated notices in contrib/dblink except when creating new connections (Itagaki Takahiro)

Fix potential coredump on missing public key in contrib/pgcrypto (Marti Raudsepp)

Fix memory leak in contrib/xml2's XPath query functions (Tom Lane)

Update time zone data files to tzdata release 2010o for DST law changes in Fiji and Samoa; also historical corrections for
Hong Kong.

E.107. Release 8.1.22


Release Date
2010-10-04
This release contains a variety of fixes from 8.1.21. For information about new features in the 8.1 major release, see Section E.129, Release 8.1 .
The PostgreSQL community will stop releasing updates for the 8.1.X release series in November 2010. Users are encouraged to
update to a newer release branch soon.

E.107.1. Migration to Version 8.1.22


A dump/restore is not required for those running 8.1.X. However, if you are upgrading from a version earlier than 8.1.18, see Section E.111, Release 8.1.18 .

E.107.2. Changes

Use a separate interpreter for each calling SQL userid in PL/Perl and PL/Tcl (Tom Lane)
This change prevents security problems that can be caused by subverting Perl or Tcl code that will be executed later in the
same session under another SQL user identity (for example, within a SECURITY DEFINER function). Most scripting languages offer numerous ways that that might be done, such as redefining standard functions or operators called by the target
function. Without this change, any SQL user with Perl or Tcl language usage rights can do essentially anything with the SQL
privileges of the target function's owner.
The cost of this change is that intentional communication among Perl and Tcl functions becomes more difficult. To provide an
escape hatch, PL/PerlU and PL/TclU functions continue to use only one interpreter per session. This is not considered a security issue since all such functions execute at the trust level of a database superuser already.
It is likely that third-party procedural languages that claim to offer trusted execution have similar security issues. We advise
1613

Notes de version

contacting the authors of any PL you are depending on for security-critical purposes.
Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433).

Prevent possible crashes in pg_get_expr() by disallowing it from being called with an argument that is not one of the system catalog columns it's intended to be used with (Heikki Linnakangas, Tom Lane)

Fix cannot handle unplanned sub-select error (Tom Lane)


This occurred when a sub-select contains a join alias reference that expands into an expression containing another sub-select.

Prevent show_session_authorization() from crashing within autovacuum processes (Tom Lane)

Defend against functions returning setof record where not all the returned rows are actually of the same rowtype (Tom Lane)

Fix possible failure when hashing a pass-by-reference function result (Tao Ma, Tom Lane)

Take care to fsync the contents of lockfiles (both postmaster.pid and the socket lockfile) while writing them (Tom Lane)
This omission could result in corrupted lockfile contents if the machine crashes shortly after postmaster start. That could in
turn prevent subsequent attempts to start the postmaster from succeeding, until the lockfile is manually removed.

Avoid recursion while assigning XIDs to heavily-nested subtransactions (Andres Freund, Robert Haas)
The original coding could result in a crash if there was limited stack space.

Fix log_line_prefix's %i escape, which could produce junk early in backend startup (Tom Lane)

Fix possible data corruption in ALTER TABLE ... SET TABLESPACE when archiving is enabled (Jeff Davis)

Allow CREATE DATABASE and ALTER DATABASE ... SET TABLESPACE to be interrupted by query-cancel
(Guillaume Lelarge)

In PL/Python, defend against null pointer results from PyCObject_AsVoidPtr and PyCObject_FromVoidPtr (Peter
Eisentraut)

Improve contrib/dblink's handling of tables containing dropped columns (Tom Lane)

Fix connection leak after duplicate connection name errors in contrib/dblink (Itagaki Takahiro)

Fix contrib/dblink to handle connection names longer than 62 bytes correctly (Itagaki Takahiro)

Update build infrastructure and documentation to reflect the source code repository's move from CVS to Git (Magnus Hagander and others)

Update time zone data files to tzdata release 2010l for DST law changes in Egypt and Palestine; also historical corrections for
Finland.
This change also adds new names for two Micronesian timezones: Pacific/Chuuk is now preferred over Pacific/Truk (and the
preferred abbreviation is CHUT not TRUT) and Pacific/Pohnpei is preferred over Pacific/Ponape.

E.108. Release 8.1.21


Release Date
2010-05-17
This release contains a variety of fixes from 8.1.20. For information about new features in the 8.1 major release, see Section E.129, Release 8.1 .

E.108.1. Migration to Version 8.1.21


A dump/restore is not required for those running 8.1.X. However, if you are upgrading from a version earlier than 8.1.18, see Section E.111, Release 8.1.18 .

E.108.2. Changes

Enforce restrictions in plperl using an opmask applied to the whole interpreter, instead of using Safe.pm (Tim Bunce,
Andrew Dunstan)
1614

Notes de version

Recent developments have convinced us that Safe.pm is too insecure to rely on for making plperl trustable. This change
removes use of Safe.pm altogether, in favor of using a separate interpreter with an opcode mask that is always applied. Pleasant side effects of the change include that it is now possible to use Perl's strict pragma in a natural way in plperl, and
that Perl's $a and $b variables work as expected in sort routines, and that function compilation is significantly faster.
(CVE-2010-1169)

Prevent PL/Tcl from executing untrustworthy code from pltcl_modules (Tom)


PL/Tcl's feature for autoloading Tcl code from a database table could be exploited for trojan-horse attacks, because there was
no restriction on who could create or insert into that table. This change disables the feature unless pltcl_modules is owned by a
superuser. (However, the permissions on the table are not checked, so installations that really need a less-than-secure modules
table can still grant suitable privileges to trusted non-superusers.) Also, prevent loading code into the unrestricted normal
Tcl interpreter unless we are really going to execute a pltclu function. (CVE-2010-1170)

Do not allow an unprivileged user to reset superuser-only parameter settings (Alvaro)


Previously, if an unprivileged user ran ALTER USER ... RESET ALL for himself, or ALTER DATABASE ... RESET
ALL for a database he owns, this would remove all special parameter settings for the user or database, even ones that are only
supposed to be changeable by a superuser. Now, the ALTER will only remove the parameters that the user has permission to
change.

Avoid possible crash during backend shutdown if shutdown occurs when a CONTEXT addition would be made to log entries
(Tom)
In some cases the context-printing function would fail because the current transaction had already been rolled back when it
came time to print a log message.

Update pl/perl's ppport.h for modern Perl versions (Andrew)

Fix assorted memory leaks in pl/python (Andreas Freund, Tom)

Prevent infinite recursion in psql when expanding a variable that refers to itself (Tom)

Ensure that contrib/pgstattuple functions respond to cancel interrupts promptly (Tatsuhito Kasahara)

Make server startup deal properly with the case that shmget() returns EINVAL for an existing shared memory segment
(Tom)
This behavior has been observed on BSD-derived kernels including OS X. It resulted in an entirely-misleading startup failure
complaining that the shared memory request size was too large.

Update time zone data files to tzdata release 2010j for DST law changes in Argentina, Australian Antarctic, Bangladesh,
Mexico, Morocco, Pakistan, Palestine, Russia, Syria, Tunisia; also historical corrections for Taiwan.

E.109. Release 8.1.20


Release Date
2010-03-15
This release contains a variety of fixes from 8.1.19. For information about new features in the 8.1 major release, see Section E.129, Release 8.1 .

E.109.1. Migration to Version 8.1.20


A dump/restore is not required for those running 8.1.X. However, if you are upgrading from a version earlier than 8.1.18, see Section E.111, Release 8.1.18 .

E.109.2. Changes

Add new configuration parameter ssl_renegotiation_limit to control how often we do session key renegotiation for
an SSL connection (Magnus)
This can be set to zero to disable renegotiation completely, which may be required if a broken SSL library is used. In particular, some vendors are shipping stopgap patches for CVE-2009-3555 that cause renegotiation attempts to fail.

Fix possible crashes when trying to recover from a failure in subtransaction start (Tom)
1615

Notes de version

Fix server memory leak associated with use of savepoints and a client encoding different from server's encoding (Tom)

Make substring() for bit types treat any negative length as meaning all the rest of the string (Tom)
The previous coding treated only -1 that way, and would produce an invalid result value for other negative values, possibly
leading to a crash (CVE-2010-0442).

Fix integer-to-bit-string conversions to handle the first fractional byte correctly when the output bit width is wider than the given integer by something other than a multiple of 8 bits (Tom)

Fix some cases of pathologically slow regular expression matching (Tom)

Fix the STOP WAL LOCATION entry in backup history files to report the next WAL segment's name when the end location
is exactly at a segment boundary (Itagaki Takahiro)

Fix some more cases of temporary-file leakage (Heikki)


This corrects a problem introduced in the previous minor release. One case that failed is when a plpgsql function returning set
is called within another function's exception handler.

When reading pg_hba.conf and related files, do not treat @something as a file inclusion request if the @ appears inside
quote marks; also, never treat @ by itself as a file inclusion request (Tom)
This prevents erratic behavior if a role or database name starts with @. If you need to include a file whose path name contains
spaces, you can still do so, but you must write @"/path to/file" rather than putting the quotes around the whole
construct.

Prevent infinite loop on some platforms if a directory is named as an inclusion target in pg_hba.conf and related files
(Tom)

Fix psql's numericlocale option to not format strings it shouldn't in latex and troff output formats (Heikki)

Fix plpgsql failure in one case where a composite column is set to NULL (Tom)

Add volatile markings in PL/Python to avoid possible compiler-specific misbehavior (Zdenek Kotala)

Ensure PL/Tcl initializes the Tcl interpreter fully (Tom)


The only known symptom of this oversight is that the Tcl clock command misbehaves if using Tcl 8.5 or later.

Prevent crash in contrib/dblink when too many key columns are specified to a dblink_build_sql_* function
(Rushabh Lathia, Joe Conway)

Fix assorted crashes in contrib/xml2 caused by sloppy memory management (Tom)

Update time zone data files to tzdata release 2010e for DST law changes in Bangladesh, Chile, Fiji, Mexico, Paraguay, Samoa.

E.110. Release 8.1.19


Release Date
2009-12-14
This release contains a variety of fixes from 8.1.18. For information about new features in the 8.1 major release, see Section E.129, Release 8.1 .

E.110.1. Migration to Version 8.1.19


A dump/restore is not required for those running 8.1.X. However, if you are upgrading from a version earlier than 8.1.18, see Section E.111, Release 8.1.18 .

E.110.2. Changes

Protect against indirect security threats caused by index functions changing session-local state (Gurjeet Singh, Tom)
This change prevents allegedly-immutable index functions from possibly subverting a superuser's session (CVE-2009-4136).

Reject SSL certificates containing an embedded null byte in the common name (CN) field (Magnus)
This prevents unintended matching of a certificate to a server or client name during SSL validation (CVE-2009-4034).
1616

Notes de version

Fix possible crash during backend-startup-time cache initialization (Tom)

Prevent signals from interrupting VACUUM at unsafe times (Alvaro)


This fix prevents a PANIC if a VACUUM FULL is canceled after it's already committed its tuple movements, as well as transient errors if a plain VACUUM is interrupted after having truncated the table.

Fix possible crash due to integer overflow in hash table size calculation (Tom)
This could occur with extremely large planner estimates for the size of a hashjoin's result.

Fix very rare crash

You might also like