sqllogictest 소개

sqllogictest 소개 (sqllogictest Introduction)

일반 SQL을 테스트하기 위해 우리는 SQLite에서 채택한 SQL 로직 테스트 스위트(extension 버전)를 사용해요. 각 테스트는 test/sql 디렉터리에 위치한 단일 자족형(self-contained) 파일이에요. 기본 test 디렉터리 밖에 있는 테스트를 실행하려면 --test-dir <root_directory>를 지정하고, 제공하는 테스트 파일 경로가 그 루트 디렉터리에 상대적이어야 해요.

출처: 문서

본문

테스트는 일련의 SQL 문과 함께, 예상 결과, statement ok 표시, 또는 statement error 표시 중 하나를 기술해요. 테스트 파일의 예시는 아래와 같아요.

# name: test/sql/projection/test_simple_projection.test
# group [projection]

# enable query verification
statement ok
PRAGMA enable_verification

# create table
statement ok
CREATE TABLE a (i INTEGER, j INTEGER);

# insertion: 1 affected row
statement ok
INSERT INTO a VALUES (42, 84);

query II
SELECT * FROM a;
----
42	84

이 예시에서는 세 개의 문이 실행돼요. 처음 두 문은 성공할 것으로 예상돼요(statement ok로 접두됨). 세 번째 문은 두 컬럼을 가진 단일 행을 반환할 것으로 예상돼요(query II로 표시). 행의 값은 4284(탭 문자로 구분)일 것으로 예상돼요. 쿼리 결과 검증에 대한 자세한 내용은 결과 검증 섹션을 참고해요.

모든 파일의 맨 위에는 테스트의 이름과 그룹을 설명하는 주석이 있어야 해요. 테스트의 이름은 항상 파일의 상대 경로예요. 그룹은 파일이 들어 있는 폴더예요. 테스트의 이름과 그룹은 중요해요. unittest 그룹에서 해당 테스트만 실행하는 데 사용할 수 있기 때문이에요. 예를 들어 위 테스트 실행하려면 unittest test/sql/projection/test_simple_projection.test 명령을 실행해요. 특정 디렉터리의 모든 테스트를 실행하려면 unittest "[projection]" 명령을 실행해요.

test 디렉터리에 놓인 모든 테스트는 자동으로 테스트 스위트에 추가돼요. 테스트의 확장자가 중요하다는 점을 기억하세요. sqllogictest는 .test 확장자나 .test_slow 확장자를 사용해야 해요. .test_slow 확장자는 테스트 실행에 시간이 걸려서, unittest *로 모든 테스트를 명시적으로 실행할 때만 실행된다는 뜻이에요. .test 확장자가 있는 테스트는 빠른 테스트 집합에 포함돼요.

쿼리 검증 (Query Verification)

많은 간단한 테스트는 쿼리 검증을 활성화하는 것으로 시작해요. 다음 PRAGMA 문을 통해 활성화할 수 있어요.

statement ok
PRAGMA enable_verification

쿼리 검증은 기본 코드가 올바르게 실행되는지 확인하기 위해 추가 검증을 수행해요. 가장 중요한 부분은 옵티마이저가 쿼리에 버그를 일으키지 않는지 검증한다는 거예요. 이를 위해 최적화되지 않은 버전과 최적화된 버전의 쿼리를 모두 실행하고 결과가 동일한지 확인해요.

쿼리 검증은 옵티마이저의 버그뿐 아니라 조인(join) 구현 등의 버그도 찾아내기 때문에 매우 유용해요. 최적화되지 않은 버전은 보통 크로스 프로덕트(cross product)를 사용해 실행되기 때문이에요. 그래서 쿼리 검증은 더 큰 데이터셋을 다룰 때 매우 느릴 수 있어요. 따라서 더 큰 데이터셋(약 10~100행 이상)을 제외한 모든 단위 테스트에서 쿼리 검증을 켜는 것이 권장돼요.

에디터와 문법 하이라이팅 (Editors & Syntax Highlighting)

sqllogictests는 산업 표준은 아니지만, 여러 다른 시스템에서도 이것을 채택했어요. sqllogictest 파싱은 의도적으로 단순해요. 모든 문은 빈 줄로 구분되어야 해요. 그래서 문법 하이라이터를 작성하는 것은 그리 어렵지 않아요.

Visual Studio Code용 문법 하이라이터가 있어요. 우리는 DuckDB 방언의 sqllogictests를 지원하는 포크도 만들었어요. 원본을 설치한 다음 syntaxes/sqllogictest.tmLanguage.json을 설치된 확장에 복사해 포크를 사용할 수 있어요(macOS에서는 ~/.vscode/extensions/benesch.sqllogictest-0.1.1에 위치).

CLion용 문법 하이라이터도 있어요. 마켓플레이스에서 SQLTest를 검색해 IDE에 직접 설치할 수 있어요. GitHub 저장소도 있는데, 확장과 버그 리포트를 환영해요.

임시 파일 (Temporary Files)

일부 테스트(예: CSV/Parquet 파일 형식 테스트)는 임시 파일을 만들어야 해요. 임시 파일은 임시 테스트 디렉터리에 만들어야 해요. 이 디렉터리는 쿼리에 __TEST_DIR__ 문자열을 넣으면 사용할 수 있어요. 이 문자열은 임시 테스트 디렉터리의 경로로 대체돼요.

statement ok
COPY csv_data TO '__TEST_DIR__/output_file.csv.gz' (COMPRESSION gzip);

필요 항목과 확장 (Require & Extensions)

핵심 시스템의 비대화를 피하기 위해 DuckDB의 일부 기능은 확장으로만 사용할 수 있어요. 테스트에 require 필드를 추가하면 그 확장에 대한 테스트를 만들 수 있어요. 확장이 로드되지 않으면 require 필드 이후에 오는 문은 건너뛰어져요. 예를 들어 require parquet 또는 require icu 같은 것들이 있어요.

또 다른 용도는 테스트를 특정 벡터 크기로 제한하는 거예요. 예를 들어 테스트에 require vector_size 512를 추가하면 벡터 크기가 512 이상일 때만 테스트가 실행돼요. 일부 기능은 낮은 벡터 크기에서 지원되지 않지만, 우리는 CI에서 벡터 크기 2로 테스트를 실행하기 때문에 유용해요.

더 알아보기 (Learn more)