10.3. Fonctions

La fonction spécifique à utiliser dans une invocation de fonctions est déterminée selon les étapes suivantes.

Résolution de types pour les fonctions

  1. Sélectionner les fonctions à examiner depuis le catalogue système pg_proc. Si un nom non-qualifié de fonction était utilisé, les fonctions examinées sont celles avec un nom et un nombre d'arguments corrects et qui sont visibles dans le chemin de recherche courant (regardez la Section 5.8.3). Si un nom qualifié de fonctions a été donné, seules les fonctions dans le schéma spécifique sont examinées.

    1. Si un chemin de recherche trouve de nombreuses fonctions avec des types d'arguments identiques, seule celle apparaissant le plus tôt dans le chemin sera examinée. Mais les fonctions avec des types d'arguments différents sont examinées sur une base d'égalité indépendamment de leur position dans le chemin de recherche.

  2. Vérifier que la fonction accepte le type exact des arguments en entrée. Si une fonction existe (il peut en avoir uniquement une qui corresponde exactement dans l'ensemble des fonctions considérées), utiliser cette fonction. (Les cas impliquant le type inconnu ne trouveront jamais de correspondance à cette étape.)

  3. Si aucune correspondance n'est trouvée, regarder si l'appel à la fonction apparaît être une requête triviale de conversion de types. Cela arrive si l'appel à la fonction a juste un argument et si le nom de la fonction est le même que le nom (interne) de certains types de données. 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 données nommés. Quand ces conditions sont réunies, l'argument de la fonction est converti vers le type de données nommé sans aucun appel effectif à la fonction.

  4. Regarder pour la meilleure correspondance.

    1. Se débarrasser des fonctions candidates pour lesquelles les types en entrée ne correspondent pas et qui ne peuvent pas être convertis (en utilisant une conversion implicite) pour correspondre. Le type inconnu est supposé être convertible vers n'importe quoi. Si seulement un candidat reste, utiliser le, sinon aller à la prochaine étape.

    2. Parcourir tous les candidats et garder ceux avec la correspondance la plus exacte par rapport aux types en entrée. (Les domaines sont considérés de la même façon que leur type de base pour cette étape.) Garder tous les candidats si aucun n'a de correspondances exactes. Si seulement un candidat reste, utiliser le ; sinon aller à la prochaine étape.

    3. Parcourir tous les candidats et garder ceux qui acceptent les types préférés (de la catégorie des types de données en entrée) aux positions où la conversion de types aurait été requise. Garder tous les candidats si aucun n'accepte les types préférés. Si seulement un candidat reste, utiliser le ; sinon aller à la prochaine étape.

    4. Si des arguments en entrée sont inconnu, vérifier les catégories de types acceptées à la position de ces arguments par les candidats restants. À chaque position, sélectionner la catégorie chaîne de caractères si un des candidats accepte cette catégorie. (Cette préférence envers les chaînes de caractères est appropriée depuis que le terme type-inconnu ressemble à une chaîne de caractères.) Dans le cas contraire, si tous les candidats restants acceptent la même catégorie de types, sélectionner cette catégorie. Dans le cas contraire échouer car le choix correct ne peut pas être déduit sans plus d'indices. Se débarrasser maintenant des candidats qui n'acceptent pas la catégorie sélectionnée. De plus, si des candidats acceptent un type préféré comme argument donné, se débarrasser des candidats qui acceptent, pour cet argument, les types qui ne sont pas préférés.

    5. Si seulement un candidat reste, utiliser le. Si aucun candidat ou si plus d'un candidat reste, alors échouer.

Notez que les règles de << correspondance optimale >> sont identiques pour la résolution de types concernant les opérateurs et les fonctions. Quelques exemples suivent.

Exemple 10-4. Résolution de types pour les arguments de la fonction arrondie

Il n'existe qu'une seule fonction round avec deux arguments. (Le premier est un numérique, le second est un entier. Ainsi, la requête suivante convertie automatiquement le type du premier argument de entier vers numérique.

SELECT round(4, 4);

 round
--------
 4.0000
(1 row)

La requête est en fait transformée par l'analyseur en

SELECT round(CAST (4 AS numeric), 4);

Puisque le type numérique est initialement assigné aux constantes numériques avec un point décimal, la requête suivante ne requièrera pas une conversion de types et pourra par conséquent être un peu plus efficace :

SELECT round(4.0, 4);

Exemple 10-5. Résolution de types pour les fonctions retournant un segment de chaîne

Il existe plusieurs fonctions substr, une d'entre elles prend les types texte et entier. Si cette fonction est appelée avec une constante de chaînes d'un type inconnu, le système choisi la fonction candidate qui accepte un argument issu de la catégorie préférée chaînes (c'est-à-dire de type texte).

SELECT substr('1234', 3);

 substr
--------
     34
(1 row)

Si la chaîne de caractères est déclarée comme étant du type varchar (chaîne de caractères de longueur variable), ce qui peut être le cas si elle vient d'une table, alors l'analyseur essayera de la convertir en texte :

SELECT substr(varchar '1234', 3);

 substr
--------
     34
(1 row)

Ceci est transformé par l'analyseur pour efficacement devenir

SELECT substr(CAST (varchar '1234' AS text), 3);

Note : L'analyseur apprend depuis le catalogue pg_cast que les types texte 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 conséquent, aucun appel de conversion explicite de types n'est réellement inséré dans ce cas.

Et si la fonction est appelée avec un argument de type entier, l'analyseur essayera de le convertir en texte :

SELECT substr(1234, 3);

 substr
--------
     34
(1 row)

Ceci est en fait exécuté de la façon suivante :

SELECT substr(CAST (1234 AS text), 3);

Cette transformation automatique peut réussir parce qu'il y a une invocation de conversion implicite du type entier vers le type texte.