Java UDF 설계

이 항목은 Java UDF를 설계하는 데 도움이 됩니다.

이 항목의 내용:

데이터 타입 선택

코드를 작성하기 전에:

  • 함수가 인자로 수락해야 하는 데이터 타입, 그리고 함수가 반환해야 하는 데이터 타입을 선택하십시오.

  • 타임존 관련 문제를 고려하십시오.

  • NULL 값을 처리하는 방법을 결정하십시오.

매개 변수 및 반환 형식에 대한 SQL-Java 데이터 타입 매핑

아래 표는SQL과 Java 간의 형식 매핑을 보여줍니다. 이러한 매핑은 일반적으로 Java UDF에 전달된 인자, 그리고 UDF에서 반환된 값 모두에 적용됩니다. 그러나 몇 가지 예외가 있으며, 이는 각주에 나열되어 있습니다.

일부 SQL 데이터 타입(예: NUMBER)은 여러 Java 데이터 타입(예: int, long 등)과 호환됩니다. 이러한 경우, 전달될 실제 값을 보유하기에 충분한 용량이 있는 모든 Java 데이터 타입을 사용할 수 있습니다. SQL 값을 호환되지 않는 Java 데이터 타입에 전달하면(또는 그 반대로) Snowflake에서 오류가 발생합니다.

SQL 형식

Java 형식

참고

NUMBER

short

null일 수 없습니다. short 범위에 맞아야 합니다(소수부가 없고 정수부는 최대/최소 short 값을 초과할 수 없음).

NUMBER

Short

short 범위에 맞아야 합니다(소수부가 없고 정수부는 최대/최소 short 값을 초과할 수 없음).

NUMBER

int

null일 수 없습니다. int 범위에 맞아야 합니다(소수부가 없고 정수부는 최대/최소 int 값을 초과할 수 없음).

NUMBER

Integer

int 범위에 맞아야 합니다(소수부가 없고 정수부는 최대/최소 int 값을 초과할 수 없음).

NUMBER

long

null일 수 없습니다. long 범위에 맞아야 합니다(소수부가 없고 정수부는 최대/최소 long 값을 초과할 수 없음).

NUMBER

Long

long 범위에 맞아야 합니다(소수부가 없고 정수부는 최대/최소 long 값을 초과할 수 없음).

NUMBER

java.math.BigDecimal

NUMBER

java.math.BigInteger

BigInteger 범위에 맞아야 합니다(소수부 없음).

NUMBER

String

FLOAT

double

null일 수 없습니다.

FLOAT

Double

FLOAT

float

null일 수 없습니다. 정밀도 손실이 발생할 수 있습니다.

FLOAT

Float

정밀도 손실이 발생할 수 있습니다.

FLOAT

String

정밀도 손실이 발생할 수 있습니다(float -> string 변환에서 손실 발생).

VARCHAR

String

BINARY

byte[]

BINARY

String

이진 문자열을 16진수로 인코딩합니다. 4

BINARY

InputStream

BINARY 값을 바이트 시퀀스로 노출합니다.

BOOLEAN

boolean

null일 수 없습니다.

BOOLEAN

Boolean

BOOLEAN

String

4

DATE

java.sql.Date

DATE

String

날짜 형식을 YYYY-MM-DD 로 지정합니다. 4

TIME

java.sql.Time

3

TIME

String

시간 형식을 HH:MI:SS.SSSSSSSSS 로 지정합니다. 여기서 소수 자리 초 부분은 시간의 정밀도에 따라 다릅니다. 3

TIMESTAMP_LTZ

java.sql.Timestamp

java.sql.Timestamp 범위에 맞아야 합니다. 3

TIMESTAMP_LTZ

String

출력 형식은 DY, DD MON YYYY HH24:MI:SS TZHTZM 입니다. 1 , 3 , 4

TIMESTAMP_NTZ

java.sql.Timestamp

java.sql.Timestamp 범위에 맞아야 합니다. wallclock 시간을 Unix epoch(UTC 타임존을 효과적으로 부과)의 오프셋으로 처리합니다. 3

TIMESTAMP_NTZ

String

wallclock 시간을 Unix epoch(UTC 타임존을 효과적으로 부과)의 오프셋으로 처리합니다. 출력 형식은 DY, DD MON YYYY HH:MI:SS 입니다. 2 , 3 , 4

TIMESTAMP_TZ

java.sql.Timestamp

java.sql.Timestamp 범위에 맞아야 합니다. 3

TIMESTAMP_TZ

String

출력 형식은 DY, DD MON YYYY HH24:MI:SS TZHTZM 입니다. 1 , 3 , 4

VARIANT

베리언트

베리언트 데이터 타입은 Snowpark 패키지에 있는 클래스입니다. 자세한 내용은 Snowpark 패키지에서 지원되는 타입 섹션을 참조하십시오. 예를 보려면 인라인 Java UDF에 VARIANT 값 전달 를 참조하십시오.

OBJECT

Map<String, String>

맵의 키는 오브젝트의 키이고 값 형식은 문자열로 지정됩니다.

OBJECT

String

오브젝트 형식을 JSON 문자열로 지정합니다(예: {"x": 3, "y": true}).

ARRAY

String[]

배열 요소의 형식을 문자열로 지정합니다.

ARRAY

String

배열 형식을 JSON 문자열로 지정합니다(예: [1, "foo", null]).

GEOGRAPHY

String

지리 형식을 GeoJSON 으로 지정합니다.

GEOGRAPHY

Geography

5

1(1,2)

형식은 타임스탬프 형식 에 설명된 대로 인터넷(RFC) 타임스탬프 형식 DY, DD MON YYYY HH24:MI:SS TZHTZM 과 일치합니다. 타임존 오프셋(TZHTZM 구성 요소)이 있는 경우, 일반적으로 숫자입니다(예: -0700 은 UTC보다 7시간 늦음). 타임존 오프셋이 숫자가 아닌 Z (《Zulu》의 경우)인 경우, 《+0000》(UTC)과 동의어입니다.

2

형식은 타임스탬프 형식 에 설명된 대로 인터넷(RFC) 타임스탬프 형식 DY, DD MON YYYY HH24:MI:SS 와 일치합니다. 문자열 뒤에 공백과 Z (《Zulu》의 경우)가 오는 경우, 오프셋이 《+0000》(UTC)임을 명시적으로 나타냅니다.

3(1,2,3,4,5,6,7,8)

Snowflake는 나노초 정밀도로 시간 값을 저장할 수 있지만, java.sql.time 라이브러리는 밀리초 정밀도만 유지합니다. Snowflake와 Java 데이터 타입 간의 변환은 유효 정밀도를 밀리초로 줄일 수 있습니다.

4(1,2,3,4,5,6)

이 형식 매핑은 SQL 인자를 Java로 변환할 때 지원되지만, Java 반환 형식을 SQL 형식으로 변환할 때는 지원되지 않습니다.

5

Java에는 기본 Geography 데이터 타입이 없습니다. 여기서 말하는 Geography 데이터 타입은 Snowpark 패키지에 있는 클래스입니다. 자세한 내용은 Snowpark 패키지에서 지원되는 타입 섹션을 참조하십시오.

Snowpark 패키지에서 지원되는 타입

사용자 정의 함수에서 Snowflake Snowpark Java 패키지 에 포함된 타입 중 특정한 일부 타입을 사용할 수 있습니다. 이러한 타입은 Snowpark 코드에서 사용하도록 설계되었지만, 일부 타입은 제공 가능한 편의를 위해 UDF에서도 사용하도록 지원됩니다. (Snowpark에 대한 자세한 내용은 Snowpark 설명서 를 참조하십시오.)

다음 표의 Snowpark 유형은 UDF 코드에서 지원됩니다. 다른 Snowpark 유형은 UDF 코드에서 지원되지 않으므로 이 코드에서 사용하면 안 됩니다.

Snowpark 유형

필요한 Snowpark 버전

설명

Geography

1.2.0 이상

Snowflake GEOGRAPHY 유형을 나타냅니다. Geography 데이터 타입을 사용하는 예는 인라인 Java UDF에 GEOGRAPHY 값 전달 섹션을 참조하십시오.

베리언트

1.4.0 이상

Snowflake VARIANT 데이터를 나타냅니다. Variant 데이터 타입을 사용하는 예는 인라인 Java UDF에 VARIANT 값 전달 섹션을 참조하십시오.

Snowpark 패키지를 UDF 종속 항목으로 지정하기

Snowpark 패키지를 사용하는 UDF 코드 개발 시, Snowpark 종속 항목이 있는 코드를 컴파일하고 실행할 수 있도록 개발 환경을 설정해야 합니다. 자세한 내용은 Snowpark Java를 위한 기타 개발 환경 설정하기 섹션을 참조하십시오.

CREATE FUNCTION 문을 실행하여 UDF를 배포할 때 JAR 파일을 스테이지에 업로드하지 않고 Snowpark 패키지를 종속 항목으로 지정할 수 있습니다(라이브러리는 이미 Snowflake에 있음). 이렇게 하려면 PACKAGES 절에 패키지 이름과 버전을 지정하십시오. 구문 예제는 인라인 Java UDF에 GEOGRAPHY 값 전달 섹션을 참조하십시오.

TIMESTAMP_LTZ 값 및 타임존

Java UDF는 호출되는 환경과 크게 분리되어 있습니다. 그러나 타임존은 호출 환경에서 상속됩니다. 호출자의 세션이 Java UDF 호출 전에 기본 타임존을 설정한 경우, Java UDF는 동일한 기본 타임존을 갖습니다. Java UDF는 기본 TIMEZONE Snowflake SQL이 사용하는 것과 동일한 IANA타임존 데이터베이스 데이터(즉, 타임존 데이터베이스의 릴리스 2021a 에서 가져온 데이터)를 사용합니다.

NULL 값

Snowflake는 두 가지 고유한 NULL 값을 지원하는데, 이는 SQL NULL 과 VARIANT의 JSON null 입니다. (Snowflake VARIANT NULL에 대한 자세한 내용은 NULL 값 을 참조하십시오.)

Java는 기본이 아닌 데이터 타입에만 해당하는 하나의 null 값을 지원합니다.

Java UDF에 대한 SQL NULL 인자는 Java null 값으로 변환되지만, null 을 지원하는 Java 데이터 타입에만 해당됩니다.

반환된 Java null 값은 SQL NULL 로 다시 변환됩니다.

배열 및 가변 인자 수

Java UDF는 다음 Java 데이터 타입의 배열을 수신할 수 있습니다.

  • String

  • boolean

  • double

  • float

  • int

  • long

  • short

전달된 SQL 값의 데이터 타입은 해당 Java 데이터 타입과 호환되어야 합니다. 데이터 타입 호환성에 대한 매개 변수 및 반환 형식에 대한 SQL-Java 데이터 타입 매핑 을 참조하십시오.

지정된 각 Java 데이터 타입에 대해 다음과 같은 추가 규칙이 적용됩니다.

  • boolean: Snowflake ARRAY는 BOOLEAN 요소만 포함해야 하며 NULL 값을 포함해서는 안 됩니다.

  • int/short/long: Snowflake ARRAY는 스케일이 0인 고정 소수점 요소만 포함해야 하며 NULL 값을 포함해서는 안 됩니다.

  • float/double: Snowflake ARRAY는 다음 중 하나를 포함해야 합니다.

    ARRAY는 NULL 값을 포함할 수 없습니다.

Java 메서드는 다음 두 가지 방법 중 하나로 이러한 배열을 수신할 수 있습니다.

  • Java의 배열 기능을 사용합니다.

  • Java의 varargs (가변 인자 수) 기능을 사용합니다.

두 경우 모두 SQL 코드는 ARRAY 를 전달해야 합니다.

ARRAY를 통해 전달

Java 매개 변수를 배열로 선언하십시오. 예를 들어, 다음 메서드의 세 번째 매개 변수는 문자열 배열입니다.

static int myMethod(int fixedArgument1, int fixedArgument2, String[] stringArray)

다음은 완전한 예입니다.

테이블을 만들고 로딩합니다.

CREATE TABLE string_array_table(id INTEGER, a ARRAY);
INSERT INTO string_array_table (id, a) SELECT
        1, ARRAY_CONSTRUCT('Hello');
INSERT INTO string_array_table (id, a) SELECT
        2, ARRAY_CONSTRUCT('Hello', 'Jay');
INSERT INTO string_array_table (id, a) SELECT
        3, ARRAY_CONSTRUCT('Hello', 'Jay', 'Smith');

UDF를 만듭니다.

create or replace function concat_varchar_2(a ARRAY)
returns varchar
language java
handler='TestFunc_2.concatVarchar2'
target_path='@~/TestFunc_2.jar'
as
$$
    class TestFunc_2 {
        public static String concatVarchar2(String[] strings) {
            return String.join(" ", strings);
        }
    }
$$;

UDF를 호출합니다.

SELECT concat_varchar_2(a)
    FROM string_array_table
    ORDER BY id;
+---------------------+
| CONCAT_VARCHAR_2(A) |
|---------------------|
| Hello               |
| Hello Jay           |
| Hello Jay Smith     |
+---------------------+

Varargs를 통해 전달

varargs를 사용하는 것은 배열을 사용하는 것과 매우 유사합니다.

Java 코드에서 Java의 varargs 선언 스타일을 사용하십시오.

static int myMethod(int fixedArgument1, int fixedArgument2, String ... stringArray)

다음은 완전한 예입니다. 이 예와 이전 예(배열의 경우) 간의 유일한 중요한 차이점은 메서드에 대한 매개 변수 선언입니다.

테이블을 만들고 로딩합니다.

CREATE TABLE string_array_table(id INTEGER, a ARRAY);
INSERT INTO string_array_table (id, a) SELECT
        1, ARRAY_CONSTRUCT('Hello');
INSERT INTO string_array_table (id, a) SELECT
        2, ARRAY_CONSTRUCT('Hello', 'Jay');
INSERT INTO string_array_table (id, a) SELECT
        3, ARRAY_CONSTRUCT('Hello', 'Jay', 'Smith');

UDF를 만듭니다.

create or replace function concat_varchar(a ARRAY)
returns varchar
language java
handler='TestFunc.concatVarchar'
target_path='@~/TestFunc.jar'
as
$$
    class TestFunc {
        public static String concatVarchar(String ... stringArray) {
            return String.join(" ", stringArray);
        }
    }
$$;

UDF를 호출합니다.

SELECT concat_varchar(a)
    FROM string_array_table
    ORDER BY id;
+-------------------+
| CONCAT_VARCHAR(A) |
|-------------------|
| Hello             |
| Hello Jay         |
| Hello Jay Smith   |
+-------------------+

Snowflake에서 부과한 제약 조건 내에서 유지되는 Java UDF 설계

Snowflake 환경 내에서 안정성을 보장하기 위해 Snowflake는 Java UDF에 다음과 같은 제약 조건을 적용합니다. 달리 명시되지 않는 한 이러한 제한 사항은 UDF가 만들어질 때가 아니라 실행될 때 적용됩니다.

메모리

너무 많은 메모리를 사용하지 마십시오.

  • 큰 데이터 값(일반적으로 BINARY, long VARCHAR, 또는 large ARRAY 또는 OBJECT나 VARIANT 데이터 타입)은 많은 양의 메모리를 사용할 수 있습니다.

  • 과도한 스택 깊이는 많은 양의 메모리를 사용할 수 있습니다. Snowflake는 오류 없이 50개 수준으로 중첩된 간단한 함수 호출을 테스트했습니다. 실제 최대 제한은 스택에 있는 정보의 양에 따라 다릅니다.

UDF는 메모리를 너무 많이 사용하는 경우 오류를 반환합니다. 특정 제한은 변경될 수 있습니다.

시간

호출당 많은 시간이 소요되는 알고리즘을 피하십시오.

UDF를 완료하는 데 너무 오래 걸리는 경우, Snowflake는 SQL 문을 종료하고 사용자에게 오류를 반환합니다. 이는 무한 루프와 같은 오류의 영향과 비용을 제한합니다.

라이브러리

Java 메서드가 표준 Java 라이브러리의 클래스와 메서드를 사용할 수 있지만, Snowflake 보안 제한으로 인해 파일에 쓰는 것과 같은 일부 기능이 비활성화됩니다. 라이브러리 제한 사항에 대한 자세한 내용은 우수한 보안 관행 따르기 섹션을 참조하십시오.

클래스 설계

SQL 문이 Java UDF를 호출하면 Snowflake는 사용자가 작성한 Java 메서드를 호출합니다. Java 메서드를 《핸들러 메서드》 또는 줄여서 《핸들러》라고 합니다.

모든 Java 메서드와 마찬가지로 메서드는 클래스의 일부로 선언되어야 합니다. 핸들러 메서드는 클래스의 정적 메서드 또는 인스턴스 메서드일 수 있습니다. 핸들러가 인스턴스 메서드이고 클래스가 인자가 없는 생성자를 정의하는 경우, Snowflake는 초기화 시 생성자를 호출하여 클래스의 인스턴스를 만듭니다. 핸들러가 정적 메서드인 경우, 클래스에는 생성자가 필요하지 않습니다.

핸들러는 Java UDF에 전달된 각 행에 대해 한 번 호출됩니다. (참고: 클래스의 새 인스턴스는 각 행에 대해 만들어지지 않습니다. Snowflake는 동일한 인스턴스의 핸들러 메서드를 두 번 이상 호출하거나 동일한 정적 메서드를 두 번 이상 호출할 수 있습니다.)

코드 실행을 최적화하기 위해 Snowflake는 초기화가 느릴 수 있는 반면 핸들러 메서드의 실행은 빠르다고 가정합니다. Snowflake는 핸들러를 실행하는 것(한 행의 입력으로 핸들러를 호출하는 시간)보다 초기화 실행(UDF를 로딩하는 시간, 그리고 생성자가 정의된 경우 핸들러 메서드의 포함된 클래스의 생성자를 호출하는 시간 포함)에 더 긴 시간 제한을 설정합니다.

클래스 설계에 대한 추가 정보는 Java UDF 만들기 에 있습니다.

스칼라 UDF에서 초기화 최적화 및 전역 상태 제어

대부분의 스칼라 UDF는 아래 지침을 따라야 합니다.

  • 행 간에 변경되지 않는 공유 상태를 초기화해야 하는 경우, UDF 클래스의 생성자에서 초기화하십시오.

  • 스레드로부터 안전하도록 핸들러 메서드를 작성하십시오.

  • 행 간에 동적 상태를 저장 및 공유하지 마십시오.

UDF가 이러한 지침을 따를 수 없거나 이러한 지침의 이유를 더 깊이 이해하려는 경우, 다음 몇 가지 하위 섹션을 읽으십시오.

소개

Snowflake는 스칼라 UDF가 독립적으로 처리될 것으로 예상합니다. 호출 간에 공유되는 상태에 의존하면 예기치 않은 동작이 발생할 수 있습니다. 시스템이 임의의 순서로 행을 처리하고 이러한 호출을 여러 JVM에 분산할 수 있기 때문입니다. UDF는 핸들러 메서드에 대한 호출에서 공유 상태에 의존하는 것을 피해야 합니다. 그러나 사용자가 UDF에서 공유 상태를 저장하려 할 수 있는 다음 두 가지 상황이 있습니다.

  • 각 행에 대해 반복하고 싶지 않은, 부담이 큰 초기화 논리가 포함된 코드입니다.

  • 캐시와 같이 행 간에 공유 상태를 활용하는 코드입니다.

여러 행에서 상태를 공유해야 하고 해당 상태가 시간이 지나도 변경되지 않는 경우, 생성자를 사용하여 인스턴스 수준 변수를 설정해 공유 상태를 만드십시오. 생성자는 인스턴스당 한 번만 실행되는 반면 핸들러는 행당 한 번 호출되므로 핸들러가 여러 행을 처리할 때 생성자에서 초기화하는 것이 부담이 더 적습니다. 그리고 생성자는 한 번만 호출되기 때문에 생성자는 스레드로부터 안전하도록 작성할 필요가 없습니다.

변경되는 공유 상태를 UDF가 저장하는 경우, 해당 상태에 대한 동시 액세스를 처리할 수 있도록 코드를 준비해야 합니다. 다음 두 섹션에서는 병렬 처리 및 공유 상태에 대한 자세한 정보를 제공합니다.

Java UDF 병렬 처리 이해

성능을 향상시키기 위해 Snowflake는 JVM 전체에 걸쳐, 그리고 JVM 내에서 병렬 처리를 합니다.

  • JVM 전체에 걸쳐:

    Snowflake는 웨어하우스 의 작업자 전체에 걸쳐 병렬 처리를 합니다. 각 작업자는 하나 이상의 JVM을 실행합니다. 이는 전역 공유 상태가 없음을 의미합니다. 기껏해야 단일 JVM 내에서만 상태를 공유할 수 있습니다.

  • JVM 내에서:

    • 각 JVM은 동일한 인스턴스의 핸들러 메서드를 병렬로 호출할 수 있는 여러 스레드를 실행할 수 있습니다. 이는 각 핸들러 메서드가 스레드로부터 안전해야 함을 의미합니다.

    • UDF가 IMMUTABLE이고 SQL 문이 동일 행에 대해 동일 인자를 사용하여 UDF를 두 번 이상 호출하는 경우, UDF는 해당 행의 각 호출에 대해 동일 값을 반환합니다. 예를 들어, UDF가 IMMUTABLE인 경우 다음은 각 행에 대해 동일 값을 두 번 반환합니다.

      select
             my_java_udf(42),
             my_java_udf(42)
          from table1;
      

      동일 인자가 전달된 경우에도 여러 호출이 독립 값을 반환하고 함수 VOLATILE을 선언하지 않으려면 여러 개별 UDF를 동일 핸들러 메서드에 바인딩하십시오. 예:

      1. 다음 코드를 사용하여 @java_udf_stage/rand.jar 이라는 JAR 파일을 만듭니다.

        class MyClass {
        
            private double x;
        
            // Constructor
            public MyClass()  {
                x = Math.random();
            }
        
            // Handler
            public double myHandler() {
                return x;
            }
        }
        
      2. 아래와 같이 Java UDF를 만듭니다. 이러한 UDF는 이름이 다르지만, 동일 JAR 파일을 사용하며, 해당 JAR 파일 내에서 동일 핸들러를 사용합니다.

        create function my_java_udf_1()
            returns double
            language java
            imports = ('@java_udf_stage/rand.jar')
            handler = 'MyClass.myHandler';
        
        create function my_java_udf_2()
            returns double
            language java
            imports = ('@java_udf_stage/rand.jar')
            handler = 'MyClass.myHandler';
        
      3. 다음 코드는 두 UDF를 모두 호출합니다. UDF는 동일한 JAR 파일 및 핸들러를 가리킵니다. 이러한 호출은 동일한 클래스의 두 인스턴스를 만듭니다. 각 인스턴스는 독립적인 값을 반환하므로 아래 예에서는 동일 값을 두 번 반환하는 대신 두 개의 독립적인 값을 반환합니다.

        select
                my_java_udf_1(),
                my_java_udf_2()
            from table1;
        

JVM 상태 정보 저장

동적 공유 상태에 의존하지 않는 한 가지 이유는 행이 반드시 예측 가능한 순서로 처리되는 것은 아니기 때문입니다. SQL 문이 실행될 때마다 Snowflake는 배치 수, 배치가 처리되는 순서, 배치 내의 행 순서를 변경할 수 있습니다. 한 행이 후속 행의 반환 값에 영향을 미치도록 스칼라 UDF가 설계된 경우, UDF는 UDF가 실행될 때마다 다른 결과를 반환할 수 있습니다.

오류 처리

UDF로 사용되는 Java 메서드는 일반 Java 예외 처리 기술을 사용하여 메서드 내에서 오류를 포착할 수 있습니다.

메서드 내에서 예외가 발생하고 이 예외가 메서드에서 포착되지 않으면 Snowflake는 예외에 대한 스택 추적을 포함하는 오류를 발생시킵니다.

쿼리를 종료하고 SQL 오류를 생성하기 위해 예외를 포착하지 않고 명시적으로 예외를 발생시킬 수 있습니다. 예:

if (x < 0)  {
    throw new IllegalArgumentException("x must be non-negative.");
    }

디버깅할 때 SQL 오류 메시지 텍스트에 값을 포함할 수 있습니다. 이렇게 하려면 전체 Java 메서드 본문을 try-catch 블록에 배치하고, 포착된 오류 메시지에 인자 값을 추가하고, 확장된 메시지와 함께 예외를 발생시키십시오. 민감한 데이터가 노출되지 않도록 하려면 JAR 파일을 프로덕션 환경에 배포하기 전에 인자 값을 제거하십시오.

모범 사례 따르기

  • 플랫폼 독립적인 코드를 작성하십시오.

    • 특정 CPU 아키텍처(예: x86)를 가정하는 코드를 피하십시오.

    • 특정 운영 체제를 가정하는 코드를 피하십시오.

  • 초기화 코드를 실행해야 하지만, 호출하는 메서드에 이를 포함하지 않으려면 초기화 코드를 정적 초기화 블록에 넣을 수 있습니다.

참고 항목:

우수한 보안 관행 따르기

  • 메서드(및 호출하는 모든 라이브러리 메서드)는 순수 함수로 작동해야 하며, 수신한 데이터에 대해서만 작동하고 해당 데이터를 기반으로 값을 반환해야 하며, 이 과정에서 부작용 없이 작동해야 합니다. 코드는 적절한 양의 메모리와 프로세서 시간을 사용하는 것 외에는 기본 시스템의 상태에 영향을 미치려고 해서는 안 됩니다.

  • Java UDF는 제한된 엔진 내에서 실행됩니다. 코드 또는 사용하는 라이브러리 메서드의 코드는 다음을 포함하여 금지된 시스템 호출을 사용해서는 안 됩니다.

    • 프로세스 제어. 예를 들어, 프로세스를 포크할 수 없습니다. (단, 여러 스레드는 사용할 수 있습니다.)

    • 파일 시스템 액세스.

      다음 예외를 제외하고 Java UDF는 파일을 읽거나 쓰지 않아야 합니다.

      • Java UDF는 CREATE FUNCTION 명령의 imports 절에 지정된 파일을 읽을 수 있습니다. 자세한 내용은 CREATE FUNCTION 섹션을 참조하십시오.

      • Java UDF는 로그 파일과 같은 파일을 /tmp 디렉터리에 쓸 수 있습니다.

        각 쿼리는 고유한 /tmp가 저장되는 자체 메모리 지원 파일 시스템을 가져오므로 서로 다른 쿼리에는 파일 이름 충돌이 있을 수 없습니다.

        그러나 단일 쿼리가 둘 이상의 UDF를 호출하고 이러한 UDF가 동일 파일 이름에 쓰려고 하면 쿼리 내 충돌이 발생할 수 있습니다.

    • 네트워크 액세스.

      참고

      코드는 네트워크에 직접 또는 간접적으로 액세스할 수 없으므로 Snowflake JDBC 드라이버의 코드를 사용하여 데이터베이스에 액세스할 수 없습니다. UDF 자체는 Snowflake의 클라이언트 역할을 할 수 없습니다.

  • JNI(Java 네이티브 인터페이스)는 지원되지 않습니다. Snowflake는 (Java 바이트 코드와는 대조적으로) 네이티브 코드가 포함된 라이브러리를 로딩하는 것을 금지합니다.

  • 정부 리전 내에서 사용 시, Java UDF는 연방 정보 처리 표준(140-2)(FIPS 140-2) 요구 사항을 충족하는 것으로 검증된 암호화 알고리즘을 지원합니다. Java용 BouncyCastle 암호화 API의 FIPS 승인 모드에서 허용되는 암호화 알고리즘만 사용할 수 있습니다. FIPS 140-2에 대한 자세한 내용은 FIPS 140-2 를 참조하십시오.

맨 위로 이동