CREATE FUNCTION (SQL a Python)
Platí pro: Databricks SQL Databricks Runtime
Vytvoří skalární nebo table funkci SQL, která přebírá set argumentů a vrací skalární hodnotu nebo set řádků.
Platí pro: Databricks SQL Databricks Runtime 13.3 LTS a vyšší
Vytvoří skalární funkci Pythonu, která přebírá set argumentů a vrací skalární hodnotu.
Funkce definované uživatelem v Pythonu vyžadují unity Catalog na bezserverových nebo pro SQL Warehouse nebo na clusteru Unity s jedním uživatelem Catalog.
Platí pro: Databricks SQL Databricks Runtime 14.1 a vyšší
Kromě vyvolání pozičních parametrů můžete také vyvolat UDF a SQL a Python pomocí pojmenovaného vyvolání parametru.
Syntaxe
CREATE [OR REPLACE] [TEMPORARY] FUNCTION [IF NOT EXISTS]
function_name ( [ function_parameter [, ...] ] )
{ [ RETURNS data_type ] |
RETURNS TABLE [ ( column_spec [, ...]) ] }
[ characteristic [...] ]
{ AS dollar_quoted_string | RETURN { expression | query } }
function_parameter
parameter_name data_type [DEFAULT default_expression] [COMMENT parameter_comment]
column_spec
column_name data_type [COMMENT column_comment]
characteristic
{ LANGUAGE { SQL | PYTHON } |
[NOT] DETERMINISTIC |
COMMENT function_comment |
[CONTAINS SQL | READS SQL DATA] }
Parameters
NEBO NAHRADIT
Pokud je zadáno, nahradí se funkce se stejným názvem a podpisem (počet parameters a typů parametrů). Existující funkci nelze nahradit jiným podpisem. To je užitečné hlavně pro update tělo funkce a návratový typ funkce. Tento parametr nelze zadat pomocí parametru
IF NOT EXISTS
.DOČASNÝ
Rozsah vytvářené funkce. Při zadání
TEMPORARY
je vytvořená funkce platná a viditelná v aktuální relaci. V catalogse nevytváří žádná trvalá položka.POKUD NEEXISTUJE
Pokud je zadáno, vytvoří funkci pouze v případě, že neexistuje. Vytvoření funkce proběhne úspěšně (není vyvolán žádná chyba), pokud zadaná funkce již v systému existuje. Tento parametr nelze zadat pomocí parametru
OR REPLACE
.-
Název funkce. U trvalé funkce můžete volitelně qualify název funkce nahradit názvem schema. Pokud název není kvalifikovaný, vytvoří se trvalá funkce v aktuálním schema.
function_parameter
Určuje parametr funkce.
-
Název parametru musí být v rámci funkce jedinečný.
-
Libovolný podporovaný datový typ. V případě Pythonu
data_type
se přetypuje na datový typ Pythonu podle tohoto mapování jazyka. VÝCHOZÍ default_expression
Platí pro: Databricks SQL Databricks Runtime 10.4 LTS a vyšší
Volitelné výchozí nastavení, které se má použít, když vyvolání funkce nepřiřazuje argument parametru.
default_expression
musí být přetypovat nadata_type
. Výraz nesmí odkazovat na jiný parametr ani obsahovat poddotaz.Pokud zadáte výchozí hodnotu pro jeden parametr, musí mít všechny následující parameters také výchozí hodnotu.
DEFAULT
je podporován pouze proLANGUAGE SQL
.KOMENTÁŘ
Volitelný popis parametru.
comment
musí býtSTRING
literál.
-
VRÁTÍ data_type
Návratový datový typ skalární funkce. Pro Python UDFs se values musí přesně shodovat s datovým typem uvedeným v
data_type
. Pokud chcete zabránit neočekávacím převodům typů, funkce selže.Pro UDF SQL je tato klauzule nepovinná. Datový typ bude odvozen z těla funkce, pokud není zadán.
RETURNS TABLE [ (column_spec [,...] ) ]
Tato klauzule označuje funkci jako funkci table. Volitelně také určuje podpis výsledku funkce table. Pokud není zadána žádná column_spec, bude odvozena z těla uživatelem definovaného uživatelem SQL.
RETURNS TABLE
je podporován pouze proLANGUAGE SQL
.-
Název column musí být v rámci podpisu jedinečný.
-
Libovolný podporovaný datový typ.
COLUMN_COMMENT KOMENTÁŘE
Volitelný popis column.
comment
musí býtSTRING
literál.
-
RETURN { expression | query }
Tělo funkce. Pro skalární funkci může být dotaz nebo výraz. U table funkce to může být jenom dotaz. Výraz nemůže obsahovat:
- Agregační funkce
- Window funkcí
- Funkce řazení
- Funkce pro výrobu řádků, jako je explodování
V těle funkce můžete odkazovat na parametr podle jeho nekvalifikovaného názvu nebo kvalifikace parametru s názvem funkce.
DOLLAR_QUOTED_DEFINITION AS
dollar_quoted_definition
je funkcebody
Pythonu uzavřená dvěma shodnými$[tag]$body$[tag]$
.tag
může být prázdný řetězec.Příklady:
$$ return “Hello world” $$ $py$ return "Hello World" $py$
charakteristický
Všechny charakteristické klauzule jsou volitelné. Můžete zadat libovolný počet v libovolném pořadí, ale každou klauzuli můžete zadat pouze jednou.
JAZYK SQL nebo JAZYK PYTHON
Jazyk implementace funkce.
[NE] DETERMINISTICKÝ
Zda je funkce deterministická. Funkce je deterministická, pokud vrátí pouze jeden výsledek pro danou set argumentů. Funkci můžete označit jako
DETERMINISTIC
v případě, že její tělo není a naopak. Důvodem může být podpora nebo odrazování optimalizace dotazů, jako je konstantní posouvání nebo ukládání dotazů do mezipaměti. Pokud nezadáte možnost ths, je odvozena z těla funkce.FUNCTION_COMMENT KOMENTÁŘE
Komentář pro funkci.
function_comment
musí být řetězcový literál.OBSAHUJE SQL nebo READS SQL DATA
Ať už funkce čte data přímo nebo nepřímo z table nebo z náhledu. Při čtení dat SQL funkce nelze zadat
CONTAINS SQL
. Pokud nezadáte ani jednu klauzuli, vlastnost je odvozena z těla funkce.
Podporované knihovny v uživatelem definovaných funkcích Pythonu
Pokud chcete použít jakékoli závislosti, použijte import <package>
v těle funkce. Podívejte se například na následující:
CREATE FUNCTION […]
AS $$
import json
[... (rest of function definition)]
$$
Závislosti jsou omezené na standardní knihovnu Pythonu a následující knihovny:
Balíček | Verze |
---|---|
bělit | 4.0.0 |
chardet | 4.0.0 |
charset-normalizer | 2.0.4 |
defusedxml | 0.7.1 |
googleapis-common-protos | 1.56.4 |
grpcio | 1.47.0 |
grpcio-status | 1.47.0 |
jmespath | 0.10.0 |
joblib | 1.1.0 |
numpy | 1.20.3 |
balení | 21.3 |
pandas | 1.3.4 |
bábovka | 0.5.2 |
protobuf | 4.21.5 |
pyarrow | 7.0.0 |
pyparsing | 3.0.9 |
python-dateutil | 2.8.2 |
pytz | 2021.3 |
scikit-learn | 0.24.2” |
scipy | 1.7.1” |
setuptools | 65.2.0 |
Šest | 1.16.0 |
threadpoolctl | 3.1.0 |
webencodings | 0.5.1 |
user-agents | 2.2.0 |
kryptografie | 38.0.4 |
Příklady
- Vytvoření a použití skalární funkce SQL
- Vytvoření a použití funkce, která používá defaulty
- Vytvoření funkce SQL table
- Nahrazení funkce SQL
- Popis funkce SQL
- Vytváření funkcí Pythonu
Vytvoření a použití skalární funkce SQL
> CREATE VIEW t(c1, c2) AS VALUES (0, 1), (1, 2);
-- Create a temporary function with no parameter.
> CREATE TEMPORARY FUNCTION hello() RETURNS STRING
RETURN 'Hello World!';
> SELECT hello();
Hello World!
-- Create a permanent function with parameters.
> CREATE FUNCTION area(x DOUBLE, y DOUBLE) RETURNS DOUBLE RETURN x * y;
-- Use a SQL function in the SELECT clause of a query.
> SELECT area(c1, c2) AS area FROM t;
0.0
2.0
-- Use a SQL function in the WHERE clause of a query.
> SELECT * FROM t WHERE area(c1, c2) > 0;
1 2
-- Compose SQL functions.
> CREATE FUNCTION square(x DOUBLE) RETURNS DOUBLE RETURN area(x, x);
> SELECT c1, square(c1) AS square FROM t;
0 0.0
1 1.0
-- Create a non-deterministic function
> CREATE FUNCTION roll_dice()
RETURNS INT
NOT DETERMINISTIC
CONTAINS SQL
COMMENT 'Roll a single 6 sided die'
RETURN (rand() * 6)::INT + 1;
-- Roll a single 6-sided die
> SELECT roll_dice();
3
Vytvoření a použití funkce, která používá defaulty
-- Extend the function to support variable number of sides and dice.
-- Use defaults to support a variable number of arguments
> DROP FUNCTION roll_dice;
> CREATE FUNCTION roll_dice(num_dice INT DEFAULT 1 COMMENT 'number of dice to roll (Default: 1)',
num_sides INT DEFAULT 6 COMMENT 'number of sides per die (Default: 6)')
RETURNS INT
NOT DETERMINISTIC
CONTAINS SQL
COMMENT 'Roll a number of n-sided dice'
RETURN aggregate(sequence(1, roll_dice.num_dice, 1),
0,
(acc, x) -> (rand() * roll_dice.num_sides)::int,
acc -> acc + roll_dice.num_dice);
-- Roll a single 6-sided die still works
> SELECT roll_dice();
3
-- Roll 3 6-sided dice
> SELECT roll_dice(3);
15
-- Roll 3 10-sided dice
> SELECT roll_dice(3, 10)
21
-- Roll 3 10-sided dice using named parameter invocation
> SELECT roll_dice(10 => num_sides, num_dice => 3)
17
-- Create a SQL function with a scalar subquery.
> CREATE VIEW scores(player, score) AS VALUES (0, 1), (0, 2), (1, 2), (1, 5);
> CREATE FUNCTION avg_score(p INT) RETURNS FLOAT
COMMENT 'get an average score of the player'
RETURN SELECT AVG(score) FROM scores WHERE player = p;
> SELECT c1, avg_score(c1) FROM t;
0 1.5
1 3.5
Vytvoření funkce SQL table
-- Produce all weekdays between two dates
> CREATE FUNCTION weekdays(start DATE, end DATE)
RETURNS TABLE(day_of_week STRING, day DATE)
RETURN SELECT extract(DAYOFWEEK_ISO FROM day), day
FROM (SELECT sequence(weekdays.start, weekdays.end)) AS T(days)
LATERAL VIEW explode(days) AS day
WHERE extract(DAYOFWEEK_ISO FROM day) BETWEEN 1 AND 5;
-- Return all weekdays
> SELECT weekdays.day_of_week, day
FROM weekdays(DATE'2022-01-01', DATE'2022-01-14');
1 2022-01-03
2 2022-01-04
3 2022-01-05
4 2022-01-06
5 2022-01-07
1 2022-01-10
2 2022-01-11
3 2022-01-12
4 2022-01-13
5 2022-01-14
-- Return weekdays for date ranges originating from a LATERAL correlation
> SELECT weekdays.*
FROM VALUES (DATE'2020-01-01'),
(DATE'2021-01-01'),
(DATE'2022-01-01') AS starts(start),
LATERAL weekdays(start, start + INTERVAL '7' DAYS);
3 2020-01-01
4 2020-01-02
5 2020-01-03
1 2020-01-06
2 2020-01-07
3 2020-01-08
5 2021-01-01
1 2021-01-04
2 2021-01-05
3 2021-01-06
4 2021-01-07
5 2021-01-08
1 2022-01-03
2 2022-01-04
3 2022-01-05
4 2022-01-06
5 2022-01-07
Nahrazení funkce SQL
-- Replace a SQL scalar function.
> CREATE OR REPLACE FUNCTION square(x DOUBLE) RETURNS DOUBLE RETURN x * x;
-- Replace a SQL table function.
> CREATE OR REPLACE FUNCTION getemps(deptno INT)
RETURNS TABLE (name STRING)
RETURN SELECT name FROM employee e WHERE e.deptno = getemps.deptno;
-- Describe a SQL table function.
> DESCRIBE FUNCTION getemps;
Function: default.getemps
Type: TABLE
Input: deptno INT
Returns: id INT
name STRING
Poznámka:
Existující funkci nelze nahradit jiným podpisem.
Popis funkce SQL
> DESCRIBE FUNCTION hello;
Function: hello
Type: SCALAR
Input: ()
Returns: STRING
> DESCRIBE FUNCTION area;
Function: default.area
Type: SCALAR
Input: x DOUBLE
y DOUBLE
Returns: DOUBLE
> DESCRIBE FUNCTION roll_dice;
Function: default.roll_dice
Type: SCALAR
Input: num_dice INT
num_sides INT
Returns: INT
> DESCRIBE FUNCTION EXTENDED roll_dice;
Function: default.roll_dice
Type: SCALAR
Input: num_dice INT DEFAULT 1 'number of dice to roll (Default: 1)'
num_sides INT DEFAULT 6 'number of sides per dice (Default: 6)'
Returns: INT
Comment: Roll a number of m-sided dice
Deterministic: false
Data Access: CONTAINS SQL
Configs: ...
Owner: the.house@always.wins
Create Time: Sat Feb 12 09:29:02 PST 2022
Body: aggregate(sequence(1, roll_dice.num_dice, 1),
0,
(acc, x) -> (rand() * roll_dice.num_sides)::int,
acc -> acc + roll_dice.num_dice)
Vytváření funkcí Pythonu
—- Hello World-like functionality using Python UDFs
> CREATE FUNCTION main.default.greet(s STRING)
RETURNS STRING
LANGUAGE PYTHON
AS $$
def greet(name):
return "Hello " + name + "!"
return greet(s) if s else None
$$
—- Can import functions from std library and environment
> CREATE FUNCTION main.default.isleapyear(year INT)
RETURNS BOOLEAN
LANGUAGE PYTHON
AS $$
import calendar
return calendar.isleap(year) if year else None
$$
—- Must return the correct type. Otherwise will fail at runtime.
> CREATE FUNCTION main.default.a_number()
RETURNS INTEGER
LANGUAGE PYTHON
AS $$
# does not work: return "10"
# does not work: return 3.14
return 10
$$
—- Deal with exceptions.
> CREATE FUNCTION main.default.custom_divide(n1 INT, n2 INT)
RETURNS FLOAT
LANGUAGE PYTHON
AS $$
try:
return n1/n2
except ZeroDivisionException:
# in case of 0, we can return NULL.
return None
$$