VARIANT 함수와 연산자

VARIANT 함수와 연산자 (VARIANT functions and operators)

VARIANT 타입은 Apache Iceberg Variant 스펙이 정의하는 반정형(semi-structured) 값을 나타내요. 캐스팅(cast)을 통해 만들고, 다시 캐스팅으로 디코딩하며, SQL 첨자 연산자([])로 값을 꺼내 써요.

출처: 문서

본문

VARIANT 타입은 Apache Iceberg Variant 스펙이 정의하는 반정형 값을 나타내요. VARIANT 값은 캐스팅으로 만들어지고, 캐스팅으로 디코딩되며, SQL 첨자 연산자([])로 역참조(dereference)돼요.

동등성 의미 (Equality semantics)

VARIANT 값이 같은 논리적 값을 나타내면, 내부 인코딩 세부 사항과 무관하게 서로 같다고 봐요. 즉 동등성은 바이트 단위 인코딩이 아니라 값 의미론(value semantics)에 기반해요. 예를 들어:

  • 숫자는 인코딩 종류와 무관하게 숫자 값으로 비교돼요.
  • 문자열은 짧은 문자열 또는 일반 문자열 인코딩과 무관하게 문자열 바이트로 비교돼요.
  • 타임스탬프는 두 정밀도(마이크로초 vs 나노초)에서 정확히 표현 가능할 때, 인스턴스/값으로 비교돼요.
  • TIMESTAMPTIMESTAMP WITH TIME ZONE은 서로 다른 타임스탬프 종류로 남아 있으며 서로 같지 않아요.

숫자에는 추가적인 경계 케이스 규칙이 적용돼요:

  • 정수와 소수 형태는 정확한 숫자 값으로 비교돼요. 1, 1.0, 1.00은 같아요.
  • 부동소수점 값(REAL, DOUBLE)은 그 값이 variant decimal로 정확히 표현될 수 있을 때만 정확한 숫자와 같아요. 예를 들어 0.5DECIMAL '0.5'와 같지만, 0.1DECIMAL '0.1'과 같지 않아요. 이진 부동소수점이 0.1을 정확히 표현하지 못하기 때문이에요.
  • +0.0-0.0은 같아요.
  • NaN은 자기 자신을 포함해 어떤 값과도 같지 않아요.

첨자 연산자 (Subscript operator)

VARIANT 값의 요소는 SQL 첨자 연산자([])로 접근할 수 있어요. 첨자 연산의 결과는 항상 VARIANT 값이에요.

객체 (Objects)

기반 값이 객체라면 VARCHAR 키를 사용해요.

variant_expression['key']

객체 안에 지정된 키가 없다면 결과는 SQL NULL이에요.

배열 (Arrays)

기반 값이 배열이라면 1부터 시작하는 인덱스의 bigint를 사용해요.

variant_expression[index]

SQL 배열 인덱싱 규칙이 동일하게 적용돼요.

  • 인덱스는 1부터 시작해요.
  • 인덱스 0이나 음수 인덱스는 유효하지 않으며 오류를 일으켜요.
  • 배열 길이보다 큰 인덱스는 오류를 일으켜요.

함수 (Functions)

  • variant_is_null(variant) → boolean

    입력 값이 variant null을 나타내면 true를 돌려줘요. 이 함수는 variant null 값과 SQL NULL을 구분해요.

    • 값이 variant null이면 true
    • 그 외 모든 variant 값이면 false
    • 입력이 SQL NULL이면 SQL NULL

    예시:

    SELECT variant_is_null(CAST(JSON 'null' AS VARIANT)); -- true
    SELECT variant_is_null(CAST(42 AS VARIANT));          -- false
    SELECT variant_is_null(NULL);                         -- NULL
    

VARIANT로 캐스팅 (Cast to VARIANT)

다음 SQL 타입들을 VARIANT로 캐스팅할 수 있어요.

스칼라 타입 (Scalar types)

BOOLEAN, TINYINT, SMALLINT, INTEGER, BIGINT, REAL, DOUBLE, DECIMAL, VARCHAR, VARBINARY, DATE, TIME(p), TIMESTAMP(p), TIMESTAMP(p) WITH TIME ZONE, UUID, JSON, VARIANT

컨테이너 타입 (Container types)

ARRAY, MAP(VARCHAR 키 타입), ROW

컨테이너 값은 중첩 컨테이너, JSON, VARIANT 값을 포함한 모든 지원 스칼라 또는 컨테이너 타입을 담을 수 있어요.

VARIANT에서 캐스팅 (Cast from VARIANT)

VARIANT 값은 기반 값이 대상 타입과 호환될 때 다음 SQL 타입으로 캐스팅할 수 있어요. 표준 Trino cast 강제 변환(coercion) 규칙이 적용돼요. 예를 들어 문자열을 담은 VARIANT 값은 대상 타입에 유효한 값이고 범위에 들어맞는다면 숫자 타입으로 캐스팅할 수 있어요.

스칼라 타입

BOOLEAN, TINYINT, SMALLINT, INTEGER, BIGINT, REAL, DOUBLE, DECIMAL, VARCHAR, VARBINARY, DATE, TIME(p), TIMESTAMP(p), TIMESTAMP(p) WITH TIME ZONE, UUID, JSON, VARIANT

컨테이너 타입

ARRAY, MAP(VARCHAR 키 타입), ROW

대상 타입의 구조가 VARIANT 값의 내용과 호환될 때 컨테이너 타입으로의 캐스팅이 지원돼요. 기반 값이 요청된 타입과 호환되지 않으면 캐스팅은 실패해요.

더 알아보기 (Learn more)

VARIANT로 반정형 데이터를 유연하게 다룰 수 있게 됐어요. 이어서 쿼리 결과의 행을 가로질러 계산하는 윈도우 함수(window functions)를 살펴보면 좋아요.