UDF 호출하기

사용자 정의 함수(UDF) 또는 사용자 정의 테이블 함수(UDTF)는 다른 함수를 호출하는 것과 동일한 방식으로 호출할 수 있습니다.

UDF 호출하기

일반적으로 다른 함수를 호출하는 것과 동일한 방식으로 UDF를 호출합니다.

UDF에 인자가 있는 경우 해당 인자를 이름 또는 위치로 지정할 수 있습니다.

예를 들어 다음 UDF는 3개의 인자를 허용합니다.

CREATE OR REPLACE FUNCTION udf_concatenate_strings(
    first_arg VARCHAR,
    second_arg VARCHAR,
    third_arg VARCHAR)
  RETURNS VARCHAR
  LANGUAGE SQL
  AS
  $$
    SELECT first_arg || second_arg || third_arg
  $$;
Copy

UDF를 호출할 때 인자를 이름으로 지정할 수 있습니다.

SELECT udf_concatenate_strings(
  first_arg => 'one',
  second_arg => 'two',
  third_arg => 'three');
Copy
+--------------------------+
| UDF_CONCATENATE_STRINGS( |
|   FIRST_ARG => 'ONE',    |
|   SECOND_ARG => 'TWO',   |
|   THIRD_ARG => 'THREE')  |
|--------------------------|
| onetwothree              |
+--------------------------+

인자를 이름으로 지정하면 인자를 특정 순서로 지정할 필요가 없습니다.

SELECT udf_concatenate_strings(
  third_arg => 'three',
  first_arg => 'one',
  second_arg => 'two');
Copy
+--------------------------+
| UDF_CONCATENATE_STRINGS( |
|   THIRD_ARG => 'THREE',  |
|   FIRST_ARG => 'ONE',    |
|   SECOND_ARG => 'TWO')   |
|--------------------------|
| onetwothree              |
+--------------------------+

인자를 위치로 지정할 수도 있습니다.

SELECT udf_concatenate_strings(
  'one',
  'two',
  'three');
Copy
+--------------------------+
| UDF_CONCATENATE_STRINGS( |
|   'ONE',                 |
|   'TWO',                 |
|   'THREE')               |
|--------------------------|
| onetwothree              |
+--------------------------+

다음 사항을 참고하십시오.

  • 이름 또는 위치로 모든 인자를 지정해야 합니다. 일부 인자는 이름으로, 다른 인자는 위치로 지정할 수는 없습니다.

    이름으로 인자를 지정할 때 인자 이름 주위에 큰따옴표를 사용할 수 없습니다.

  • 두 함수 또는 두 프로시저가 이름은 같지만 인자 유형이 다른 경우 인자 이름이 다르면 인자 이름을 사용하여 실행할 함수 또는 프로시저를 지정할 수 있습니다. 프로시저 및 함수 오버로딩하기 섹션을 참조하십시오.

선택적 인자가 있는 UDF 호출하기

UDF에 선택적 인자 가 있는 경우 호출에서 선택적 인자를 생략할 수 있습니다. 각 선택적 인자에는 인자가 생략될 때 사용되는 기본값이 있습니다.

예를 들어 다음 UDF는 필수 인자 1개와 선택적 인자 2개가 있습니다. 각 선택적 인자에는 기본값이 있습니다.

CREATE OR REPLACE FUNCTION build_string_udf(
    word VARCHAR,
    prefix VARCHAR DEFAULT 'pre-',
    suffix VARCHAR DEFAULT '-post'
  )
  RETURNS VARCHAR
  AS
  $$
    SELECT prefix || word || suffix
  $$
  ;
Copy

호출에서 선택적 인자를 생략할 수 있습니다. 인자를 생략하면 인자의 기본값이 사용됩니다.

SELECT build_string_udf('hello');
Copy
+---------------------------+
| BUILD_STRING_UDF('HELLO') |
|---------------------------|
| pre-hello-post            |
+---------------------------+
SELECT build_string_udf('hello', 'before-');
Copy
+--------------------------------------+
| BUILD_STRING_UDF('HELLO', 'BEFORE-') |
|--------------------------------------|
| before-hello-post                    |
+--------------------------------------+

선택적 인자를 생략하고 서명에서 생략된 인자 뒤에 나타나는 다른 선택적 인자를 지정해야 하는 경우 위치 인자 대신 명명된 인자를 사용하십시오.

예를 들어 prefix 인자를 생략하고 suffix 인자를 지정한다고 가정해 보겠습니다. suffix 인자는 서명에서 prefix 뒤에 나타나므로 인자를 이름으로 지정해야 합니다.

SELECT build_string_udf(word => 'hello', suffix => '-after');
Copy
+-------------------------------------------------------+
| BUILD_STRING_UDF(WORD => 'HELLO', SUFFIX => '-AFTER') |
|-------------------------------------------------------|
| pre-hello-after                                       |
+-------------------------------------------------------+

UDTF 호출하기

테이블 함수를 호출하는 방식으로 UDTF를 호출할 수 있습니다. 기본 제공 테이블 함수 를 호출할 때와 마찬가지로, 쿼리의 FROM 절에서 UDTF를 호출할 때 TABLE 키워드 다음에 오는 괄호 안에 UDTF의 이름과 인자를 지정합니다.

즉, UDTF를 호출할 때 TABLE 키워드에 대해 다음과 같은 양식을 사용합니다.

SELECT ...
  FROM TABLE ( udtf_name (udtf_arguments) )
Copy

다음 예제의 코드는 '2021-01-16'::DATE 인자에 DATE 리터럴을 지정하여 my_java_udtf 테이블 함수를 호출합니다.

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

테이블 함수에 대한 인자는 리터럴이 아니라 식일 수 있습니다. 예를 들어, 테이블의 열을 사용하여 테이블 함수를 호출할 수 있습니다. 예 섹션 을 포함하여 몇 가지 예가 아래에 나와 있습니다.

UDF 호출 의 경우와 마찬가지로, 이름 또는 위치로 인자를 지정할 수 있습니다.

일반적인 테이블 함수에 대한 자세한 내용은 테이블 함수 를 참조하십시오.

참고

CREATE TABLE 문의 DEFAULT 절 내에서 UDF를 호출할 수 없습니다.

테이블 또는 UDTF를 UDTF에 대한 입력으로 사용하기

테이블 함수에 대한 입력은 테이블을 테이블 함수에 대한 입력으로 사용하기 에 설명된 대로 테이블 또는 다른 UDTF에서 올 수 있습니다.

아래 예는 테이블을 사용하여 UDTF split_file_into_words 에 입력을 제공하는 방법을 보여줍니다.

create table file_names (file_name varchar);
insert into file_names (file_name) values ('sample.txt'),
                                          ('sample_2.txt');

select f.file_name, w.word
   from file_names as f, table(split_file_into_words(f.file_name)) as w;
Copy

출력은 다음과 유사합니다.

+-------------------+------------+
| FILE_NAME         | WORD       |
+-------------------+------------+
| sample_data.txt   | some       |
| sample_data.txt   | words      |
| sample_data_2.txt | additional |
| sample_data_2.txt | words      |
+-------------------+------------+
Copy

UDTF의 IMPORTS 절은 UDTF에 전달된 파일의 이름과 경로를 지정해야 합니다. 예:

create function split_file_into_words(inputFileName string)
    ...
    imports = ('@inline_jars/sample.txt', '@inline_jars/sample_2.txt')
    ...
Copy

UDTF가 파일을 읽기 전에 각 파일이 이미 스테이지(이 경우 @inline_jars 라는 스테이지)에 복사되어 있어야 합니다.

UDTF를 다른 UDTF에 대한 입력으로 사용하는 예는 JavaScript UDTF 설명서에서 테이블 값 및 기타 UDTF를 입력으로 사용하는 확장된 예 섹션을 참조하십시오.

테이블 함수 및 파티션

행이 테이블 함수에 전달되기 전에 행을 파티션 으로 그룹화할 수 있습니다. 분할에는 다음과 같은 두 가지 주요 이점이 있습니다.

  • 분할을 통해 Snowflake는 워크로드를 분할하여 병렬 처리를 개선해 성능을 높일 수 있습니다.

  • 분할을 통해 Snowflake는 공통 특성을 가진 모든 행을 그룹으로 처리할 수 있습니다. 개별 행뿐만 아니라 그룹의 모든 행을 기반으로 하는 결과를 반환할 수 있습니다.

예를 들어, 주가 데이터를 주식당 하나의 그룹으로 분할할 수 있습니다. 개별 회사의 모든 주가를 함께 분석할 수 있는 한편, 각 회사의 주가는 다른 회사와 독립적으로 분석할 수 있습니다.

데이터는 명시적으로 또는 암시적으로 분할될 수 있습니다.

명시적 분할

여러 그룹으로 명시적 분할하기

다음 문은 개별 파티션에서 my_udtf 라는 UDTF를 호출합니다. 각 파티션에는 PARTITION BY 식이 동일 값(예: 동일한 회사 또는 주식 기호)으로 평가되는 모든 행이 포함됩니다.

SELECT *
    FROM stocks_table AS st,
         TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol))
Copy

단일 그룹으로 명시적 분할하기

다음 문은 하나의 파티션에서 my_udtf 라는 UDTF를 호출합니다. PARTITION BY <상수> 절(이 경우 PARTITION BY 1)은 모든 행을 동일한 파티션에 넣습니다.

SELECT *
    FROM stocks_table AS st,
         TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY 1))
Copy

보다 완전하고 현실적인 예는 쿼리에서 Java UDTF 호출의 예, 특히 단일 파티션 이라는 제목의 하위 섹션을 참조하십시오.

파티션 행 정렬하기

각 파티션의 행을 지정된 순서로 처리하려면 ORDER BY 절을 포함합니다. 이렇게 하면 Snowflake가 지정된 순서로 행별 핸들러 메서드에 행을 전달하도록 지시합니다.

예를 들어, 시간 경과에 따른 주가의 이동 평균을 계산하려면 타임스탬프별로 주가를 정렬하십시오(그리고 주식 기호로 분할). 다음 예에서는 이 작업을 수행하는 방법을 보여줍니다.

SELECT *
     FROM stocks_table AS st,
          TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol ORDER BY st.transaction_date))
Copy

OVER 절은 PARTITION BY 절이 없어도 ORDER BY 절을 포함할 수 있습니다.

OVER 절 내부에 ORDER BY 절을 포함하는 것은 쿼리의 가장 바깥쪽 수준에 ORDER BY 절을 넣는 것과 같지 않음을 기억하십시오. 전체 쿼리 결과를 정렬하려면 별도의 ORDER BY 절이 필요합니다. 예:

SELECT *
    FROM stocks_table AS st,
         TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol ORDER BY st.transaction_date))
    ORDER BY st.symbol, st.transaction_date, st.transaction_time;
Copy

명시적 분할에 대한 사용법 노트

PARTITION BY 절과 함께 UDTF를 사용할 때 PARTITION BY 절은 일반 식이 아닌 열 참조 또는 리터럴을 사용해야 합니다. 예를 들어 다음은 허용되지 않습니다.

SELECT * FROM udtf_table, TABLE(my_func(col1) OVER (PARTITION BY udtf_table.col2 * 2));   -- NO!
Copy

암시적 분할

테이블 함수가 PARTITION BY 절을 사용하여 명시적으로 행을 분할하지 않는 경우 일반적으로 Snowflake는 성능을 향상하기 위해 병렬 처리를 사용하도록 암시적으로 행을 분할합니다.

파티션의 수는 일반적으로 함수를 처리하는 웨어하우스의 크기 및 입력 관계의 카디널리티와 같은 요소를 기반으로 합니다. 행은 일반적으로 행의 물리적 위치(예: 마이크로 파티션)와 같은 요소를 기반으로 특정 파티션에 할당되므로 파티션 그룹화는 의미가 없습니다.