CREATE OPERATOR

Name

CREATE OPERATOR  --  définit un nouvel opérateur

Synopsis

CREATE OPERATOR name ( PROCEDURE = func_name
     [, LEFTARG = lefttype
     ] [, RIGHTARG = righttype ]
     [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
     [, RESTRICT = res_proc ] [, JOIN = join_proc ]
     [, HASHES ] [, SORT1 = left_sort_op ] [, SORT2 = right_sort_op ] )
  

Entrées

name

l'opérateur à définir. Voir plus bas pour les caractères admis.

func_name

la fonction utilisée pour implémenter cet opérateur.

lefttype

le type côté gauche de l'opérateur. Cette option sera omise pour un opérateur unaire gauche.

righttype

Le type côté droit de l'opérateur. Cette option sera omise pour un opérateur unaire droit.

com_op

Le commutateur de cet opérateur

neg_op

Le négateur de cet opérateur.

res_proc

La fonction d'estimateur de sélectivité de restriction pour cet opérateur.

join_proc

La fonction d'estimateur de sélectivité de jonction pour cet opérateur.

HASHES

Indique si l'opérateur peut supporter un algorithme de jointure-hachage.

left_sort_op

Si cet opérateur peut supporter une fusion de jointure, l'opérateur qui trie le type gauche de cet opérateur.

right_sort_op

Si cet opérateur peut supporter une fusion de jointure, l'opérateur qui trie le type droit de cet opérateur.

Sorties

CREATE

message retourné si l'opérateur a été créé correctement.

Description

CREATE OPERATOR définit un nouvel opérateur name. L'utilisateur qui crée l'opérateur en devient le propriétaire.

The operator name est une séquence supérieure à NAMEDATALEN-1 (31 par défaut) caractères de la liste suivante :

+ - * / < > = ~ ! @ # % ^ & | ` ? $
   

Il y a quelques restrictions sur le choix du nom :

Note

Quand vous travaillez avec des noms d'opérateur non-standards SQL, vous avez besoin habituellement de séparer les opérateurs adjacents avec des espaces pour éviter toute ambiguïté. Par exemple, si vous avez défini un opérateur unaire-gauche nommé @, vous ne pourrez écrire X*@Y; vous devez simplement écrire X* @Y pour vous assurer que PostgreSQL les lit comme deux noms d'opérateurs pas un.

L'opérateur != est mappé vers <> en entrée, ainsi il sont donc équivalents.

Enfin un LEFTARG et RIGHTARG doit être défini. Pour les opérateurs binaires, les deux doivent être définis. Pour les opérateurs unaire droit, seulement LEFTARG sera défini, tandis que pour les opérateurs unaire gauche, seulement RIGHTARG sera défini.

Également, la procédure func_name doit avoir été préalablement définie en utilisant CREATE FUNCTION et doit être définie pour accepter le nombre d'arguments correct (un ou deux).

L'opérateur commutateur est présent de façon que Postgres puisse renverser l'ordre des opérandes s'il le désire. Par exemple, l'opérateur area-less-than <<<, aura un opérateur commutateur, area-greater-than, >>>. L'optimiseur de requête pourra librement convertir :

box '((0,0), (1,1))'  >>> MYBOXES.description
   
en
MYBOXES.description <<< box '((0,0), (1,1))'
   

Ceci permet au code d'exécution de toujours utiliser la dernière représentation et simplifie l'optimiseur de requête.

De façon similaire, si il existe un opérateur négation, alors il sera identifié. Supposons qu'un opérateur, area-equal, ===, existe, aussi bien que un area not equal, !==. Le lien négation permet à l'optimiseur de requête de simplifier

NOT MYBOXES.description === box '((0,0), (1,1))'
   
en
MYBOXES.description !== box '((0,0), (1,1))'
   

Si un nom d'opérateur commutateur est fournit, Postgres le recherche dans le catalogue. Si il est trouvé et qu'il ne peut cependant pas avoir le commutateur lui-même, alors l'entrée commutateur est mise à jour pour avoir l'opérateur courant (nouveau) comme commutateur. Ceci s'applique au négateur aussi bien. Ceci pour permettre la définition de deux opérateurs que sont les commutateurs ou les négateurs de chaque autre. Le premier opérateur sera défini sans commutateur ou négateur. Quand le second opérateur est défini, nomme le premier comme commutateur ou négateur. Le premier sera mis à jour comme un effet secondaire.

Les options HASHES, SORT1, et SORT2 sont présentes pour aider l'optimiseur de requête a exécuter les jointures. PostgreSQL peut toujours évaluer une jointure (i.e., en évaluant une clause avec deux variables de tuples séparées par un opérateur qui renvoie un booléen) par substitution itérative [WONG76]. De plus Postgres peut utiliser un algorithme de jointure-hachage dans les lignes de [SHAP86]; cependant, il doit connaître comment appliquer cette stratégie. L'algorithme de jointure-hachage est correct seulement pour les opérateurs qui représentent des tests d'égalité; De plus, l'égalité du type doit signifier, au niveau du bit, l'égalité de la représentation du type. (Par exemple, un type qui contient des bits non utilisés qui ne servent pas dans les tests d'égalité ne pourrait pas subir de jointure). Le flag HASHES indique à l'optimiseur de requête qu'une jointure de hachage peut de façon sûre être utilisée avec cet opérateur.

De façon similaire, les deux opérateurs de tri indiquent à l'optimiseur de requête comment la fusion-tri utilise la stratégie de jointure et quels opérateurs seront utilisés pour trier les deux classes opérandes. Les opérateurs de tri devront être fournis seulement pour un opérateur d'égalité, et ils se référeront aux opérateurs inférieurs-à pour les données types droite et gauche respectivement.

Si d'autres stratégies de jointures sont ajoutées, Postgres changera l'optimiseur et le système de délai d'exécution pour les utiliser et demandera des spécifications supplémentaires quand un opérateur est défini. Heureusement, la communauté des chercheurs n'invente pas fréquemment de nouvelles stratégies de jointure.

Les options RESTRICT et JOIN aident l'optimiseur de requête dans l'estimation des tailles de résultats? Si une clause de la forme :

MYBOXES.description <<< box '((0,0), (1,1))'
   
est présente dans la qualification, PostgreSQL devra estimer la partie des instances dans MYBOXES qui satisfont la clause. La fonction res_proc doit être une fonction enregistrée (montrant qu'elle est déja définie en utilisant CREATE FUNCTION) qui accepte les arguments de types corrects et renvoit un nombre décimal. L'optimiseur de requête appelle simplement cette fonction, en passant le paramètre ((0,0), (1,1)) et multiplie le résultat par la taille de la relation pour obtenir le nombre d'instances attendues.

De façon similaire, quand les opérandes de l'opérateur contiennent les deux variables instance, l'optimiseur de requête doit estimer la taille de la jointure résultante. La fonction join-proc retournera un autre nombre décimal qui sera multiplié par les cardinalités des deux classes imbriquées pour calculer la taille des résultats attendus..

La différence entre la fonction

my_procedure_1 (MYBOXES.description, box '((0,0), (1,1))')
   
et l'opérateur
MYBOXES.description === box '((0,0), (1,1))'
   
est que Postgres essaye d'optimiser les opérateurs et peut décider d'utiliser un index pour réduire l'espace de recherche quand les opérateurs sont compliqués. Cependant, il n'y a pas de tentative d'optimiser les fonctions, elles sont exécutées de façon brutale. De plus, les fonctions peuvent avoir plusieurs arguments tandis que les opérateurs sont limités à un ou deux.

Notes

Voir le chapitre sur les opérateurs dans le Guide de l'utilisateur PostgreSQL pour plus d'information. Voir DROP OPERATOR pour supprimer les opérateurs définis par l'utilisateur d'une base.

Utilisation

La commande suivante définit un nouvel opérateur, area-equality, pour le type BOX.

CREATE OPERATOR === (
   LEFTARG = box,
   RIGHTARG = box,
   PROCEDURE = area_equal_procedure,
   COMMUTATOR = ===,
   NEGATOR = !==,
   RESTRICT = area_restriction_procedure,
   JOIN = area_join_procedure,
   HASHES,
   SORT1 = <<<,
   SORT2 = <<<
);
  

Compatibilité

SQL92

CREATE OPERATOR est une extension de PostgreSQL. Il n'y a pas de CREATE OPERATOR dans le SQL92.