문서 메뉴

타입 어노테이션#

Typesql은 선택적 타입이 있는 SQL입니다. 이 열은 null이 아니다, 이 숫자는 decimal(28,2) 범위에 들어간다, 이 json에는 plan 필드가 있다는 식으로 의존하는 가정에 어노테이션을 붙입니다. 검사기는 쿼리 실행 전과 그 아래 스키마가 바뀔 때마다 레이크의 실제 스키마를 기준으로 가정을 검증합니다.

typesql
select
  id,
  amount satisfies integer!,
  metadata::json<{plan: string}> ->> 'plan' as plan
from titan.stripe.charges

보장#

어노테이션은 쿼리의 반환 결과를 바꾸지 않습니다. typesql 문서에서 모든 어노테이션을 제거하면 동일하게 실행되는 일반 SQL이 됩니다. 행, 값, 모든 것이 같습니다. 이는 관례가 아닌 구조적 보장입니다. 타입은 검사 후 소거되며 어떤 실행 경로도 타입을 읽을 수조차 없습니다.

따라서 마이그레이션 여부를 결정할 필요가 없습니다. 한 쿼리의 표현식 하나에만 어노테이션을 붙여도 되고 모델 전체에 타입을 지정해도 됩니다. “일반 SQL”과 “완전히 타입이 지정된 SQL” 사이의 모든 단계가 동작하는 프로그램입니다.

satisfies: 표현식 검사#

표현식을 사용할 수 있는 곳이면 어디든 expr satisfies type을 쓸 수 있습니다.

typesql
select
  round(sum(amount) / 100.0, 2) satisfies decimal(38,2) as gross_volume
from titan.stripe.charges
where not _deleted

스키마 변경으로 해당 표현식이 더 이상 decimal이 아니게 되면 대시보드가 조용히 잘못된 값을 표시하는 대신 모델 검사가 실패하고 정확한 소스 범위를 가리키는 진단이 나타납니다. 모든 진단에는 안정적인 TS 코드, 위치, 수정 방법을 담은 help: 줄이 있습니다.

satisfies는 형 변환이 아닙니다. amount::string은 값을 변환하고 `amount satisfies
string은 사실을 단언하며 사실이 아니면 검사에 실패합니다. 데이터를 바꾸려면 ::를, 변화를 감지하려면 satisfies`를 사용하세요.

null 제외: !와 타입 좁히기#

string!은 “문자열이며 절대 null이 아님”을 뜻합니다. 검사기는 쿼리 로직이 null 허용성에 미치는 영향을 이해하므로 다음은 통과합니다.

typesql
select email satisfies string!
from titan.stripe.customers
where email is not null

where 절을 제거하면 실패합니다. 스키마에서 email은 null을 허용하고 쿼리 어디에서도 null을 제외하지 않았기 때문입니다. 반대도 성립합니다. 입력에서 null이 아닌 열도 left join의 외부 쪽에서는 null을 허용하게 되며 검사기는 이것도 추적합니다. 검사는 스키마 선언만이 아니라 쿼리가 실제로 하는 일을 반영합니다.

타입이 지정된 CTE 헤더#

CTE 헤더에서 열 타입을 선언하면 쿼리 단계 사이의 경계를 검증된 계약으로 만들 수 있습니다.

typesql
with monthly(month: date!, gross_volume: decimal(38,2)) as (
  select
    date_trunc('month', created_at)::date,
    round(sum(amount) / 100.0, 2)
  from titan.stripe.charges
  where not _deleted
  group by 1
)
select * from monthly where gross_volume > 250000

본문은 헤더에 맞는지 검사되고 monthly 이후의 모든 부분은 선언된 타입을 받습니다. 소거할 때 헤더에서 타입이 제거되어 with monthly(month, gross_volume) as (…)가 되며 일반 SQL로 실행됩니다.

타입이 지정된 json#

json 열에 구조를 지정하면 내부 필드에 접근할 때 추측할 필요가 없어집니다.

typesql
select
  metadata::json<{plan: string, seats: integer}> as meta,
  meta ->> 'plan' as plan
from titan.stripe.charges

이제 meta ->> 'paln' 같은 오타는 나중에 대시보드 여러 개를 거쳐 null 열로 발견되는 대신 검사 실패로 나타납니다.

편집기에서 사용#

쿼리 편집기는 입력하는 동안 같은 검사기를 실행합니다. 표현식에 마우스를 올리면 추론한 타입을 확인할 수 있습니다. 인레이 힌트는 검사기가 이미 아는 타입을 보여주고, 클릭하면 실제 satisfies 어노테이션으로 쿼리에 기록됩니다. 클릭할 때마다 점진적으로 타입을 지정할 수 있습니다. 빠른 수정은 진단이 제안하는 것과 동일한 편집을 제공합니다.

다음 단계#

  • 모델 작성: 모델은 실행할 때마다 레이크를 기준으로 검사되며 -- lint: 헤더로 어떤 진단이 실행을 막을지 조정합니다.

  • 타입 시스템 페이지는 스칼라, decimal(p,s), 목록과 구조체 타입, 테이블 타입, _synced_at 같은 시스템 열의 타입 지정 등 전체 문법을 설명합니다.