Traffine I/O

Bahasa Indonesia

2022-12-11

UDF di Snowflake

Apa itu User-Defined Function (UDF) di Snowflake

User-Defined Function (UDF) merupakan bagian integral dari Snowflake. Pada dasarnya, UDF adalah fungsi yang Anda tentukan untuk digunakan dalam pernyataan SQL. Seperti fungsi SQL bawaan, UDF secara utama meningkatkan fungsionalitas SQL dengan kemampuan tambahan atau tugas yang tidak termasuk secara native dalam bahasa tersebut.

Selain itu, UDF mengelompokkan beberapa fungsionalitas tertentu yang dapat Anda panggil secara berulang dari berbagai lokasi dalam kode Anda. Pengelompokan ini meningkatkan kegunaan ulang kode, menjadikannya alat berharga bagi pengembang dan administrator database yang bekerja dengan Snowflake.

Jenis UDF

Snowflake memungkinkan Anda untuk membuat dua jenis UDF: Fungsi Skalar dan Fungsi Tabular.

Fungsi Skalar

Fungsi skalar adalah jenis UDF yang mengembalikan satu nilai. Setiap baris masukan untuk fungsi skalar menghasilkan satu baris keluaran, yang terdiri dari satu kolom atau nilai tunggal. Karakteristik ini membuat fungsi skalar ideal untuk tugas yang perlu memanipulasi data secara baris per baris.

Fungsi Tabular

Di sisi lain, fungsi tabular, juga dikenal sebagai fungsi tabel yang didefinisikan pengguna (UDTF), mengembalikan nilai tabular untuk setiap baris masukan. Fungsi-fungsi ini menyediakan fungsionalitas yang lebih kompleks dibandingkan dengan fungsi skalar.

Saat membuat UDTF, Anda perlu menulis metode yang sesuai dengan antarmuka yang dibutuhkan oleh Snowflake. Secara khusus, metode-metode ini perlu:

  • Memproses setiap baris dalam sebuah partisi. Operasi ini merupakan bagian yang diperlukan dari UDTF.
  • Menginisialisasi penangan (handler) sekali untuk setiap partisi. Metode ini bersifat opsional tetapi dapat bermanfaat untuk beberapa kasus penggunaan.
  • Menyelesaikan pemrosesan untuk setiap partisi. Seperti inisialisasi, operasi ini bersifat opsional tetapi dapat digunakan untuk membersihkan resource atau menyelesaikan komputasi pada akhir pemrosesan.

Contoh UDF

Berikut ini adalah contoh pembuatan UDF dengan nama addone, yang menggunakan penangan yang ditulis dalam bahasa Python. Fungsi penangan adalah addone_py, dan UDF ini mengembalikan bilangan bulat.

sql
CREATE OR REPLACE FUNCTION addone(i int)
RETURNS INT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
HANDLER = 'addone_py'
as
$$
def addone_py(i):
  return i+1
$$;

Setelah UDF dibuat, Anda dapat menjalankannya seperti fungsi SQL bawaan lainnya. Contoh berikut menunjukkan cara menjalankan UDF addone.

sql
SELECT addone(3);

Pernyataan SQL ini akan menghasilkan keluaran 4, karena fungsi addone menambahkan 1 pada bilangan bulat masukan.

Bahasa yang Didukung untuk UDF

UDF di Snowflake mendukung berbagai bahasa pemrograman untuk menulis logika atau penangan fungsi. Ini memungkinkan pengembang menggunakan bahasa yang disukainya dalam batasan bahasa dan lingkungan runtime. Terlepas dari bahasa penangan, Anda membuat fungsi menggunakan SQL dengan menentukan penangan dan bahasa penangan yang Anda gunakan.

Berikut adalah bahasa-bahasa yang didukung untuk penangan UDF:

  • Java
  • JavaScript
  • Python
  • Scala
  • SQL

Membuat UDF di Snowflake

Membuat UDF atau UDTF melibatkan penulisan penangan untuk fungsi dan kemudian membuat fungsi itu sendiri dengan perintah CREATE FUNCTION.

Untuk membuat UDF di Snowflake, ikuti langkah-langkah berikut:

  1. Tulis kode penangan yang dieksekusi ketika UDF dipanggil. Penangan ini berisi logika UDF dan dapat ditulis dalam salah satu bahasa yang didukung seperti Java, JavaScript, Python, Scala, atau SQL.

  2. Pilih apakah akan menyimpan kode penangan dalam pernyataan SQL CREATE FUNCTION atau merujuknya ke stage. Keputusan ini akan bergantung pada kompleksitas dan panjang kode Anda, serta praktik pengelolaan kode organisasi Anda.

  3. Jalankan pernyataan CREATE FUNCTION dalam SQL, dengan menyebutkan properti fungsi. Properti ini mencakup nama fungsi, argumen masukan, tipe kembalian, dan fungsi penangan, antara lain.

Sintaks untuk Membuat UDF

Sintaks untuk membuat UDF bervariasi tergantung pada bahasa yang digunakan untuk menulis penangan.

Penangan Java dan Scala

Gunakan sintaks berikut jika kode sumber berada dalam pernyataan in-line:

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  [ COPY GRANTS ]
  RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
  [ [ NOT ] NULL ]
  LANGUAGE { JAVA | SCALA }
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ VOLATILE | IMMUTABLE ]
  [ RUNTIME_VERSION = <java_jdk_version> ]
  [ COMMENT = '<string_literal>' ]
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] ) ]
  [ PACKAGES = ( '<package_name_and_version>' [ , ... ] ) ]
  HANDLER = '<path_to_method>'
  [ TARGET_PATH = '<stage_path_and_file_name_to_write>' ]
  AS '<function_definition>'

Gunakan sintaks berikut jika kode penangan akan dirujuk pada stage (seperti dalam JAR):

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  [ COPY GRANTS ]
  RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
  [ [ NOT ] NULL ]
  LANGUAGE { JAVA | SCALA }
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ VOLATILE | IMMUTABLE ]
  [ RUNTIME_VERSION = <java_jdk_version> ]
  [ COMMENT = '<string_literal>' ]
  IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] )
  HANDLER = '<path_to_method>'

Penangan JavaScript

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  [ COPY GRANTS ]
  RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
  [ [ NOT ] NULL ]
  LANGUAGE JAVASCRIPT
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ VOLATILE | IMMUTABLE ]
  [ COMMENT = '<string_literal>' ]
  AS '<function_definition>'

Penangan Python

Gunakan sintaks berikut jika kode sumber berada dalam pernyataan in-line:

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  [ COPY GRANTS ]
  RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
  [ [ NOT ] NULL ]
  LANGUAGE PYTHON
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ VOLATILE | IMMUTABLE ]
  RUNTIME_VERSION = <python_version>
  [ COMMENT = '<string_literal>' ]
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] ) ]
  [ PACKAGES = ( '<package_name>[==<version>]' [ , ... ] ) ]
  HANDLER = '<function_name>'
  AS '<function_definition>'

Gunakan sintaks berikut jika kode penangan akan dirujuk pada stage (seperti dalam modul):

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  [ COPY GRANTS ]
  RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
  [ [ NOT ] NULL ]
  LANGUAGE PYTHON
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ VOLATILE | IMMUTABLE ]
  RUNTIME_VERSION = <python_version>
  [ COMMENT = '<string_literal>' ]
  IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] )
  [ PACKAGES = ( '<package_name>[==<version>]' [ , ... ] ) ]
  HANDLER = '<module_file_name>.<function_name>'

Penangan SQL

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  [ COPY GRANTS ]
  RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
  [ [ NOT ] NULL ]
  [ VOLATILE | IMMUTABLE ]
  [ MEMOIZABLE ]
  [ COMMENT = '<string_literal>' ]
  AS '<function_definition>'

Parameter untuk Pembuatan UDF

Snowflake menyediakan sejumlah parameter yang diperlukan dan opsional untuk setiap bahasa saat membuat UDF. Parameter-parameter ini memungkinkan Anda untuk menyesuaikan perilaku dan mengontrol properti-properti UDF. Untuk informasi terperinci tentang parameter-parameter ini, silakan merujuk ke dokumentasi resmi Snowflake yang terhubung dalam konten asli.

https://docs.snowflake.com/en/sql-reference/sql/create-function#required-parameters
https://docs.snowflake.com/en/sql-reference/sql/create-function#optional-parameters

Memanggil UDF di Snowflake

Setelah UDF dibuat di Snowflake, Anda dapat memanggilnya seperti memanggil fungsi lainnya.

Memanggil UDF

Cara umum memanggil UDF sama seperti memanggil fungsi lainnya. Nama UDF digunakan diikuti oleh tanda kurung, dan jika UDF memiliki argumen, argumen tersebut ditentukan di dalam tanda kurung. Argumen dapat ditentukan baik berdasarkan nama maupun posisi.

Mari pertimbangkan contoh UDF berikut yang menggabungkan tiga string:

sql
CREATE OR REPLACE FUNCTION udf_concatenate_strings(
    first VARCHAR,
    second VARCHAR,
    third VARCHAR)
  RETURNS VARCHAR
  LANGUAGE SQL
  AS
  $$
    RETURN first || second || third;
  $$;

Ketika memanggil UDF, argumen dapat ditentukan berdasarkan nama atau posisi:

sql
SELECT udf_concatenate_strings(
  first => 'one',
  second => 'two',
  third => 'three');
sql
SELECT udf_concatenate_strings(
  'one',
  'two',
  'three');

Ketika menentukan argumen, semua argumen harus ditentukan berdasarkan nama atau posisi. Gabungan keduanya tidak dapat digunakan.

Memanggil UDTF

UDTF, seperti UDF, juga dipanggil menggunakan namanya. Namun, karena mereka mengembalikan tabel, kata kunci TABLE digunakan saat memanggilnya, diikuti oleh nama UDTF dan argumen yang dikelilingi oleh tanda kurung.

Pertimbangkan contoh berikut di mana UDTF bernama my_java_udtf dipanggil dengan literal DATE '2021-01-16' sebagai argumen:

sql
SELECT ...
  FROM TABLE(my_java_udtf('2021-01-16'::DATE));

Sama seperti UDF, argumen untuk UDTF dapat ditentukan berdasarkan nama atau posisi.

Referensi

https://docs.snowflake.com/en/sql-reference/udf-overview
https://docs.snowflake.com/en/developer-guide/udf/udf-creating-sql
https://docs.snowflake.com/en/sql-reference/sql/create-function
https://docs.snowflake.com/en/developer-guide/udf/udf-calling-sql

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!