CREATE FUNCTIONยถ

์ƒˆ UDF(์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜) ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ๋ฐฉ์‹์— ๋”ฐ๋ผ ์ด ํ•จ์ˆ˜๋Š” ์Šค์นผ๋ผ ๊ฒฐ๊ณผ ๋˜๋Š” ํ…Œ์ด๋ธ” ํ˜•์‹ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

UDF๋ฅผ ๋งŒ๋“ค ๋•Œ ์ง€์›๋˜๋Š” ์–ธ์–ด ์ค‘ ํ•˜๋‚˜๋กœ ์ฝ”๋“œ๊ฐ€ ์ž‘์„ฑ๋œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ํ•ธ๋“ค๋Ÿฌ์˜ ์–ธ์–ด์— ๋”ฐ๋ผ, CREATE FUNCTION ๋ฌธ๊ณผ ํ•จ๊ป˜ ์ธ๋ผ์ธ์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ฑฐ๋‚˜ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ฏธ๋ฆฌ ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ์ด๊ฑฐ๋‚˜ ์Šคํ…Œ์ด์ง€์˜ ์†Œ์Šค ์ฝ”๋“œ์ธ ๊ฒฝ์šฐ CREATE FUNCTION์—์„œ ํ•ธ๋“ค๋Ÿฌ ์œ„์น˜๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ํ‘œ์—๋Š” ์ง€์›๋˜๋Š” ๊ฐ ์–ธ์–ด์™€ ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ CREATE FUNCTION๊ณผ ํ•จ๊ป˜ ์ธ๋ผ์ธ์œผ๋กœ ์œ ์ง€๋  ์ˆ˜ ์žˆ๋Š”์ง€, ๋˜๋Š” ์Šคํ…Œ์ด์ง€์— ์œ ์ง€๋  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๊ฐ€ ๋‚˜์—ด๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ๋ฅผ ์ธ๋ผ์ธ ๋˜๋Š” ์Šคํ…Œ์ด์ง€์— ์œ ์ง€ํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์–ธ์–ด

์ฒ˜๋ฆฌ๊ธฐ ์œ„์น˜

Java

์ธ๋ผ์ธ ๋˜๋Š” ์Šคํ…Œ์ด์ง•๋จ

JavaScript

์ธ๋ผ์ธ

Python

์ธ๋ผ์ธ ๋˜๋Š” ์Šคํ…Œ์ด์ง•๋จ

Scala

์ธ๋ผ์ธ ๋˜๋Š” ์Šคํ…Œ์ด์ง•๋จ

SQL

์ธ๋ผ์ธ

์ด ๋ช…๋ น์€ ๋‹ค์Œ ๋ณ€ํ˜•์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

  • CREATE OR ALTER FUNCTION: ํ•จ์ˆ˜๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ํ•จ์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ  ํ•ญ๋ชฉ:

ALTER FUNCTION, DROP FUNCTION, SHOW USER FUNCTIONS , DESCRIBE FUNCTION, CREATE OR ALTER <์˜ค๋ธŒ์ ํŠธ>

๊ตฌ๋ฌธยถ

CREATE FUNCTION์˜ ๊ตฌ๋ฌธ์€ UDF ํ•ธ๋“ค๋Ÿฌ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์–ธ์–ด์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

Java ํ•ธ๋“ค๋Ÿฌยถ

์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์ธ๋ผ์ธ ์ƒํƒœ์ธ ๊ฒฝ์šฐ ์•„๋ž˜ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> (
    [ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
  [ COPY GRANTS ]
  RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
  [ [ NOT ] NULL ]
  LANGUAGE JAVA
  [ { 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>'
  [ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
  [ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
  [ TARGET_PATH = '<stage_path_and_file_name_to_write>' ]
  AS '<function_definition>'
Copy

์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ๊ฐ€ ์Šคํ…Œ์ด์ง€(์˜ˆ: JAR)์—์„œ ์ฐธ์กฐ๋˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> (
    [ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
  [ COPY GRANTS ]
  RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
  [ [ NOT ] NULL ]
  LANGUAGE JAVA
  [ { 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>'
  [ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
  [ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
Copy

JavaScript ํ•ธ๋“ค๋Ÿฌยถ

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION <name> (
    [ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
  [ 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>'
Copy

Python ํ•ธ๋“ค๋Ÿฌยถ

์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์ธ๋ผ์ธ ์ƒํƒœ์ธ ๊ฒฝ์šฐ ์•„๋ž˜ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] [ AGGREGATE ] FUNCTION [ IF NOT EXISTS ] <name> (
    [ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
  [ 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>]' [ , ... ] ) ]
  [ ARTIFACT_REPOSITORY = '<repository_name>' ]
  [ ARTIFACT_REPOSITORY_PACKAGES = ( '<package_name>' [ , ... ] ) ]
  HANDLER = '<function_name>'
  [ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
  [ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
  AS '<function_definition>'
Copy

์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ๊ฐ€ ์Šคํ…Œ์ด์ง€(์˜ˆ: ๋ชจ๋“ˆ)์—์„œ ์ฐธ์กฐ๋˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] [ AGGREGATE ] FUNCTION [ IF NOT EXISTS ] <name> (
    [ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
  [ 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>' ]
  [ ARTIFACT_REPOSITORY = '<repository_name>' ]
  [ ARTIFACT_REPOSITORY_PACKAGES = ( '<package_name>' [ , ... ] ) ]
  IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] )
  [ PACKAGES = ( '<package_name>[==<version>]' [ , ... ] ) ]
  HANDLER = '<module_file_name>.<function_name>'
  [ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
  [ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
Copy

Scala ํ•ธ๋“ค๋Ÿฌยถ

์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์ธ๋ผ์ธ ์ƒํƒœ์ธ ๊ฒฝ์šฐ ์•„๋ž˜ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> (
    [ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
  [ COPY GRANTS ]
  RETURNS <result_data_type>
  [ [ NOT ] NULL ]
  LANGUAGE SCALA
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ { VOLATILE | IMMUTABLE } ]
  [ RUNTIME_VERSION = <scala_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>'
Copy

์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ๊ฐ€ ์Šคํ…Œ์ด์ง€(์˜ˆ: JAR)์—์„œ ์ฐธ์กฐ๋˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

SQL ํ•ธ๋“ค๋Ÿฌยถ

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

๋ฒ ๋ฆฌ์–ธํŠธ ๊ตฌ๋ฌธยถ

CREATE OR ALTER FUNCTIONยถ

์•„์ง ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ƒˆ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๊ธฐ์กด ํ•จ์ˆ˜๋ฅผ ๋ฌธ์— ์ •์˜๋œ ํ•จ์ˆ˜๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. CREATE OR ALTER FUNCTION ๋ฌธ์€ CREATE FUNCTION ๋ฌธ์˜ ๊ตฌ๋ฌธ ๊ทœ์น™์„ ๋”ฐ๋ฅด๋ฉฐ ALTER FUNCTION ๋ฌธ๊ณผ ์ œํ•œ ์‚ฌํ•ญ์ด ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

์ง€์›๋˜๋Š” ํ•จ์ˆ˜ ๋ณ€๊ฒฝ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํ•จ์ˆ˜ ์†์„ฑ ๋ฐ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ: SECURE, MAX_BATCH_ROWS, LOG_LEVEL ๋˜๋Š” COMMENT.

์ž์„ธํ•œ ๋‚ด์šฉ์€ CREATE OR ALTER FUNCTION ์‚ฌ์šฉ๋ฒ• ๋…ธํŠธ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

CREATE [ OR ALTER ] FUNCTION ...
Copy

์ฐธ๊ณ 

COPY GRANTS ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” ์ด ๋ฒ ๋ฆฌ์–ธํŠธ ๊ตฌ๋ฌธ์—์„œ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•„์ˆ˜ ๋งค๊ฐœ ๋ณ€์ˆ˜ยถ

๋ชจ๋“  ์–ธ์–ดยถ

name ( [ arg_name arg_data_type [ DEFAULT default_value ] ] [ , ... ] )

UDF์— ๋Œ€ํ•œ ์‹๋ณ„์ž(name), ์ž…๋ ฅ ์ธ์ž, ์„ ํƒ์  ์ธ์ž์˜ ๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

  • ์‹๋ณ„์ž์˜ ๊ฒฝ์šฐ:

    • UDF๋Š” ์ด๋ฆ„๊ณผ ์ธ์ž ํƒ€์ž…์˜ ์กฐํ•ฉ์œผ๋กœ ์‹๋ณ„ ๋ฐ ํ™•์ธ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‹๋ณ„์ž๋Š” ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์Šคํ‚ค๋งˆ์— ๋Œ€ํ•ด ๊ณ ์œ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

    • ์‹๋ณ„์ž๋Š” ์•ŒํŒŒ๋ฒณ ๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•˜๋ฉฐ ์ „์ฒด ์‹๋ณ„์ž ๋ฌธ์ž์—ด์„ ํฐ๋”ฐ์˜ดํ‘œ(์˜ˆ: โ€œMy objectโ€)๋กœ ๋ฌถ์ง€ ์•Š๋Š” ํ•œ ๊ณต๋ฐฑ์ด๋‚˜ ํŠน์ˆ˜ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์ธ ์‹๋ณ„์ž๋„ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์‹๋ณ„์ž ์š”๊ตฌ ์‚ฌํ•ญ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • ์ž…๋ ฅ ์ธ์ž์˜ ๊ฒฝ์šฐ:

RETURNS ...

UDF์—์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์ง€์ •ํ•˜๋ฉฐ, ์ด์— ๋”ฐ๋ผ UDF ํ˜•์‹์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.

  • result_data_type: ์ง€์ •๋œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์˜ ๋‹จ์ผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์Šค์นผ๋ผ UDF๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    ์ฐธ๊ณ 

    Java, Python ๋˜๋Š” Scala๋กœ ์ž‘์„ฑ๋œ UDF ์ฒ˜๋ฆฌ๊ธฐ์˜ ๊ฒฝ์šฐ result_data_type ์€ ์ฒ˜๋ฆฌ๊ธฐ ์–ธ์–ด์— ํ•ด๋‹นํ•˜๋Š” ๋‹ค์Œ ํ…Œ์ด๋ธ”์˜ SQL Data Type ์—ด์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • TABLE ( col_name col_data_type , ... ): ์ง€์ •๋œ ํ…Œ์ด๋ธ” ์—ด๊ณผ ์—ด ํ˜•์‹์„ ํฌํ•จํ•œ ํ…Œ์ด๋ธ” ํ˜•์‹ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ…Œ์ด๋ธ” UDF๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    ์ฐธ๊ณ 

    Scala UDF์˜ ๊ฒฝ์šฐ UDFs ๋ฐ˜ํ™˜ ์œ ํ˜•์ด ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

AS function_definition

UDF๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์‹คํ–‰๋˜๋Š” ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. function_definition ๊ฐ’์€ ํ•ธ๋“ค๋Ÿฌ์— ๋Œ€ํ•ด ์ง€์›๋˜๋Š” ์–ธ์–ด ์ค‘ ํ•˜๋‚˜๋กœ ์ž‘์„ฑ๋œ ์†Œ์Šค ์ฝ”๋“œ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Java. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Java UDF ์†Œ๊ฐœ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • JavaScript. ์ž์„ธํ•œ ๋‚ด์šฉ์€ JavaScript UDF ์†Œ๊ฐœ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • Python. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Python UDF ์†Œ๊ฐœ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • Scala ์ž์„ธํ•œ ๋‚ด์šฉ์€ Scala UDF ์†Œ๊ฐœ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • SQL ์‹์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ SQL UDF ์†Œ๊ฐœ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด ํ•ญ๋ชฉ์˜ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ๋ฒ• ๋…ธํŠธ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ฐธ๊ณ 

IMPORTS ์ ˆ์ด ์žˆ๋Š” ์Šคํ…Œ์ด์ง€์—์„œ UDF ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ•  ๋•Œ AS ์ ˆ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Javaยถ

LANGUAGE JAVA

์ฝ”๋“œ๊ฐ€ Java ์–ธ์–ด๋กœ ๋˜์–ด ์žˆ์Œ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

RUNTIME_VERSION = java_jdk_version

์‚ฌ์šฉํ•  Java JDK ๋Ÿฐํƒ€์ž„ ๋ฒ„์ „์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ง€์›๋˜๋Š” Java ๋ฒ„์ „์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • 11.x

  • 17.x

RUNTIME_VERSION ์ด ์„ค์ •๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด Java JDK 11์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

IMPORTS = ( 'stage_path_and_file_name_to_read' [ , ... ] )

๊ฐ€์ ธ์˜ฌ ํŒŒ์ผ์˜ ์œ„์น˜(์Šคํ…Œ์ด์ง€), ๊ฒฝ๋กœ, ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

ํŒŒ์ผ์€ JAR ํŒŒ์ผ ๋˜๋Š” ๋‹ค๋ฅธ ์œ ํ˜•์˜ ํŒŒ์ผ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒŒ์ผ์ด JAR ํŒŒ์ผ์ธ ๊ฒฝ์šฐ ํ•˜๋‚˜ ์ด์ƒ์˜ .class ํŒŒ์ผ๊ณผ 0๊ฐœ ๋˜๋Š” ๊ทธ ์ด์ƒ์˜ ๋ฆฌ์†Œ์Šค ํŒŒ์ผ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JNI(Java ๋„ค์ดํ‹ฐ๋ธŒ ์ธํ„ฐํŽ˜์ด์Šค)๋Š” ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Snowflake๋Š” (Java ๋ฐ”์ดํŠธ ์ฝ”๋“œ์™€๋Š” ๋Œ€์กฐ์ ์œผ๋กœ) ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋กœ๋”ฉํ•˜๋Š” ๊ฒƒ์„ ๊ธˆ์ง€ํ•ฉ๋‹ˆ๋‹ค.

Java UDFs๋Š” JAR ํŒŒ์ผ์ด ์•„๋‹Œ ํŒŒ์ผ๋„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋ณด๋ ค๋ฉด IMPORTS์—์„œ ์ •์ ์œผ๋กœ ์ง€์ •๋œ ํŒŒ์ผ ์ฝ๊ธฐ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

ํŒŒ์ผ(JAR ํŒŒ์ผ ๋˜๋Š” ๊ธฐํƒ€ ํŒŒ์ผ)์„ ์Šคํ…Œ์ด์ง€๋กœ ๋ณต์‚ฌํ•˜๋ ค๋Š” ๊ฒฝ์šฐ Snowflake์—์„œ๋Š” ๋ช…๋ช…๋œ ๋‚ด๋ถ€ ์Šคํ…Œ์ด์ง€ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” PUT ๋ช…๋ น์ด ๋ช…๋ช…๋œ ๋‚ด๋ถ€ ์Šคํ…Œ์ด์ง€๋กœ์˜ ํŒŒ์ผ ๋ณต์‚ฌ๋ฅผ ์ง€์›ํ•˜๊ณ  PUT ๋ช…๋ น์ด ๋ณดํ†ต์€ JAR ํŒŒ์ผ์„ ์Šคํ…Œ์ด์ง€๋กœ ๊ฐ€์žฅ ์‰ฝ๊ฒŒ ์ด๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์™ธ๋ถ€ ์Šคํ…Œ์ด์ง€๊ฐ€ ํ—ˆ์šฉ๋˜์ง€๋งŒ, PUT ์˜ ์ง€์›์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŒŒ์ผ์ด ๋‹ค๋ฅธ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋‚˜ ๋‹ค๋ฅธ ์Šคํ…Œ์ด์ง€์— ์žˆ๋”๋ผ๋„ IMPORTS ์ ˆ์˜ ๊ฐ ํŒŒ์ผ์€ ๊ณ ์œ ํ•œ ์ด๋ฆ„์„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

IMPORTS ๋ฐ TARGET_PATH ์ ˆ์ด ๋ชจ๋‘ ์žˆ๋Š” ๊ฒฝ์šฐ, ํŒŒ์ผ์ด ๋‹ค๋ฅธ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋‚˜ ๋‹ค๋ฅธ ์Šคํ…Œ์ด์ง€์— ์žˆ๋”๋ผ๋„ TARGET_PATH ์ ˆ์˜ ํŒŒ์ผ ์ด๋ฆ„์€ IMPORTS ์ ˆ์˜ ๊ฐ ํŒŒ์ผ ์ด๋ฆ„๊ณผ ๋‹ฌ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Snowflake์—์„œ๋Š” TARGET_PATH ๊ฐ€ ๊ธฐ์กด ํŒŒ์ผ๊ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. TARGET_PATH ๋ฅผ ์‚ฌ์šฉํ•ด ๊ธฐ์กด ํŒŒ์ผ์„ ๋ฎ์–ด์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ์Šคํ…Œ์ด์ง€์— ์žˆ๋Š” UDF์˜ ๊ฒฝ์šฐ UDF๋ฅผ ํฌํ•จํ•œ JAR ํŒŒ์ผ์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•ด์ฃผ๋Š” IMPORTS ์ ˆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ๊ฐ€ ์ธ๋ผ์ธ ์ƒํƒœ์ธ UDF์˜ ๊ฒฝ์šฐ, ์ธ๋ผ์ธ UDF๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋˜๋Š” ํ…์ŠคํŠธ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ํŒŒ์ผ์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•  ๋•Œ๋งŒ IMPORTS ์ ˆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Snowpark ํŒจํ‚ค์ง€ ์™€ ๊ฐ™์€ Snowflake ์‹œ์Šคํ…œ ํŒจํ‚ค์ง€์˜ ๊ฒฝ์šฐ JAR ํŒŒ์ผ์„ IMPORTS ๋กœ ์ง€์ •ํ•˜๋Š” ๋Œ€์‹  PACKAGES ์ ˆ๋กœ ํŒจํ‚ค์ง€๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ํŒจํ‚ค์ง€ JAR ํŒŒ์ผ์„ IMPORTS ๊ฐ’์— ํฌํ•จํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

์ธ๋ผ์ธ Java

AS function_definition

์ธ๋ผ์ธ Java UDFs๋Š” ํ•จ์ˆ˜ ์ •์˜ ๊ฐ€ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.

HANDLER = handler_name

์ฒ˜๋ฆฌ๊ธฐ ๋ฉ”์„œ๋“œ ๋˜๋Š” ํด๋ž˜์Šค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

  • ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ํ…Œ์ด๋ธ” ํ˜•์‹์ด ์•„๋‹Œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์Šค์นผ๋ผ UDF์˜ ์ฒ˜๋ฆฌ๊ธฐ์ธ ๊ฒฝ์šฐ HANDLER ๊ฐ’์€ MyClass.myMethod ํ˜•์‹์—์„œ์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ…Œ์ด๋ธ” ํ˜•์‹์˜ UDF์ธ ๊ฒฝ์šฐ HANDLER ๊ฐ’์€ ํ•ธ๋“ค๋Ÿฌ ํด๋ž˜์Šค์˜ ์ด๋ฆ„์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

JavaScriptยถ

LANGUAGE JAVASCRIPT

์ฝ”๋“œ๊ฐ€ JavaScript ์–ธ์–ด๋กœ ๋˜์–ด ์žˆ์Œ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

Pythonยถ

LANGUAGE PYTHON

์ฝ”๋“œ๊ฐ€ Python ์–ธ์–ด๋กœ ๋˜์–ด ์žˆ์Œ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

RUNTIME_VERSION = python_version

์‚ฌ์šฉํ•  Python ๋ฒ„์ „์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ง€์›๋˜๋Š” Python ๋ฒ„์ „์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • 3.9

  • 3.10

  • 3.11

  • 3.12

IMPORTS = ( 'stage_path_and_file_name_to_read' [ , ... ] )

๊ฐ€์ ธ์˜ฌ ํŒŒ์ผ์˜ ์œ„์น˜(์Šคํ…Œ์ด์ง€), ๊ฒฝ๋กœ, ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

ํŒŒ์ผ์€ .py ํŒŒ์ผ ๋˜๋Š” ๋‹ค๋ฅธ ์œ ํ˜•์˜ ํŒŒ์ผ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Python UDF๋Š” ํ…์ŠคํŠธ ํŒŒ์ผ๊ณผ ๊ฐ™์€ Python ํŒŒ์ผ ์ด์™ธ์˜ ํŒŒ์ผ๋„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋ณด๋ ค๋ฉด ํŒŒ์ผ ์ฝ๊ธฐ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

ํŒŒ์ผ์„ ์Šคํ…Œ์ด์ง€๋กœ ๋ณต์‚ฌํ•˜๋ ค๋Š” ๊ฒฝ์šฐ Snowflake์—์„œ๋Š” ๋ช…๋ช…๋œ ๋‚ด๋ถ€ ์Šคํ…Œ์ด์ง€ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” PUT ๋ช…๋ น์ด ๋ช…๋ช…๋œ ๋‚ด๋ถ€ ์Šคํ…Œ์ด์ง€๋กœ์˜ ํŒŒ์ผ ๋ณต์‚ฌ๋ฅผ ์ง€์›ํ•˜๊ณ  PUT ๋ช…๋ น์ด ๋ณดํ†ต์€ ํŒŒ์ผ์„ ์Šคํ…Œ์ด์ง€๋กœ ๊ฐ€์žฅ ์‰ฝ๊ฒŒ ์ด๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์™ธ๋ถ€ ์Šคํ…Œ์ด์ง€๊ฐ€ ํ—ˆ์šฉ๋˜์ง€๋งŒ, PUT ์˜ ์ง€์›์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŒŒ์ผ์ด ๋‹ค๋ฅธ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋‚˜ ๋‹ค๋ฅธ ์Šคํ…Œ์ด์ง€์— ์žˆ๋”๋ผ๋„ IMPORTS ์ ˆ์˜ ๊ฐ ํŒŒ์ผ์€ ๊ณ ์œ ํ•œ ์ด๋ฆ„์„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ๊ฐ€ ์Šคํ…Œ์ด์ง€์— ์ €์žฅ๋˜์–ด ์žˆ์œผ๋ฉด IMPORTS ์ ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ธ๋ผ์ธ Python UDF์˜ ๊ฒฝ์šฐ, UDF ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํŒจํ‚ค์ง€ ๋˜๋Š” ํ…์ŠคํŠธ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ํŒŒ์ผ์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•  ๋•Œ๋งŒ IMPORTS ์ ˆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

numpy ๊ณผ ๊ฐ™์€ Snowflake ์‹œ์Šคํ…œ์— ํฌํ•จ๋œ ํŒจํ‚ค์ง€์˜ ๊ฒฝ์šฐ, PACKAGES ์ ˆ๋งŒ ์‚ฌ์šฉํ•ด ํŒจํ‚ค์ง€๋ฅผ ์ง€์ •ํ•˜์—ฌ ํŒจํ‚ค์ง€ ์›๋ณธ์„ IMPORTS ๊ฐ’์œผ๋กœ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

HANDLER = handler_name

์ฒ˜๋ฆฌ๊ธฐ ํ•จ์ˆ˜ ๋˜๋Š” ํด๋ž˜์Šค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

  • ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์Šค์นผ๋ผ UDF์šฉ์œผ๋กœ, ํ…Œ์ด๋ธ” ํ˜•์‹์ด ์•„๋‹Œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ, HANDLER ๊ฐ’์€ ํ•จ์ˆ˜ ์ด๋ฆ„์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ๊ฐ€ CREATE FUNCTION ๋ฌธ๊ณผ ์ธ๋ผ์ธ์ผ ๊ฒฝ์šฐ ํ•จ์ˆ˜ ์ด๋ฆ„๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ๊ฐ€ ์Šคํ…Œ์ด์ง€์—์„œ ์ฐธ์กฐ๋  ๋•Œ ์ด ๊ฐ’์€ my_module.my_function ํ˜•์‹์—์„œ์ฒ˜๋Ÿผ ๋ชจ๋“ˆ ์ด๋ฆ„์œผ๋กœ ์ •๊ทœํ™”๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ…Œ์ด๋ธ” ํ˜•์‹์˜ UDF์ธ ๊ฒฝ์šฐ HANDLER ๊ฐ’์€ ํ•ธ๋“ค๋Ÿฌ ํด๋ž˜์Šค์˜ ์ด๋ฆ„์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Scalaยถ

LANGUAGE SCALA

์ฝ”๋“œ๊ฐ€ Scala ์–ธ์–ด๋กœ ๋˜์–ด ์žˆ์Œ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

RUNTIME_VERSION = scala_version

์‚ฌ์šฉํ•  Scala ๋Ÿฐํƒ€์ž„ ๋ฒ„์ „์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ง€์›๋˜๋Š” Scala ๋ฒ„์ „์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • 2.12

RUNTIME_VERSION ์ด ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ Scala 2.12๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

IMPORTS = ( 'stage_path_and_file_name_to_read' [ , ... ] )

JAR ๋˜๋Š” ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ํŒŒ์ผ๊ณผ ๊ฐ™์ด, ๊ฐ€์ ธ์˜ฌ ํŒŒ์ผ์˜ ์œ„์น˜(์Šคํ…Œ์ด์ง€), ๊ฒฝ๋กœ, ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

  • JAR ํŒŒ์ผ์—๋Š” ์ฒ˜๋ฆฌ๊ธฐ ์ข…์†์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜ ์ด์ƒ์˜ .class ํŒŒ์ผ๊ณผ 0๊ฐœ ๋˜๋Š” ๊ทธ ์ด์ƒ์˜ ๋ฆฌ์†Œ์Šค ํŒŒ์ผ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    JNI(Java ๋„ค์ดํ‹ฐ๋ธŒ ์ธํ„ฐํŽ˜์ด์Šค)๋Š” ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Snowflake๋Š” (Java ๋ฐ”์ดํŠธ ์ฝ”๋“œ์™€๋Š” ๋Œ€์กฐ์ ์œผ๋กœ) ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋กœ๋”ฉํ•˜๋Š” ๊ฒƒ์„ ๊ธˆ์ง€ํ•ฉ๋‹ˆ๋‹ค.

  • JAR ํŒŒ์ผ์ด ์•„๋‹Œ ํŒŒ์ผ์€ ์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ์—์„œ ์ฝ์€ ํŒŒ์ผ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋ณด๋ ค๋ฉด IMPORTS์—์„œ ์ •์ ์œผ๋กœ ์ง€์ •๋œ ํŒŒ์ผ ์ฝ๊ธฐ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

ํŒŒ์ผ์„ ์Šคํ…Œ์ด์ง€๋กœ ๋ณต์‚ฌํ•˜๋ ค๋Š” ๊ฒฝ์šฐ Snowflake์—์„œ๋Š” ๋ช…๋ช…๋œ ๋‚ด๋ถ€ ์Šคํ…Œ์ด์ง€ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” PUT ๋ช…๋ น์ด ๋ช…๋ช…๋œ ๋‚ด๋ถ€ ์Šคํ…Œ์ด์ง€๋กœ์˜ ํŒŒ์ผ ๋ณต์‚ฌ๋ฅผ ์ง€์›ํ•˜๊ณ  PUT ๋ช…๋ น์ด ๋ณดํ†ต์€ JAR ํŒŒ์ผ์„ ์Šคํ…Œ์ด์ง€๋กœ ๊ฐ€์žฅ ์‰ฝ๊ฒŒ ์ด๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์™ธ๋ถ€ ์Šคํ…Œ์ด์ง€๊ฐ€ ํ—ˆ์šฉ๋˜์ง€๋งŒ, PUT ์˜ ์ง€์›์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŒŒ์ผ์ด ๋‹ค๋ฅธ ์Šคํ…Œ์ด์ง€ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋‚˜ ๋‹ค๋ฅธ ์Šคํ…Œ์ด์ง€์— ์žˆ๋”๋ผ๋„ IMPORTS ์ ˆ์˜ ๊ฐ ํŒŒ์ผ์€ ๊ณ ์œ ํ•œ ์ด๋ฆ„์„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

IMPORTS ๋ฐ TARGET_PATH ์ ˆ์ด ๋ชจ๋‘ ์žˆ๋Š” ๊ฒฝ์šฐ, ํŒŒ์ผ์ด ๋‹ค๋ฅธ ์Šคํ…Œ์ด์ง€ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋‚˜ ๋‹ค๋ฅธ ์Šคํ…Œ์ด์ง€์— ์žˆ๋”๋ผ๋„ TARGET_PATH ์ ˆ์˜ ํŒŒ์ผ ์ด๋ฆ„์€ IMPORTS ์ ˆ์— ๋‚˜์—ด๋œ ํŒŒ์ผ์˜ ์ด๋ฆ„๊ณผ ๋‹ฌ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ์Šคํ…Œ์ด์ง€์— ์žˆ๋Š” UDF์˜ ๊ฒฝ์šฐ UDF๋ฅผ ํฌํ•จํ•œ JAR ํŒŒ์ผ์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•ด์ฃผ๋Š” IMPORTS ์ ˆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ๊ฐ€ ์ธ๋ผ์ธ ์ƒํƒœ์ธ UDF์˜ ๊ฒฝ์šฐ, ์ธ๋ผ์ธ UDF๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋˜๋Š” ํ…์ŠคํŠธ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ํŒŒ์ผ์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•  ๋•Œ๋งŒ IMPORTS ์ ˆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Snowpark ํŒจํ‚ค์ง€ ์™€ ๊ฐ™์€ Snowflake ์‹œ์Šคํ…œ ํŒจํ‚ค์ง€์˜ ๊ฒฝ์šฐ JAR ํŒŒ์ผ์„ IMPORTS ๋กœ ์ง€์ •ํ•˜๋Š” ๋Œ€์‹  PACKAGES ์ ˆ๋กœ ํŒจํ‚ค์ง€๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ํŒจํ‚ค์ง€ JAR ํŒŒ์ผ์„ IMPORTS ๊ฐ’์— ํฌํ•จํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

์ธ๋ผ์ธ Scala

AS function_definition

์ธ๋ผ์ธ Scala ์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” UDF์—๋Š” ํ•จ์ˆ˜ ์ •์˜ ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

HANDLER = handler_name

์ฒ˜๋ฆฌ๊ธฐ ๋ฉ”์„œ๋“œ ๋˜๋Š” ํด๋ž˜์Šค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

  • ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ํ…Œ์ด๋ธ” ํ˜•์‹์ด ์•„๋‹Œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์Šค์นผ๋ผ UDF์˜ ์ฒ˜๋ฆฌ๊ธฐ์ธ ๊ฒฝ์šฐ HANDLER ๊ฐ’์€ MyClass.myMethod ํ˜•์‹์—์„œ์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜ยถ

๋ชจ๋“  ์–ธ์–ดยถ

SECURE

ํ•จ์ˆ˜๊ฐ€ ์•ˆ์ „ํ•œ ๊ฒƒ์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ณด์•ˆ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Secure UDF์™€ ์ €์žฅ ํ”„๋กœ์‹œ์ €๋กœ ๋ฏผ๊ฐํ•œ ์ •๋ณด ๋ณดํ˜ธํ•˜๊ธฐ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

{ TEMP | TEMPORARY }

ํ•จ์ˆ˜๊ฐ€ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•œ ์„ธ์…˜ ์˜ ์ง€์† ๊ธฐ๊ฐ„ ๋™์•ˆ๋งŒ ์ง€์†๋˜๋„๋ก ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ž„์‹œ ํ•จ์ˆ˜๋Š” ์„ธ์…˜์ด ๋๋‚˜๋ฉด ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ๊ฐ’: ๊ฐ’ ์—†์Œ. TEMPORARY ๋กœ ์„ ์–ธ๋˜์ง€ ์•Š์€ ํ•จ์ˆ˜๋Š” ์˜๊ตฌ์ ์ž…๋‹ˆ๋‹ค.

์Šคํ‚ค๋งˆ์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜์™€ ์ด๋ฆ„์ด ๊ฐ™์€ ์ž„์‹œ ์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜ ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

[ [ NOT ] NULL ]

ํ•จ์ˆ˜๊ฐ€ NULL ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๊ฑฐ๋‚˜ NON-NULL ๊ฐ’๋งŒ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ NULL์ž…๋‹ˆ๋‹ค(์ฆ‰, ์ด ํ•จ์ˆ˜๋Š” NULL์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Œ).

์ฐธ๊ณ 

ํ˜„์žฌ, NOT NULL ์ ˆ์€ SQL UDFs์— ๋Œ€ํ•ด ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. NOT NULL ๋กœ ์„ ์–ธ๋œ SQL UDFs๋Š” NULL ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Snowflake๋Š” NULL ๊ฐ’์ด ์ ˆ๋Œ€ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๋„๋ก ํ•จ์ˆ˜์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ SQL UDFs์— ๋Œ€ํ•ด NOT NULL ์„ ํ”ผํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

CALLED ON NULL INPUT ๋˜๋Š” . { RETURNS NULL ON NULL INPUT | STRICT }

null ์ž…๋ ฅ์œผ๋กœ ํ˜ธ์ถœ ์‹œ UDF์˜ ๋™์ž‘์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ๊ฐ’์ด null์ผ ๋•Œ ํ•ญ์ƒ null์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์‹œ์Šคํ…œ ์ •์˜ ํ•จ์ˆ˜์™€๋Š” ๋ฐ˜๋Œ€๋กœ, UDFs๋Š” null ์ž…๋ ฅ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ž…๋ ฅ๊ฐ’์ด null์ผ ๋•Œ๋„ null์ด ์•„๋‹Œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • CALLED ON NULL INPUT ์€ ํ•ญ์ƒ null ์ž…๋ ฅ์œผ๋กœ UDF๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ์™€ ๊ฐ™์€ ๊ฐ’์„ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์€ UDF์— ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ž…๋ ฅ๊ฐ’์ด null์ธ ๊ฒฝ์šฐ RETURNS NULL ON NULL INPUT (๋˜๋Š” ๊ทธ ๋™์˜์–ด์ธ STRICT)์€ UDF๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ํ•ด๋‹น ํ–‰์— ๋Œ€ํ•ด ํ•ญ์ƒ null ๊ฐ’์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. UDF๋Š” null์ด ์•„๋‹Œ ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•ด ์—ฌ์ „ํžˆ null์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ 

SQL UDF์— ๋Œ€ํ•ด RETURNS NULL ON NULL INPUT (STRICT)์ด ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. SQL UDF๋Š” ์‚ฌ์‹ค์ƒ CALLED ON NULL INPUT ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. SQL UDF์—์„œ null ์ž…๋ ฅ๊ฐ’์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ๊ฐ’: CALLED ON NULL INPUT

{ VOLATILE | IMMUTABLE }

๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ UDF์˜ ๋™์ž‘์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

  • VOLATILE: (์˜ˆ: ๋น„๊ฒฐ์ •์„ฑ ๋ฐ ์ƒํƒœ ์ €์žฅ์œผ๋กœ ์ธํ•ด) UDF๋Š” ๋˜‘๊ฐ™์€ ์ž…๋ ฅ์— ๋Œ€ํ•ด์„œ๋„ ๋‹ค๋ฅธ ํ–‰์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • IMMUTABLE: UDF๋Š” ๊ฐ™์€ ์ž…๋ ฅ์œผ๋กœ ํ˜ธ์ถœ ์‹œ ํ•จ์ˆ˜๊ฐ€ ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ณด์ฆ์€ ํ™•์ธ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ™์€ ์ž…๋ ฅ์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” UDF์— ๋Œ€ํ•ด IMMUTABLE ์„ ์ง€์ •ํ•˜๋ฉด ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

๊ธฐ๋ณธ๊ฐ’: VOLATILE

์ฐธ๊ณ 

IMMUTABLE์€ ์ง‘๊ณ„ ํ•จ์ˆ˜์—์„œ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(AGGREGATE ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ). ๋”ฐ๋ผ์„œ ๋ชจ๋“  ์ง‘๊ณ„ ํ•จ์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ VOLATILE์ž…๋‹ˆ๋‹ค.

COMMENT = 'string_literal'

SHOW FUNCTIONS ๋ฐ SHOW USER FUNCTIONS ์ถœ๋ ฅ์˜ DESCRIPTION ์—ด์— ํ‘œ์‹œ๋˜๋Š” UDF์— ๋Œ€ํ•œ ์„ค๋ช…์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ๊ฐ’: user-defined function

COPY GRANTS

CREATE OR REPLACE FUNCTION์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ๋•Œ ์›๋ž˜ ํ•จ์ˆ˜์˜ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ์œ ์ง€ํ•˜๋„๋ก ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” OWNERSHIP์„ ์ œ์™ธํ•œ ๋ชจ๋“  ๊ถŒํ•œ์„ ๊ธฐ์กด ํ•จ์ˆ˜์—์„œ ์ƒˆ ํ•จ์ˆ˜๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ ํ•จ์ˆ˜๋Š” ์Šคํ‚ค๋งˆ์˜ ์˜ค๋ธŒ์ ํŠธ ์œ ํ˜•์— ๋Œ€ํ•ด ์ •์˜๋œ ํ–ฅํ›„ ๋ชจ๋“  ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์ƒ์†ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ, CREATE FUNCTION ๋ฌธ์„ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• ์€ ์ƒˆ ํ•จ์ˆ˜๋ฅผ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ :

  • ๋ฐ์ดํ„ฐ ๊ณต์œ  ์‚ฌ์šฉ ์‹œ, ๊ธฐ์กด ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ๊ณ„์ •์— ๊ณต์œ ๋œ ๊ฒฝ์šฐ ๋Œ€์ฒด ํ•จ์ˆ˜๋„ ๊ณต์œ ๋ฉ๋‹ˆ๋‹ค.

  • ๋Œ€์ฒด ํ•จ์ˆ˜์— ๋Œ€ํ•œ SHOW GRANTS ์ถœ๋ ฅ์—๋Š” CREATE FUNCTION ๋ฌธ์ด ์‹คํ–‰๋  ๋•Œ ํ˜„์žฌ ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ํฌํ•จํ•œ ์ด ๋ฌธ์„ ์‹คํ–‰ํ•œ ์—ญํ• ๋กœ์„œ ๋ณต์‚ฌ๋œ ๊ถŒํ•œ์˜ ํ”ผ๋ถ€์—ฌ์ž๊ฐ€ ๋‚˜์—ด๋ฉ๋‹ˆ๋‹ค.

  • ๊ถŒํ•œ ๋ถ€์—ฌ ๋ณต์‚ฌ ์ž‘์—…์€ CREATE FUNCTION ๋ช…๋ น์—์„œ ์›์ž์ ์œผ๋กœ(์ฆ‰, ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ) ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Javaยถ

PACKAGES = ( 'package_name_and_version' [ , ... ] )

์ข…์† ํ•ญ๋ชฉ์œผ๋กœ ํ•„์š”ํ•œ Snowflake ์‹œ์Šคํ…œ ํŒจํ‚ค์ง€์˜ ์ด๋ฆ„ ๋ฐ ๋ฒ„์ „ ๋ฒˆํ˜ธ. ๊ฐ’์€ package_name:version_number ํ˜•์‹์ด์–ด์•ผ ํ•˜๋ฉฐ, ์—ฌ๊ธฐ์„œ package_name ์€ snowflake_domain:package ์ž…๋‹ˆ๋‹ค. Snowflake๊ฐ€ ์‹œ์Šคํ…œ์—์„œ ์ œ๊ณต๋˜๋Š” ์ตœ์‹  ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๋ ค๋ฉด latest ๋ฅผ ๋ฒ„์ „ ๋ฒˆํ˜ธ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ:

-- Use version 1.2.0 of the Snowpark package.
PACKAGES=('com.snowflake:snowpark:1.2.0')

-- Use the latest version of the Snowpark package.
PACKAGES=('com.snowflake:snowpark:latest')
Copy

Snowflake์—์„œ ๋‹ค์Œ SQL์„ ์‹คํ–‰ํ•˜์—ฌ ์ง€์›๋˜๋Š” ์‹œ์Šคํ…œ ํŒจํ‚ค์ง€ ๋ชฉ๋ก์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'java';
Copy

PACKAGES ๋กœ ์ง€์ •ํ•˜๋Š” ์ข…์†์„ฑ์˜ ๊ฒฝ์šฐ IMPORTS ์ ˆ์— JAR ํŒŒ์ผ๋„ ์ง€์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

์ธ๋ผ์ธ Java

TARGET_PATH = stage_path_and_file_name_to_write

function_definition ์— ์ง€์ •๋œ ์ฒ˜๋ฆฌ๊ธฐ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•œ ๊ฒฐ๊ณผ๊ฐ€ ํฌํ•จ๋œ JAR ํŒŒ์ผ์„ Snowflake๊ฐ€ ์ž‘์„ฑํ•  ์œ„์น˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ด ์ ˆ์ด ํฌํ•จ๋˜๋ฉด Snowflake๋Š” ๊ฒฐ๊ณผ๋ฌผ์ธ JAR ํŒŒ์ผ์„ ์ ˆ์˜ ๊ฐ’์œผ๋กœ ์ง€์ •๋œ ์Šคํ…Œ์ด์ง€ ์œ„์น˜์— ์”๋‹ˆ๋‹ค. ์ด ์ ˆ์„ ์ƒ๋žตํ•  ๊ฒฝ์šฐ Snowflake๋Š” ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ JAR ํŒŒ์ผ์€ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅ๋˜์ง€ ์•Š์œผ๋ฉฐ ์‚ฌ์šฉ์ž๋Š” JAR ํŒŒ์ผ์„ ์ •๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

Snowflake์—์„œ๋Š” TARGET_PATH ๊ฐ€ ๊ธฐ์กด ํŒŒ์ผ๊ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. TARGET_PATH ๋ฅผ ์‚ฌ์šฉํ•ด ๊ธฐ์กด ํŒŒ์ผ์„ ๋ฎ์–ด์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ƒ์„ฑ๋œ JAR ํŒŒ์ผ์€ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ํŒŒ์ผ์„ ์‚ญ์ œํ•˜๋”๋ผ๋„ ๋ช…์‹œ์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์‚ญ์ œํ•  ๋•Œ๊นŒ์ง€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. UDF ๋ฅผ ์‚ญ์ œํ•  ๋•Œ JAR ์€ ๋” ์ด์ƒ UDF ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ JAR ํŒŒ์ผ์„ ๋ณ„๋„๋กœ ์ œ๊ฑฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ TARGET_PATH ์˜ˆ์ œ์—์„œ๋Š” myhandler.jar ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์–ด handlers ์Šคํ…Œ์ด์ง€๋กœ ๋ณต์‚ฌ๋ณธ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

TARGET_PATH = '@handlers/myhandler.jar'
Copy

UDF ๋ฅผ ์ œ๊ฑฐํ•˜๋ ค๋ฉด REMOVE ๋ช…๋ น ์„ ์‹คํ–‰ํ•˜๋Š” ๋“ฑ ํ•ด๋‹น ์ฒ˜๋ฆฌ๊ธฐ JAR ํŒŒ์ผ๋„ ์ œ๊ฑฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

REMOVE @handlers/myhandler.jar;
Copy
EXTERNAL_ACCESS_INTEGRATIONS = ( integration_name [ , ... ] )

์ด ํ•จ์ˆ˜์˜ ์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ๊ฐ€ ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด ํ•„์š”ํ•œ ์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ ์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ์€ ์™ธ๋ถ€ REST API์™€ ๊ฐ™์€ ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ๋ฅผ ์š”์ฒญํ•  ๋•Œ ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์™ธ๋ถ€ ์œ„์น˜ ๋ฐ ์ž๊ฒฉ ์ฆ๋ช…(์žˆ๋Š” ๊ฒฝ์šฐ)์„ ์ง€์ •ํ•˜๋Š” ๋„คํŠธ์›Œํฌ ๊ทœ์น™ ๋ฐ ์‹œํฌ๋ฆฟ ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

SECRETS = ( 'secret_variable_name' = secret_name [ , ...  ] )

์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ์˜ ์‹œํฌ๋ฆฟ์—์„œ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹œํฌ๋ฆฟ์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์‹œํฌ๋ฆฟ ์ด๋ฆ„์„ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์ง€์ •ํ•˜๋Š” ์‹œํฌ๋ฆฟ์€ ์ด CREATE FUNCTION ๋ช…๋ น์˜ EXTERNAL_ACCESS_INTEGRATIONS ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ๊ฐ’์œผ๋กœ ์ง€์ •๋œ ์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ ์—์„œ ํ—ˆ์šฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ๊ฐ’์€ ๋‹ค์Œ ๋ถ€๋ถ„์„ ํฌํ•จํ•œ ํ• ๋‹น ์‹์˜ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋œ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

  • ํ—ˆ์šฉ๋œ ์‹œํฌ๋ฆฟ์˜ ์ด๋ฆ„์ธ secret_name.

    EXTERNAL_ACCESS_INTEGRATIONS ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ง€์ •๋œ ํ†ตํ•ฉ์—๋„ ์‹œํฌ๋ฆฟ์ด ํฌํ•จ๋˜์ง€ ์•Š์€ SECRETS ๊ฐ’์„ ์ง€์ •ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • ์‹œํฌ๋ฆฟ์—์„œ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ๋ณ€์ˆ˜์ธ 'secret_variable_name'.

์˜ˆ๋ฅผ ํฌํ•จํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ•จ์ˆ˜ ๋˜๋Š” ํ”„๋กœ์‹œ์ €์—์„œ ์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ ์‚ฌ์šฉํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Pythonยถ

AGGREGATE

ํ•จ์ˆ˜๊ฐ€ ์ง‘๊ณ„ ํ•จ์ˆ˜์ž„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ ์ง‘๊ณ„ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Python ์‚ฌ์šฉ์ž ์ •์˜ ์ง‘๊ณ„ ํ•จ์ˆ˜ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ฐธ๊ณ 

IMMUTABLE์€ ์ง‘๊ณ„ ํ•จ์ˆ˜์—์„œ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(AGGREGATE ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ). ๋”ฐ๋ผ์„œ ๋ชจ๋“  ์ง‘๊ณ„ ํ•จ์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ VOLATILE์ž…๋‹ˆ๋‹ค.

ARTIFACT_REPOSITORY = repository_name

ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•  PyPI ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

Snowflake๋Š” ์•„ํ‹ฐํŒฉํŠธ ์ด๋ฏธ์ง€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์—์„œ ์ด๋Ÿฌํ•œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

ARTIFACT_REPOSITORY_PACKAGES = ( 'package_name' [ , ... ] )

ํ•จ์ˆ˜์— ์„ค์น˜ํ•˜์—ฌ ์‚ฌ์šฉํ•  ํŒจํ‚ค์ง€์˜ ์ด๋ฆ„ ๋ชฉ๋ก์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

Snowflake๋Š” ์•„ํ‹ฐํŒฉํŠธ ์ด๋ฏธ์ง€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์—์„œ ์ด๋Ÿฌํ•œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

PACKAGES = ( 'package_name_and_version' [ , ... ] )

์ข…์† ํ•ญ๋ชฉ์œผ๋กœ ํ•„์š”ํ•œ ํŒจํ‚ค์ง€์˜ ์ด๋ฆ„ ๋ฐ ๋ฒ„์ „ ๋ฒˆํ˜ธ. ๊ฐ’์€ package_name==version_number ํ˜•์‹์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„์ „ ๋ฒˆํ˜ธ๋ฅผ ์ƒ๋žตํ•  ๊ฒฝ์šฐ Snowflake๋Š” ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ตœ์‹  ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

-- Use version 1.2.2 of the NumPy package.
PACKAGES=('numpy==1.2.2')

-- Use the latest version of the NumPy package.
PACKAGES=('numpy')
Copy

Snowflake์—์„œ ๋‹ค์Œ SQL์„ ์‹คํ–‰ํ•˜์—ฌ ์ง€์›๋˜๋Š” ์‹œ์Šคํ…œ ํŒจํ‚ค์ง€ ๋ชฉ๋ก์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'python';
Copy

ํฌํ•จ๋œ ํŒจํ‚ค์ง€์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์„œ๋“œ ํŒŒํ‹ฐ ํŒจํ‚ค์ง€ ์‚ฌ์šฉํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

EXTERNAL_ACCESS_INTEGRATIONS = ( integration_name [ , ... ] )

์ด ํ•จ์ˆ˜์˜ ์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ๊ฐ€ ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด ํ•„์š”ํ•œ ์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ ์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ์€ ์™ธ๋ถ€ REST API์™€ ๊ฐ™์€ ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ๋ฅผ ์š”์ฒญํ•  ๋•Œ ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์™ธ๋ถ€ ์œ„์น˜ ๋ฐ ์ž๊ฒฉ ์ฆ๋ช…(์žˆ๋Š” ๊ฒฝ์šฐ)์„ ์ง€์ •ํ•˜๋Š” ๋„คํŠธ์›Œํฌ ๊ทœ์น™ ๋ฐ ์‹œํฌ๋ฆฟ ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

SECRETS = ( 'secret_variable_name' = secret_name [ , ...  ] )

์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ์˜ ์‹œํฌ๋ฆฟ์—์„œ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹œํฌ๋ฆฟ์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์‹œํฌ๋ฆฟ ์ด๋ฆ„์„ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์ง€์ •ํ•˜๋Š” ์‹œํฌ๋ฆฟ์€ ์ด CREATE FUNCTION ๋ช…๋ น์˜ EXTERNAL_ACCESS_INTEGRATIONS ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ๊ฐ’์œผ๋กœ ์ง€์ •๋œ ์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ ์—์„œ ํ—ˆ์šฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ๊ฐ’์€ ๋‹ค์Œ ๋ถ€๋ถ„์„ ํฌํ•จํ•œ ํ• ๋‹น ์‹์˜ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋œ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

  • ํ—ˆ์šฉ๋œ ์‹œํฌ๋ฆฟ์˜ ์ด๋ฆ„์ธ secret_name.

    EXTERNAL_ACCESS_INTEGRATIONS ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ง€์ •๋œ ํ†ตํ•ฉ์—๋„ ์‹œํฌ๋ฆฟ์ด ํฌํ•จ๋˜์ง€ ์•Š์€ SECRETS ๊ฐ’์„ ์ง€์ •ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • ์‹œํฌ๋ฆฟ์—์„œ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ๋ณ€์ˆ˜์ธ 'secret_variable_name'.

์˜ˆ๋ฅผ ํฌํ•จํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ•จ์ˆ˜ ๋˜๋Š” ํ”„๋กœ์‹œ์ €์—์„œ ์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ ์‚ฌ์šฉํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

SQLยถ

MEMOIZABLE

ํ•จ์ˆ˜๊ฐ€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๊ฐ€๋Šฅ UDF ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Scalaยถ

PACKAGES = ( 'package_name_and_version' [ , ... ] )

์ข…์† ํ•ญ๋ชฉ์œผ๋กœ ํ•„์š”ํ•œ Snowflake ์‹œ์Šคํ…œ ํŒจํ‚ค์ง€์˜ ์ด๋ฆ„ ๋ฐ ๋ฒ„์ „ ๋ฒˆํ˜ธ. ๊ฐ’์€ package_name:version_number ํ˜•์‹์ด์–ด์•ผ ํ•˜๋ฉฐ, ์—ฌ๊ธฐ์„œ package_name ์€ snowflake_domain:package ์ž…๋‹ˆ๋‹ค. Snowflake๊ฐ€ ์‹œ์Šคํ…œ์—์„œ ์ œ๊ณต๋˜๋Š” ์ตœ์‹  ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๋ ค๋ฉด latest ๋ฅผ ๋ฒ„์ „ ๋ฒˆํ˜ธ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ:

-- Use version 1.7.0 of the Snowpark package.
PACKAGES=('com.snowflake:snowpark:1.7.0')

-- Use the latest version of the Snowpark package.
PACKAGES=('com.snowflake:snowpark:latest')
Copy

Snowflake์—์„œ ๋‹ค์Œ SQL์„ ์‹คํ–‰ํ•˜์—ฌ ์ง€์›๋˜๋Š” ์‹œ์Šคํ…œ ํŒจํ‚ค์ง€ ๋ชฉ๋ก์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'scala';
Copy

PACKAGES ๋กœ ์ง€์ •ํ•˜๋Š” ์ข…์†์„ฑ์˜ ๊ฒฝ์šฐ IMPORTS ์ ˆ์— JAR ํŒŒ์ผ๋„ ์ง€์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

TARGET_PATH = stage_path_and_file_name_to_write

function_definition ์— ์ง€์ •๋œ ์ฒ˜๋ฆฌ๊ธฐ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•œ ๊ฒฐ๊ณผ๊ฐ€ ํฌํ•จ๋œ JAR ํŒŒ์ผ์„ Snowflake๊ฐ€ ์ž‘์„ฑํ•  ์œ„์น˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ด ์ ˆ์ด ํฌํ•จ๋˜๋ฉด Snowflake๋Š” ๊ฒฐ๊ณผ๋ฌผ์ธ JAR ํŒŒ์ผ์„ ์ ˆ์˜ ๊ฐ’์œผ๋กœ ์ง€์ •๋œ ์Šคํ…Œ์ด์ง€ ์œ„์น˜์— ์”๋‹ˆ๋‹ค. ์ด ์ ˆ์„ ์ƒ๋žตํ•  ๊ฒฝ์šฐ Snowflake๋Š” ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ JAR ํŒŒ์ผ์€ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅ๋˜์ง€ ์•Š์œผ๋ฉฐ ์‚ฌ์šฉ์ž๋Š” JAR ํŒŒ์ผ์„ ์ •๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

Snowflake์—์„œ๋Š” TARGET_PATH ๊ฐ€ ๊ธฐ์กด ํŒŒ์ผ๊ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. TARGET_PATH ๋ฅผ ์‚ฌ์šฉํ•ด ๊ธฐ์กด ํŒŒ์ผ์„ ๋ฎ์–ด์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ƒ์„ฑ๋œ JAR ํŒŒ์ผ์€ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ํŒŒ์ผ์„ ์‚ญ์ œํ•˜๋”๋ผ๋„ ๋ช…์‹œ์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์‚ญ์ œํ•  ๋•Œ๊นŒ์ง€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. UDF ๋ฅผ ์‚ญ์ œํ•  ๋•Œ JAR ์€ ๋” ์ด์ƒ UDF ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ JAR ํŒŒ์ผ์„ ๋ณ„๋„๋กœ ์ œ๊ฑฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ TARGET_PATH ์˜ˆ์ œ์—์„œ๋Š” myhandler.jar ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์–ด handlers ์Šคํ…Œ์ด์ง€๋กœ ๋ณต์‚ฌ๋ณธ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

TARGET_PATH = '@handlers/myhandler.jar'
Copy

UDF ๋ฅผ ์ œ๊ฑฐํ•˜๋ ค๋ฉด REMOVE ๋ช…๋ น ์„ ์‹คํ–‰ํ•˜๋Š” ๋“ฑ ํ•ด๋‹น ์ฒ˜๋ฆฌ๊ธฐ JAR ํŒŒ์ผ๋„ ์ œ๊ฑฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

REMOVE @handlers/myhandler.jar;
Copy

์•ก์„ธ์Šค ์ œ์–ด ์š”๊ตฌ ์‚ฌํ•ญยถ

์ด ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์—ญํ•  ์—๋Š” ์ตœ์†Œํ•œ ๋‹ค์Œ ๊ถŒํ•œ ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ถŒํ•œ

์˜ค๋ธŒ์ ํŠธ

์ฐธ๊ณ 

CREATE FUNCTION

์Šคํ‚ค๋งˆ

์ด ๊ถŒํ•œ์œผ๋กœ๋งŒ ์Šคํ‚ค๋งˆ์—์„œ ์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜๋งŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ๋ฉ”ํŠธ๋ฆญ ํ•จ์ˆ˜ ์ƒ์„ฑ์„ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด ์—ญํ• ์— CREATE DATA METRIC FUNCTION ๊ถŒํ•œ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

USAGE

ํ•จ์ˆ˜

์ƒˆ๋กœ ์ƒ์„ฑํ•œ ํ•จ์ˆ˜์— ๋Œ€ํ•œ USAGE ๊ถŒํ•œ์„ ์—ญํ• ์— ๋ถ€์—ฌํ•˜๋ฉด ํ•ด๋‹น ์—ญํ• (์˜ˆ: ์™ธ๋ถ€ ํ† ํฐํ™”์— ๋Œ€ํ•œ ๋งˆ์Šคํ‚น ์ •์ฑ… ์†Œ์œ ์ž ์—ญํ• )์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž๊ฐ€ Snowflake์˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

USAGE

์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ

ํ†ตํ•ฉ(์žˆ๋Š” ๊ฒฝ์šฐ)์— ํ•„์š”ํ•˜๋ฉฐ, EXTERNAL_ACCESS_INTEGRATIONS ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ง€์ •๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ CREATE EXTERNAL ACCESS INTEGRATION ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

READ

์‹œํฌ๋ฆฟ

SECRETS ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ง€์ •๋œ ์‹œํฌ๋ฆฟ(์žˆ๋Š” ๊ฒฝ์šฐ)์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ž๊ฒฉ ์ฆ๋ช…์„ ๋‚˜ํƒ€๋‚ด๋Š” ์‹œํฌ๋ฆฟ ๋งŒ๋“ค๊ธฐ ๋ฐ ํ•จ์ˆ˜ ๋˜๋Š” ํ”„๋กœ์‹œ์ €์—์„œ ์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ ์‚ฌ์šฉํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

USAGE

์Šคํ‚ค๋งˆ

SECRETS ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ง€์ •๋œ ์‹œํฌ๋ฆฟ์ด ํฌํ•จ๋œ ์Šคํ‚ค๋งˆ(์žˆ๋Š” ๊ฒฝ์šฐ)์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ž๊ฒฉ ์ฆ๋ช…์„ ๋‚˜ํƒ€๋‚ด๋Š” ์‹œํฌ๋ฆฟ ๋งŒ๋“ค๊ธฐ ๋ฐ ํ•จ์ˆ˜ ๋˜๋Š” ํ”„๋กœ์‹œ์ €์—์„œ ์™ธ๋ถ€ ์•ก์„ธ์Šค ํ†ตํ•ฉ ์‚ฌ์šฉํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์Šคํ‚ค๋งˆ์˜ ๋ชจ๋“  ์˜ค๋ธŒ์ ํŠธ์— ๋Œ€ํ•ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ์ƒ์œ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ ์Šคํ‚ค๋งˆ์— ๋Œ€ํ•œ USAGE ๊ถŒํ•œ.

์ง€์ •๋œ ๊ถŒํ•œ ์„ธํŠธ๋กœ ์‚ฌ์šฉ์ž ์ง€์ • ์—ญํ• ์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ง€์นจ์€ ์‚ฌ์šฉ์ž ์ง€์ • ์—ญํ•  ๋งŒ๋“ค๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋ณด์•ˆ ์˜ค๋ธŒ์ ํŠธ ์— ๋Œ€ํ•ด SQL ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์—ญํ• ๊ณผ ๊ถŒํ•œ ๋ถ€์—ฌ์— ๋Œ€ํ•œ ์ผ๋ฐ˜์ ์ธ ์ •๋ณด๋Š” ์•ก์„ธ์Šค ์ œ์–ด์˜ ๊ฐœ์š” ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ๋ฒ• ๋…ธํŠธยถ

๋ชจ๋“  ์–ธ์–ดยถ

  • function_definition ์—๋Š” ํฌ๊ธฐ ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์ตœ๋Œ€ ํฌ๊ธฐ๋Š” ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • function_definition ์ฃผ์œ„์˜ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๋Š” ์ž‘์€๋”ฐ์˜ดํ‘œ ๋˜๋Š” ํ•œ ์Œ์˜ ๋‹ฌ๋Ÿฌ ๊ธฐํ˜ธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    $$ ๋ฅผ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ž‘์€๋”ฐ์˜ดํ‘œ๊ฐ€ ํฌํ•จ๋œ ํ•จ์ˆ˜๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ํ•จ์ˆ˜ ๋ณธ๋ฌธ์˜ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๊ฐ€ ์ž‘์€๋”ฐ์˜ดํ‘œ ๋ฌธ์ž์ธ ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ function_definition ๋‚ด์˜ ๋ชจ๋“  ์ž‘์€๋”ฐ์˜ดํ‘œ(์˜ˆ: ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด)๋ฅผ ์ž‘์€๋”ฐ์˜ดํ‘œ๋กœ ์ด์Šค์ผ€์ดํ”„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ๋งˆ์Šคํ‚น ์ •์ฑ… ์—์„œ UDF๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์—ด์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…, UDF, ๋งˆ์Šคํ‚น ์ •์ฑ…์ด ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋งˆ์Šคํ‚น ์ •์ฑ…์˜ ์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • UDF์˜ ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ์— CURRENT_DATABASE ๋˜๋Š” CURRENT_SCHEMA ํ•จ์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋ฉด ํ•จ์ˆ˜๋Š” ์„ธ์…˜์— ์‚ฌ์šฉ ์ค‘์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋˜๋Š” ์Šคํ‚ค๋งˆ๊ฐ€ ์•„๋‹ˆ๋ผ UDF๊ฐ€ ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋˜๋Š” ์Šคํ‚ค๋งˆ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ด€๋ จ:

    ์ฃผ์˜

    ๊ณ ๊ฐ์€ Snowflake ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐœ์ธ ๋ฐ์ดํ„ฐ(์‚ฌ์šฉ์ž ์˜ค๋ธŒ์ ํŠธ ์ œ์™ธ), ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ, ์ˆ˜์ถœ ํ†ต์ œ ๋Œ€์ƒ ๋ฐ์ดํ„ฐ ๋˜๋Š” ๊ธฐํƒ€ ๊ทœ์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋กœ ์ž…๋ ฅ๋˜์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Snowflake์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ•„๋“œ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • OR REPLACE ๋ฐ IF NOT EXISTS ์ ˆ์€ ์ƒํ˜ธ ๋ฐฐํƒ€์ ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฌธ์ž๋ฅผ ๊ฐ™์€ ๋ฌธ์— ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • CREATE OR REPLACE <์˜ค๋ธŒ์ ํŠธ> ๋ฌธ์€ ์›์ž์„ฑ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋ฐ”๋€” ๋•Œ ๋‹จ์ผ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ด์ „ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์‚ญ์ œ๋˜๊ณ  ์ƒˆ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

Javaยถ

  • Java์—์„œ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ NULL ๊ฐ’์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ์ธ์ž์— ๋Œ€ํ•ด NULL์„ ์ „๋‹ฌํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • HANDLER ์ ˆ์—์„œ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

  • IMPORTS ๋ฐ TARGET_PATH ์ ˆ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    • ํŒจํ‚ค์ง€, ํด๋ž˜์Šค ๋ฐ ํŒŒ์ผ ์ด๋ฆ„์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

    • ์Šคํ…Œ์ด์ง€ ์ด๋ฆ„์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • PACKAGES ์ ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ Snowflake ์‹œ์Šคํ…œ ์ •์˜ ์ข…์†์„ฑ์— ๋Œ€ํ•œ ํŒจํ‚ค์ง€ ์ด๋ฆ„๊ณผ ๋ฒ„์ „ ๋ฒˆํ˜ธ(์˜ˆ: Snowpark์˜ ํŒจํ‚ค์ง€ ์ด๋ฆ„๊ณผ ๋ฒ„์ „ ๋ฒˆํ˜ธ)๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ข…์† ํ•ญ๋ชฉ์˜ ๊ฒฝ์šฐ IMPORTS ์ ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ข…์† ํ•ญ๋ชฉ JAR ํŒŒ์ผ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

  • Snowflake๋Š” ๋‹ค์Œ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.

    • CREATE FUNCTION ๋ฌธ์˜ HANDLER์— ์ง€์ •๋œ JAR ํŒŒ์ผ์ด ์กด์žฌํ•˜๊ณ  ์ด ํŒŒ์ผ์—๋Š” ์ง€์ •๋œ ํด๋ž˜์Šค์™€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

    • UDF ์„ ์–ธ์— ์ง€์ •๋œ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ์œ ํ˜•์€ Java ๋ฉ”์„œ๋“œ์˜ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ์œ ํ˜•๊ณผ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค.

    ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋Š” ํ™œ๋™ ์ค‘์ธ Snowflake ์›จ์–ดํ•˜์šฐ์Šค์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์ƒ์„ฑ ์‹œ ๋˜๋Š” ์‹คํ–‰ ์‹œ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์ƒ์„ฑ ์‹œ๊ฐ„ โ€” CREATE FUNCTION ๋ฌธ์ด ์‹คํ–‰๋  ๋•Œ ํ™œ์„ฑ ์ƒํƒœ์ธ Snowflake ์›จ์–ดํ•˜์šฐ์Šค์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฉด UDF ๋Š” ์ƒ์„ฑ ์‹œ์ ์— ์œ ํšจ์„ฑ์ด ๊ฒ€์‚ฌ๋ฉ๋‹ˆ๋‹ค.

    • ์‹คํ–‰ ์‹œ๊ฐ„ โ€” ํ™œ๋™ ์ค‘์ธ Snowflake ์›จ์–ดํ•˜์šฐ์Šค์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ UDF ๊ฐ€ ์ƒ์„ฑ๋˜์ง€๋งŒ ์ฆ‰์‹œ ์œ ํšจ์„ฑ์ด ๊ฒ€์‚ฌ๋˜์ง€ ์•Š์œผ๋ฉฐ, Snowflake๋Š” ๋‹ค์Œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

      Function <์ด๋ฆ„> created successfully, but could not be validated since there is no active warehouse

JavaScriptยถ

  • Snowflake๋Š” UDF ์ƒ์„ฑ ์‹œ์ ์—๋Š” JavaScript ์ฝ”๋“œ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ฝ”๋“œ๊ฐ€ ์œ ํšจํ•œ์ง€ ์—ฌ๋ถ€์— ๊ด€๊ณ„์—†์ด UDF ์ƒ์„ฑ์€ ์„ฑ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด ์ฟผ๋ฆฌ ์‹œ UDF ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ Snowflake๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Pythonยถ

  • HANDLER ์ ˆ์—์„œ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜ ์ด๋ฆ„์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

  • IMPORTS ์ ˆ์—์„œ:

    • ํŒŒ์ผ ์ด๋ฆ„์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

    • ์Šคํ…Œ์ด์ง€ ์ด๋ฆ„์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • PACKAGES ์ ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ข…์†์„ฑ์— ๋Œ€ํ•œ ํŒจํ‚ค์ง€ ์ด๋ฆ„๊ณผ ๋ฒ„์ „ ๋ฒˆํ˜ธ(์˜ˆ: Snowpark์˜ ํŒจํ‚ค์ง€)๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ข…์† ํ•ญ๋ชฉ์˜ ๊ฒฝ์šฐ IMPORTS ์ ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ข…์† ํ•ญ๋ชฉ ํŒŒ์ผ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

  • Snowflake๋Š” ๋‹ค์Œ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.

    • CREATE FUNCTION ๋ฌธ์˜ HANDLER์— ์ง€์ •๋œ ํ•จ์ˆ˜ ๋˜๋Š” ํด๋ž˜์Šค๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

    • UDF ์„ ์–ธ์— ์ง€์ •๋œ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ์œ ํ˜•์€ ํ•ธ๋“ค๋Ÿฌ์˜ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ์œ ํ˜•๊ณผ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค.

Scalaยถ

  • HANDLER ์ ˆ์—์„œ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

  • IMPORTS ๋ฐ TARGET_PATH ์ ˆ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    • ํŒจํ‚ค์ง€, ํด๋ž˜์Šค ๋ฐ ํŒŒ์ผ ์ด๋ฆ„์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

    • ์Šคํ…Œ์ด์ง€ ์ด๋ฆ„์€ ๋Œ€/์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • PACKAGES ์ ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ Snowflake ์‹œ์Šคํ…œ ์ •์˜ ์ข…์†์„ฑ์— ๋Œ€ํ•œ ํŒจํ‚ค์ง€ ์ด๋ฆ„๊ณผ ๋ฒ„์ „ ๋ฒˆํ˜ธ(์˜ˆ: Snowpark์˜ ํŒจํ‚ค์ง€ ์ด๋ฆ„๊ณผ ๋ฒ„์ „ ๋ฒˆํ˜ธ)๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ข…์† ํ•ญ๋ชฉ์˜ ๊ฒฝ์šฐ IMPORTS ์ ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ข…์† ํ•ญ๋ชฉ JAR ํŒŒ์ผ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

  • Snowflake๋Š” ๋‹ค์Œ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.

    • CREATE FUNCTION ๋ฌธ์˜ HANDLER์— ์ง€์ •๋œ JAR ํŒŒ์ผ์ด ์กด์žฌํ•˜๊ณ  ์ด ํŒŒ์ผ์—๋Š” ์ง€์ •๋œ ํด๋ž˜์Šค์™€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

    • UDF ์„ ์–ธ์— ์ง€์ •๋œ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ์œ ํ˜•์€ Scala ๋ฉ”์„œ๋“œ์˜ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ์œ ํ˜•๊ณผ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค.

    ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋Š” ํ™œ๋™ ์ค‘์ธ Snowflake ์›จ์–ดํ•˜์šฐ์Šค์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์ƒ์„ฑ ์‹œ ๋˜๋Š” ์‹คํ–‰ ์‹œ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์ƒ์„ฑ ์‹œ๊ฐ„ โ€” CREATE FUNCTION ๋ฌธ์ด ์‹คํ–‰๋  ๋•Œ ํ™œ์„ฑ ์ƒํƒœ์ธ Snowflake ์›จ์–ดํ•˜์šฐ์Šค์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฉด UDF ๋Š” ์ƒ์„ฑ ์‹œ์ ์— ์œ ํšจ์„ฑ์ด ๊ฒ€์‚ฌ๋ฉ๋‹ˆ๋‹ค.

    • ์‹คํ–‰ ์‹œ๊ฐ„ โ€” ํ™œ๋™ ์ค‘์ธ Snowflake ์›จ์–ดํ•˜์šฐ์Šค์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ UDF ๊ฐ€ ์ƒ์„ฑ๋˜์ง€๋งŒ ์ฆ‰์‹œ ์œ ํšจ์„ฑ์ด ๊ฒ€์‚ฌ๋˜์ง€ ์•Š์œผ๋ฉฐ, Snowflake๋Š” ๋‹ค์Œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

      Function <์ด๋ฆ„> created successfully, but could not be validated since there is no active warehouse

SQLยถ

  • ํ˜„์žฌ, NOT NULL ์ ˆ์€ SQL UDF์— ๋Œ€ํ•ด ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

CREATE OR ALTER FUNCTION ์‚ฌ์šฉ๋ฒ• ๋…ธํŠธยถ

  • ALTER FUNCTION ๋ช…๋ น์˜ ๋ชจ๋“  ์ œํ•œ ์‚ฌํ•ญ์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • FUNCTION ์„ PROCEDURE ๋กœ ๋ฐ”๊พธ๊ฑฐ๋‚˜ PROCEDURE ๋ฅผ FUNCTION ์œผ๋กœ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ๋ณ€ํ˜•ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • ์ž„์‹œ FUNCTION ์„ ์ž„์‹œ๊ฐ€ ์•„๋‹Œ FUNCTION ์œผ๋กœ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ์ž„์‹œ๊ฐ€ ์•„๋‹Œ FUNCTION ์„ ์ž„์‹œ FUNCTION ์œผ๋กœ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • ์ผ๋ฐ˜ FUNCTION ์„ EXTERNAL FUNCTION ์œผ๋กœ ๋ฐ”๊พธ๊ฑฐ๋‚˜ EXTERNAL FUNCTION ์„ ์ผ๋ฐ˜ FUNCTION ์œผ๋กœ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ๋ณ€ํ˜•ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • LANGUAGE, IMPORTS, RETURNS, HANDLER, RUNTIME_VERSION, PACKAGES, VOLATILITY, NULL_HANDLING, TARGET_PATH ์†์„ฑ์˜ ๋ณ€๊ฒฝ์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ํƒœ๊ทธ ์„ค์ • ๋˜๋Š” ์„ค์ • ํ•ด์ œ๋Š” ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ํƒœ๊ทธ๋Š” CREATE OR ALTER FUNCTION ๋ฌธ์— ์˜ํ•ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฉฐ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

์˜ˆยถ

Javaยถ

๋‹ค์Œ์€ ์ธ๋ผ์ธ ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ์žˆ๋Š” CREATE FUNCTION์˜ ๊ธฐ๋ณธ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค.

CREATE OR REPLACE FUNCTION echo_varchar(x VARCHAR)
  RETURNS VARCHAR
  LANGUAGE JAVA
  CALLED ON NULL INPUT
  HANDLER = 'TestFunc.echoVarchar'
  TARGET_PATH = '@~/testfunc.jar'
  AS
  'class TestFunc {
    public static String echoVarchar(String x) {
      return x;
    }
  }';
Copy

๋‹ค์Œ์€ ์Šคํ…Œ์ด์ง•๋œ ์ฒ˜๋ฆฌ๊ธฐ์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š” CREATE FUNCTION์˜ ๊ธฐ๋ณธ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค.

create function my_decrement_udf(i numeric(9, 0))
    returns numeric
    language java
    imports = ('@~/my_decrement_udf_package_dir/my_decrement_udf_jar.jar')
    handler = 'my_decrement_udf_package.my_decrement_udf_class.my_decrement_udf_method'
    ;
Copy

Java UDFs์˜ ๋” ๋งŽ์€ ์˜ˆ๋Š” ์˜ˆ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

JavaScriptยถ

js_factorial ๋กœ ๋ช…๋ช…๋œ JavaScript UDF ๋งŒ๋“ค๊ธฐ:

CREATE OR REPLACE FUNCTION js_factorial(d double)
  RETURNS double
  LANGUAGE JAVASCRIPT
  STRICT
  AS '
  if (D <= 0) {
    return 1;
  } else {
    var result = 1;
    for (var i = 2; i <= D; i++) {
      result = result * i;
    }
    return result;
  }
  ';
Copy

Pythonยถ

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ๊ฐ€ udf ๋กœ ์ธ๋ผ์ธ์ธ py_udf ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

CREATE OR REPLACE FUNCTION py_udf()
  RETURNS VARIANT
  LANGUAGE PYTHON
  RUNTIME_VERSION = '3.10'
  PACKAGES = ('numpy','pandas','xgboost==1.5.0')
  HANDLER = 'udf'
AS $$
import numpy as np
import pandas as pd
import xgboost as xgb
def udf():
    return [np.__version__, pd.__version__, xgb.__version__]
$$;
Copy

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” @my_stage ์Šคํ…Œ์ด์ง€์— ์žˆ๋Š” sleepy.py ํŒŒ์ผ์— ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์žˆ๋Š” dream ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

CREATE OR REPLACE FUNCTION dream(i int)
  RETURNS VARIANT
  LANGUAGE PYTHON
  RUNTIME_VERSION = '3.10'
  HANDLER = 'sleepy.snore'
  IMPORTS = ('@my_stage/sleepy.py')
Copy

Scalaยถ

๋‹ค์Œ์€ ์ธ๋ผ์ธ ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ์žˆ๋Š” CREATE FUNCTION์˜ ๊ธฐ๋ณธ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค.

CREATE OR REPLACE FUNCTION echo_varchar(x VARCHAR)
  RETURNS VARCHAR
  LANGUAGE SCALA
  RUNTIME_VERSION = 2.12
  HANDLER='Echo.echoVarchar'
  AS
  $$
  class Echo {
    def echoVarchar(x : String): String = {
      return x
    }
  }
  $$;
Copy

๋‹ค์Œ์€ ์Šคํ…Œ์ด์ง•๋œ ์ฒ˜๋ฆฌ๊ธฐ์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š” CREATE FUNCTION์˜ ๊ธฐ๋ณธ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค.

CREATE OR REPLACE FUNCTION echo_varchar(x VARCHAR)
  RETURNS VARCHAR
  LANGUAGE SCALA
  RUNTIME_VERSION = 2.12
  IMPORTS = ('@udf_libs/echohandler.jar')
  HANDLER='Echo.echoVarchar';
Copy

Scala UDF์˜ ๋” ๋งŽ์€ ์˜ˆ๋Š” Scala UDF ์ฒ˜๋ฆฌ๊ธฐ์˜ ์˜ˆ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

SQLยถ

์ˆ˜ํ•™ ์ƒ์ˆ˜ pi์˜ ํ•˜๋“œ ์ฝ”๋“œ๋œ ๊ทผ์‚ฌ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ„๋‹จํ•œ SQL ์Šค์นผ๋ผ UDF ๋งŒ๋“ค๊ธฐ:

CREATE FUNCTION pi_udf()
  RETURNS FLOAT
  AS '3.141592654::FLOAT'
  ;
Copy

ํ•˜๋“œ ์ฝ”๋“œ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ„๋‹จํ•œ SQL ํ…Œ์ด๋ธ” UDF ๋งŒ๋“ค๊ธฐ:

CREATE FUNCTION simple_table_function ()
  RETURNS TABLE (x INTEGER, y INTEGER)
  AS
  $$
    SELECT 1, 2
    UNION ALL
    SELECT 3, 4
  $$
  ;
Copy
SELECT * FROM TABLE(simple_table_function());
Copy

์ถœ๋ ฅ:

SELECT * FROM TABLE(simple_table_function());
+---+---+
| X | Y |
|---+---|
| 1 | 2 |
| 3 | 4 |
+---+---+
Copy

์—ฌ๋Ÿฌ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ํ—ˆ์šฉํ•˜๋Š” UDF ๋งŒ๋“ค๊ธฐ:

CREATE FUNCTION multiply1 (a number, b number)
  RETURNS number
  COMMENT='multiply two numbers'
  AS 'a * b';
Copy

์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  get_countries_for_user ๋กœ ๋ช…๋ช…๋œ SQL ํ…Œ์ด๋ธ” UDF ๋งŒ๋“ค๊ธฐ:

CREATE OR REPLACE FUNCTION get_countries_for_user ( id NUMBER )
  RETURNS TABLE (country_code CHAR, country_name VARCHAR)
  AS 'SELECT DISTINCT c.country_code, c.country_name
      FROM user_addresses a, countries c
      WHERE a.user_id = id
      AND c.country_code = a.country_code';
Copy

CREATE OR ALTER FUNCTION ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹คยถ

๋‘ ๊ฐœ์˜ ์ˆซ์ž๋ฅผ ํ—ˆ์šฉํ•˜๋Š” multiply ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

CREATE OR ALTER FUNCTION multiply(a NUMBER, b NUMBER)
  RETURNS NUMBER
  AS 'a * b';
Copy

multiply ๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ์„ค๋ช…์„ ์ถ”๊ฐ€ํ•˜๊ณ  ํ•จ์ˆ˜๋ฅผ ๋ณด์•ˆ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

CREATE OR ALTER SECURE FUNCTION multiply(a NUMBER, b NUMBER)
  RETURNS NUMBER
  COMMENT = 'Multiply two numbers.'
  AS 'a * b';
Copy