PostgreSQL - Opérateur CAST vs :: sur la fonction de table LATÉRALE

Nov 27 2020

Tant que je peux

SELECT elem[1], elem[2]
FROM   ( VALUES ('1,2'::TEXT) ) AS q(arr),
       LATERAL CAST(String_To_Array(q.arr, ',') AS INT[]) AS elem
;

en utilisant un appel explicite à CAST, je ne peux pas

SELECT elem[1], elem[2]
FROM   ( VALUES ('1,2'::TEXT) ) AS q(arr),
       LATERAL String_To_Array(q.arr, ',')::INT[] AS elem
;

en utilisant l' ::opérateur appelant implicitement :

ERREUR: erreur de syntaxe à ou près de "::"

Un autre emplacement auquel un explicite CASTest requis:

CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );

Je doute qu'il y ait une raison syntaxique, par exemple en utilisant des parenthèses supplémentaires - qui est incorrecte ici.

L'appel de fonction explicite est-il simplement nécessaire à ce stade dans le cadre de l'implémentation de bas niveau? Ou suit-il des règles linguistiques?

Réponses

5 ErwinBrandstetter Nov 27 2020 at 11:35

Excellents exemples de cas d'angle. Ces deux variantes de syntaxe sont des "castes de types explicites", faisant exactement la même chose. Il se trouve que certains emplacements spéciaux dans le code SQL n'autorisent que la notation fonctionnelle pour éviter les ambiguïtés.

Quant à votre deuxième observation:

Un autre emplacement auquel un explicite CASTest requis:

CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );

La syntaxe abrégée peut en fait être utilisée ici - avec un jeu supplémentaire de parenthèses pour la rendre non ambiguë:

CREATE INDEX ON ... ((<straw>::<gold>));

db <> violon ici

Et chaque variante de syntaxe correspond également à l'autre expression dans les requêtes. Voir:

  • Pouvons-nous créer un index pour la clé / valeur du type de données JSONB?
  • Comment créer un index sur une propriété json entière dans postgres
  • Fractionnement de la date / heure en 2 colonnes pour le schéma de réservation de restaurant?

(Il existe des moyens plus efficaces de faire ce que fait votre premier exemple, mais c'est probablement hors de propos.)

5 LaurenzAlbe Nov 27 2020 at 10:27

C'est un peu bizarre, oui, mais la grammaire n'acceptera que quelque chose de similaire syntaxiquement à un appel de fonction dans une expression function-in-FROM.

C'est donc une astuce que vous pouvez utiliser si vous voulez une expression arbitraire dans une FROMclause: entourez-la d'une CASTexpression inutile .

PostgreSQL traitera volontiers tout ce qui ressemble à une fonction comme une fonction de table dans un tel contexte.