UDFs SQL scalaires¶
Ce chapitre couvre des concepts et des dĂ©tails dâutilisation spĂ©cifiques aux UDFs SQL (fonctions dĂ©finies par lâutilisateur).
Dans ce chapitre :
Utilisation générale¶
Un UDF SQL Ă©value une expression arbitraire SQL et retourne les rĂ©sultats de lâexpression.
La dĂ©finition de la fonction peut ĂȘtre une expression SQL qui retourne soit une valeur scalaire (câest-Ă -dire unique), soit, si elle est dĂ©finie comme fonction de table, un ensemble de lignes. Par exemple, voici un exemple de base dâun UDF scalaire qui calcule lâaire dâun cercle :
CREATE FUNCTION area_of_circle(radius FLOAT)
RETURNS FLOAT
AS
$$
pi() * radius * radius
$$
;
SELECT area_of_circle(1.0);
Sortie :
SELECT area_of_circle(1.0);
+---------------------+
| AREA_OF_CIRCLE(1.0) |
|---------------------|
| 3.141592654 |
+---------------------+
Lâexpression peut ĂȘtre une expression de requĂȘte (une expression SELECT). Par exemple :
CREATE FUNCTION profit()
RETURNS NUMERIC(11, 2)
AS
$$
SELECT SUM((retail_price - wholesale_price) * number_sold)
FROM purchases
$$
;
Lorsque vous utilisez une expression de requĂȘte dans un UDF SQL, vous nâavez pas besoin dâinclure un point-virgule dans le corps de lâUDF pour terminer lâexpression de la requĂȘte.
Vous ne pouvez inclure quâune seule expression de requĂȘte. Lâexpression peut inclure UNION [ALL].
Note
Bien que le corps dâun UDF puisse contenir une instruction SELECT complĂšte, il ne peut pas contenir dâinstructions DDL ni toute instruction DML autre que SELECT.
Note
Les fonctions scalaires (UDFs) ont une limite de 500 arguments dâentrĂ©e.
UDFs mémoïsables¶
Une UDF SQL scalaire peut ĂȘtre mĂ©moĂŻsable. Une fonction mĂ©moĂŻsable met en cache le rĂ©sultat de lâappel dâune UDF SQL scalaire et renvoie ensuite le rĂ©sultat en cache lorsque la sortie est nĂ©cessaire ultĂ©rieurement. Lâavantage de lâutilisation dâune fonction mĂ©moĂŻsable est dâamĂ©liorer les performances pour les requĂȘtes complexes, telles que les recherches de colonnes multiples dans les tables de mappage rĂ©fĂ©rencĂ©es dans une politique dâaccĂšs aux lignes ou une politique de masquage.
Les propriĂ©taires de la politique (par exemple, le rĂŽle ayant le privilĂšge OWNERSHIP sur la politique dâaccĂšs aux lignes) peuvent mettre Ă jour leurs conditions de politique pour remplacer les sous-requĂȘtes qui ont des tables de mappage par une fonction mĂ©moĂŻsable. Lorsque les utilisateurs font rĂ©fĂ©rence Ă la colonne protĂ©gĂ©e par la politique dans une requĂȘte ultĂ©rieure, les rĂ©sultats mis en cache par la fonction mĂ©moĂŻsable sont disponibles pour ĂȘtre utilisĂ©s selon les besoins.
Créer une fonction mémoïsable¶
Vous pouvez dĂ©finir une UDF SQL scalaire Ă mĂ©moĂŻser dans lâinstruction CREATE FUNCTION en spĂ©cifiant le mot-clĂ© MEMOIZABLE
. Vous pouvez crĂ©er un mĂ©moisable pour fonctionner avec ou sans arguments. En utilisant des arguments, vous avez plus de libertĂ© pour dĂ©finir lâUDF SQL. Lorsque vous Ă©crivez une politique pour appeler la fonction mĂ©moisable, vous disposez dâune plus grande libertĂ© dans la dĂ©finition de la politique.
Si vous spĂ©cifiez des arguments, ceux-ci doivent ĂȘtre des valeurs constantes avec lâun des types de donnĂ©es suivants :
VARCHAR et dâautres types de donnĂ©es de type chaĂźne.
NUMBER et dâautres types de donnĂ©es numĂ©riques.
TIMESTAMP et dâautres types de donnĂ©es de date.
BOOLEAN.
Les valeurs non constantes et leurs types de données, tels que les types de données semi-structurées et les colonnes de tables ne sont pas pris en charge.
Lorsque vous écrivez une fonction mémoïsable :
SpĂ©cifiez BOOLEAN ou dâautres types de donnĂ©es scalaires comme
result_data_type
.Soyez prudent lorsque vous spécifiez ARRAY comme
result_data_type
car la taille du cache est limitĂ©e.Ne spĂ©cifiez pas dâautres types de donnĂ©es tels que OBJECT et VARIANT.
Ne faites pas référence à une autre fonction mémoïsable de quelque maniÚre que ce soit.
Appeler une fonction mémoïsable¶
Une fonction mĂ©moisable peut ĂȘtre appelĂ©e dans une instruction SELECT ou ĂȘtre incluse dans une dĂ©finition de politique, qui appelle ensuite la fonction mĂ©moisable en fonction des conditions de la politique.
Lorsque vous appelez une fonction mémoïsable, notez :
Pour les UDFs SQL qui renvoient le type de données ARRAY ou spécifient une valeur non scalaire, utilisez la fonction mémoïsable comme argument dans la fonction ARRAY_CONTAINS.
Limite de la taille du cache :
Chaque fonction mémoïsable a une limite 10 KB pour la session Snowflake en cours.
Si la fonction mĂ©moĂŻsable dĂ©passe cette limite pour le cache du jeu de rĂ©sultats, Snowflake ne met pas en cache le rĂ©sultat de lâappel de la fonction mĂ©moĂŻsable. Au lieu de cela, lâUDF agit comme une UDF scalaire normale selon la façon dont la fonction est Ă©crite.
Utilisation du cache :
Les fonctions mĂ©moĂŻsables disposent dâun cache de rĂ©sultats rĂ©utilisable pour diffĂ©rentes instructions SQL lorsque lâenvironnement et le contexte de la requĂȘte ne changent pas. En gĂ©nĂ©ral, cela signifie que le cache de rĂ©sultat sâapplique Ă diffĂ©rentes instructions SQL Ă condition que :
Lâautorisation de contrĂŽle dâaccĂšs sur les objets et les colonnes rĂ©fĂ©rencĂ©s dans une requĂȘte reste la mĂȘme.
Les objets rĂ©fĂ©rencĂ©s dans la requĂȘte ne sont pas modifiĂ©s (par exemple, par des instructions DML).
La colonne CHILD_QUERIES_WAIT_TIME de la vue Account Usage QUERY_HISTORY enregistre le temps (en millisecondes) nĂ©cessaire pour effectuer la recherche en cache lors de lâappel dâune fonction mĂ©moĂŻsable.
Les fonctions mémoïsables ne réutilisent pas les résultats mis en cache lorsque :
La fonction référence une table ou un autre objet et il y a une mise à jour de la table référencée.
Il y a un changement dans le contrĂŽle dâaccĂšs Ă la table.
La fonction appelle une fonction non déterministe.
La fonction appelle une fonction externe ou une UDF qui nâest pas une UDF SQL.
Exemples¶
Exemple(s) dâUDF scalaires SQL de base¶
Cet exemple renvoie une approximation codée en dur de la constante mathématique pi.
CREATE FUNCTION pi_udf()
RETURNS FLOAT
AS '3.141592654::FLOAT'
;
SELECT pi_udf();
Sortie :
SELECT pi_udf();
+-------------+
| PI_UDF() |
|-------------|
| 3.141592654 |
+-------------+
Exemples SQL courants¶
Expression de requĂȘte avec lâinstruction SELECT¶
Créez la table et les données à utiliser :
CREATE TABLE purchases (number_sold INTEGER, wholesale_price NUMBER(7,2), retail_price NUMBER(7,2));
INSERT INTO purchases (number_sold, wholesale_price, retail_price) VALUES
(3, 10.00, 20.00),
(5, 100.00, 200.00)
;
CrĂ©ez lâUDF :
CREATE FUNCTION profit()
RETURNS NUMERIC(11, 2)
AS
$$
SELECT SUM((retail_price - wholesale_price) * number_sold)
FROM purchases
$$
;
Appelez lâUDF dans une requĂȘte :
SELECT profit();
Sortie :
SELECT profit();
+----------+
| PROFIT() |
|----------|
| 530.00 |
+----------+
UDF dans une clause WITH¶
CREATE TABLE circles (diameter FLOAT);
INSERT INTO circles (diameter) VALUES
(2.0),
(4.0);
CREATE FUNCTION diameter_to_radius(f FLOAT)
RETURNS FLOAT
AS
$$ f / 2 $$
;
WITH
radii AS (SELECT diameter_to_radius(diameter) AS radius FROM circles)
SELECT radius FROM radii
ORDER BY radius
;
Sortie :
+--------+
| RADIUS |
|--------|
| 1 |
| 2 |
+--------+
Fonctionnement JOIN¶
Cet exemple utilise une requĂȘte plus complexe, qui inclut une opĂ©ration JOIN :
Créez la table et les données à utiliser :
CREATE TABLE orders (product_ID varchar, quantity integer, price numeric(11, 2), buyer_info varchar);
CREATE TABLE inventory (product_ID varchar, quantity integer, price numeric(11, 2), vendor_info varchar);
INSERT INTO inventory (product_ID, quantity, price, vendor_info) VALUES
('X24 Bicycle', 4, 1000.00, 'HelloVelo'),
('GreenStar Helmet', 8, 50.00, 'MellowVelo'),
('SoundFX', 5, 20.00, 'Annoying FX Corporation');
INSERT INTO orders (product_id, quantity, price, buyer_info) VALUES
('X24 Bicycle', 1, 1500.00, 'Jennifer Juniper'),
('GreenStar Helmet', 1, 75.00, 'Donovan Liege'),
('GreenStar Helmet', 1, 75.00, 'Montgomery Python');
CrĂ©ez lâUDF :
CREATE FUNCTION store_profit()
RETURNS NUMERIC(11, 2)
AS
$$
SELECT SUM( (o.price - i.price) * o.quantity)
FROM orders AS o, inventory AS i
WHERE o.product_id = i.product_id
$$
;
Appelez lâUDF dans une requĂȘte :
SELECT store_profit();
Sortie :
SELECT store_profit();
+----------------+
| STORE_PROFIT() |
|----------------|
| 550.00 |
+----------------+
La rubrique CREATE FUNCTION contient des exemples supplémentaires.
Utilisation dâUDFs dans diffĂ©rentes clauses¶
Un UDF scalaire peut ĂȘtre utilisĂ© partout oĂč une expression scalaire peut ĂȘtre utilisĂ©e. Par exemple :
-- ----- These examples show a UDF called from different clauses ----- --
select MyFunc(column1) from table1;
select * from table1 where column2 > MyFunc(column1);
Utilisation des variables SQL dans une UDF¶
Cet exemple montre comment définir une variable SQL et utiliser cette variable dans un UDF :
SET id_threshold = (SELECT COUNT(*)/2 FROM table1);
CREATE OR REPLACE FUNCTION my_filter_function()
RETURNS TABLE (id int)
AS
$$
SELECT id FROM table1 WHERE id > $id_threshold
$$
;
Fonctions mémoïsables¶
Pour des exemples, voir :
Fonction mĂ©moisable sans arguments dans une politique dâaccĂšs aux lignes.
Fonction mémoisable avec des arguments dans une politique de masquage.