Le planificateur classifie les opérations impliquées dans une requête
   comme étant à parallélisation sûre,
   parallélisation restreinte, ou
   parallélisation non sûre. Une opération
   à parallélisation sûre
   est une opération n'entrant pas en conflit avec une
   requête parallélisée. Une opération à parallélisation restreinte
   ne peut pas être exécutée par un
   worker parallélisé, mais peut l'être
   par le leader pendant
   l'exécution. De ce fait, les opérations à parallélisation
   restreinte ne peuvent jamais survenir sous un nœud
   Gather ou Gather Merge. Une
   opération à parallélisation non sûre ne peut être exécutée dans une
   requête parallélisée, y compris au niveau du
   leader. Quand une requête contient quoi que
   ce soit de non sûr à paralléliser, la parallélisation y est
   complètement désactivée.
  
Les opérations suivantes sont toujours à parallélisation restreinte.
Parcours de CTE (Common Table Expressions).
Parcours de tables temporaires.
     Parcours de tables externes, sauf si le wrapper de données distantes a
     une API IsForeignScanParallelSafe qui indique le
     contraire.
    
     Nœuds du plan pour lesquels un InitPlan est
     attaché.
    
     Nœuds du plan qui référencent un SubPlan corrélé.
    
    Le planificateur ne peut pas déterminer automatiquement si une fonction ou
    un agrégat définis par un utilisateur est à parallélisation sûre,
    restreinte ou non sûre, car cela nécessiterait de pouvoir prédire
    chaque opération réalisable par la fonction. En général, c'est équivalent au
    problème de l'arrêt et de ce fait, impossible.
    Même pour des fonctions simples où cela pourrait se faire, nous n'essayons
    pas, car ce serait coûteux et sujet à erreurs. À la place, toutes les
    fonctions définies par des utilisateurs sont supposées à parallélisation non sûre
    sauf indication contraire. Lors de l'utilisation des
    instructions CREATE FUNCTION et ALTER FUNCTION, un marquage est possible en spécifiant
    PARALLEL SAFE, PARALLEL RESTRICTED
    ou PARALLEL UNSAFE suivant ce qui est approprié. Lors
    de l'utilisation de CREATE AGGREGATE, l'option
    PARALLEL peut être spécifiée comme
    SAFE, RESTRICTED ou
    UNSAFE.
   
    Les fonctions et agrégats doivent être marqués PARALLEL
     UNSAFE s'ils écrivent dans la base, accèdent à des séquences,
    modifient l'état de la transaction même temporairement (par exemple, une
    fonction PL/pgSQL qui définit un bloc EXCEPTION pour
    récupérer des erreurs), ou font des modifications persistantes sur les
    paramètres. De façon similaire, les fonctions doivent être marquées
    PARALLEL RESTRICTED si elles accèdent à des tables
    temporaires, à l'état de connexion du client, à des curseurs, à des
    requêtes préparées ou à un quelconque état local du processus serveur que le système
    ne peut pas synchroniser entre les différents
    workers. Par exemple,
    setseed et random sont à
    parallélisation restreinte pour cette dernière raison.
   
    En général, si une fonction est marquée comme étant sûre alors qu'elle ne
    l'est pas, ou si elle est marquée restreinte alors que sa
    parallélisation en fait n'est pas sûre, elle
    peut être cause d'erreurs ou de réponses fausses lors de
    l'utilisation dans une requête parallélisée. Les fonctions en langage C
    peuvent en théorie avoir des comportements indéfinis en cas de mauvais
    marquage, car le système n'a aucun moyen de se défendre contre du code C
    arbitraire. Cela étant dit, dans la plupart des cas, le résultat ne sera pas
    pire qu'avec toute autre fonction. En cas de doute, le mieux est probablement
    de marquer les fonctions en tant que UNSAFE.
   
    Si une fonction exécutée avec un worker
    parallèle acquiert des verrous non détenus par le
    leader, par exemple en exécutant une
    requête sur une table non référencée dans la requête, ces verrous seront
    relâchés à la sortie du worker, et non pas
    à la fin de la transaction. Si vous écrivez une fonction qui fait cela et
    que cette différence de comportement a une importance pour vous, marquez ces
    fonctions comme PARALLEL RESTRICTED pour vous assurer
    qu'elles ne s'exécutent qu'au sein du
    leader.
   
    Notez que le planificateur de requêtes ne cherche pas à différer
    l'évaluation des fonctions ou agrégats à parallélisation restreinte
    impliqués dans la requête pour obtenir un meilleur plan. Donc, par
    exemple, si une clause WHERE appliquée à une table
    particulière est à parallélisation restreinte, le planificateur ne
    tentera pas de placer le parcours de cette table dans une portion
    parallélisée du plan. Dans certains cas, il serait possible
    (voire efficace) d'inclure le parcours de cette table dans la
    partie parallélisée de la requête et de différer l'évaluation de la
    clause WHERE afin qu'elle se déroule au-dessus du
    nœud Gather. Néanmoins, le planificateur ne le
    fait pas.