사용자 정의 함수
사용자 정의 함수 (UDF) 개요
Snowflake가 기본 제공하는 함수만으로는 부족할 때가 있어요. 회사 고유의 계산 규칙을 함수 하나로 묶고 싶다면 사용자 정의 함수(UDF, User-defined Function) 를 직접 작성할 수 있어요. 한 번 만들어 두면 여러 번 재사용할 수 있고, 표현식을 지정해 명시적으로 값을 반환하므로 계산 결과를 돌려받는 용도에 잘 맞아요.
출처: User-defined functions overview - Snowflake Documentation
UDF의 종류
입력과 출력의 형태에 따라 UDF는 몇 가지 변형으로 나뉘어요.
| 변형 | 설명 |
|---|---|
| UDF | 스칼라 함수라고도 불러요. 입력 행마다 단일 컬럼/값을 한 행으로 반환해요. |
| UDAF (사용자 정의 집계 함수) | 여러 행에 걸친 값들로 합·평균·개수·최소/최대·표준편차 같은 수학 연산을 수행해요. |
| UDTF (사용자 정의 테이블 함수) | 입력 행마다 테이블 형태의 값을 반환해요. |
| Vectorized UDF | 입력 행 배치를 Pandas DataFrame으로 받아 결과 배치를 Pandas array 또는 Series로 반환해요. |
| Vectorized UDTF | 입력 행 배치를 Pandas DataFrame으로 받아 테이블 형태의 결과를 반환해요. |
UDF는 저장 프로시저(Stored procedure)와 비슷해 보이지만 쓰임새가 달라요. 어떤 쪽이 맞는지는 저장 프로시저 vs UDF 선택 문서를 참고하세요.
지원 언어와 도구
UDF의 로직(핸들러)은 지원 언어 중 하나로 작성해요. 핸들러를 작성한 뒤 Snowflake가 제공하는 여러 도구 중 하나로 UDF를 만들고(CREATE UDF) 실행할 수 있어요.
- SQL: Java·JavaScript·Python·Scala·SQL 중 하나로 핸들러 로직을 작성. 핸들러를 스테이지에 두는 대신 인라인으로 작성해야 하는지(inline-or-staged) 확인이 필요해요.
- Java·Python·Scala: 클라이언트에서 작성한 코드를 Snowflake로 푸시해 처리.
- 명령줄 인터페이스(Snowflake CLI): JSON 객체 속성으로 객체를 지정해 명령줄에서 생성·관리.
- Python API: 파이썬으로 함수를 만들고 핸들러를 지원 언어 중 하나로 작성.
- REST API: RESTful 엔드포인트 요청으로 UDF를 생성·관리.
핸들러 결과가 공유 가능(Sharable)한 UDF인지도 따져 볼 필요가 있어요. 시큐어 데이터 공유(Secure Data Sharing)에서 쓰려면 공유 가능한 방식으로 만들어야 하거든요.
고려사항
- UDF가 스테이지 파일에 접근하는데, 같은 SQL 문에서 UDF·UDTF를 호출하는 뷰를 함께 조회하면 사용자 오류로 실패해요(뷰가 실제로 파일에 접근하는지와 무관하게요).
- UDTF는 여러 파일을 병렬로 처리할 수 있지만, UDF는 현재 파일을 직렬로 처리해요.
GROUP BY절로 행을 묶는 방식이 해결책이에요. - 쿼리 실행 중에 스테이지 파일이 수정되거나 삭제되면 함수 호출이 오류로 끝나요.
- UDF 핸들러 코드 안에서
CURRENT_DATABASE나CURRENT_SCHEMA를 쓰면, 세션에서 사용 중인 값이 아니라 UDF가 속한 데이터베이스·스키마를 반환해요.
UDF 예시
파이썬으로 작성한 addone이라는 UDF를 만들어 봐요. 핸들러 함수는 addone_py이고, 반환 타입은 int예요.
CREATE OR REPLACE FUNCTION addone(i INT)
RETURNS INT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.12'
HANDLER = 'addone_py'
AS $$
def addone_py(i):
return i + 1
$$;
만든 함수는 내장 함수처럼 호출할 수 있어요.
SELECT addone(3);
작성 시 지침·제약
- 네이밍: 다른 함수와 충돌하지 않도록 이름을 지어 주세요(네이밍 규칙).
- 인자: 인자를 지정하고 어떤 인자가 선택인지 표시해요(인자 정의).
- 데이터 타입 매핑: 핸들러 언어와 SQL 타입 사이의 매핑은 언어별로 달라요(타입 매핑).
- Snowflake 제약 내 설계: 핸들러가 Snowflake가 부과한 제약 안에서 동작하도록 설계해요.
핸들러 작성 시 외부 네트워크 접근이 필요하면 external network access로 특정 위치에 대한 안전한 접근을 만들 수 있고, 로그·트레이스·메트릭을 기록해 나중에 조회할 수 있어요(logging & tracing).
보안
UDF·UDTF가 특정 SQL 동작을 수행하는 데 필요한 객체 권한을 부여할 수 있어요(UDF 권한 부여). 함수는 저장 프로시저와 비슷한 보안 고려사항을 공유해요. 민감 정보를 접근 권한이 없는 사용자로부터 숨기려면 시큐어 UDF·저장 프로시저로 만들면 돼요(Secure UDFs).