


고성능 데이터베이스 코드를 속도와 호환성을 해치지 않고 고치기
Java, SQL, Rust, 네이티브 코드, CI에 걸친 속도 중심 데이터베이스를 AI가 고칠 때 씁니다. 코드 작성 방식, NULL 처리와 메모리 정리, 쿼리 테스트, 실패 조사, 풀 리퀘스트와 빌드 규칙을 정하고, 완료를 말하기 전 마지막 확인으로 끝냅니다.
이 AI 규칙을 사용하려면
## 데이터베이스 모듈 경계를 지키고 메모리를 할당하지 않는 데이터 경로 보호하기
- 스토리지 엔진, SQL 엔진, 네트워크 프로토콜, 유틸리티, 워커 큐, 로깅, 백그라운드 작업, 벤치마크, 호환성 테스트, 예제의 모듈 경계를 명확하게 유지하세요.
- 프로덕션 코드를 벤치마크, 빌드 유틸리티, 예제, 플랫폼 래퍼와 분리하세요.
- 중첩된 클라이언트 저장소나 서브모듈을 자체 커밋과 호환성 목표를 가진 독립 저장소로 취급하세요.
- 동작을 변경하기 전에 서버 시작, 스토리지 엔진, SQL 컴파일러, 테이블 리더, 테이블 라이터 중 올바른 진입점을 식별하세요.
- 쿼리 실행과 수집 중에는 할당이 없는 데이터 경로를 보호하세요.
- 아키텍처가 요구할 때 객체 풀, 재사용 가능한 버퍼, 열 지향 스토리지, 벡터화 실행, 네이티브 가속을 우선하세요.
- 프로젝트가 성능에 중요한 알고리즘을 의도적으로 직접 구현한다면 타사 런타임 의존성을 도입하지 마세요.
- 메모리, 플랫폼, 실패 위험을 감수할 정당성이 있는 작업에만 네이티브 코드를 사용하세요.
## Java 클래스 멤버를 정렬하고 옛 Java 클라이언트와의 호환성 지키기
- 클래스 멤버를 정적 또는 인스턴스 여부와 가시성에 따라 그룹화한 다음, 각 그룹 안에서 멤버를 알파벳순으로 유지하세요.
- 장식용 섹션 그룹을 만들지 말고 새 필드와 메서드를 정렬상 올바른 위치에 삽입하세요.
- 배너 주석을 인위적인 Java 섹션 제목으로 추가하지 마세요.
- 향상된 `switch`, 여러 줄 문자열, 패턴 변수를 포함하여 기본 모듈이 지원하는 최신 언어 기능을 사용하세요.
- 호환성 모듈의 이전 언어 목표를 준수하고, 기본 모듈의 구문이 더 이른 Java 릴리스를 대상으로 하는 클라이언트에 유입되지 않게 하세요.
- 불리언 변수, 필드, 메서드에는 적절하게 `is` 또는 `has` 접두사를 붙이세요.
- 로깅 파이프라인이 유니코드 문장 부호나 기호를 안정적으로 표시하지 못한다면 로그 메시지에는 ASCII만 사용하세요.
- 기존 정리 유틸리티와 통합되는 경우 일반 객체 배열 대신 프로젝트의 리소스 인식 컬렉션 타입을 사용하세요.
- 새로운 추상화를 도입하기 전에 기존 명명, 소유권, 할당 패턴을 따르세요.
## NULL 처리를 정하고 모든 오류 경로에서 메모리 정리하기
- 열 데이터, 표현식 결과, SQL 문, 중간 상태의 NULL 동작을 명시적으로 결정하세요.
- “아직 초기화되지 않음”을 뜻하는 NULL 센티널과 실제 데이터 NULL을 구분하세요.
- 성공, 오류, 취소, 조기 반환 경로 전체에서 모든 할당과 닫을 수 있는 리소스를 추적하세요.
- 목록과 닫을 수 있는 요소에 저장소의 정리 도우미를 일관되게 사용하세요.
- 누수 방지를 테스트에만 국한된 관심사가 아니라 설계 요구사항으로 취급하세요.
- 네이티브 메모리를 할당하는 테스트에 메모리 누수 어설션을 추가하세요.
- 네이티브 메모리를 할당하지 않음이 입증된 좁은 범위의 단위 테스트는 누수 하네스를 생략해도 됩니다.
- 성공 경로뿐 아니라 관련된 모든 오류 경로에서 정리 작업을 검증하세요.
- 편리한 컨테이너나 도우미 뒤에 소유권의 모호함을 숨기지 마세요.
## 결과를 다시 읽는 엄격한 검증으로 쿼리 테스트하기
- 기존의 단일 패스 출력·비교 도우미보다 표준 fluent 쿼리 어설션 프레임워크를 우선하세요.
- 결정론적 쿼리에는 두 번째 커서 패스, 크기 교차 확인, 가변 열 확인, 관련 팩토리 속성 어설션을 요구하세요.
- 다시 읽을 때마다 프로젝션이 실제로 불안정한 경우에만 단일 패스 어설션을 사용하고 그 이유를 명시하세요.
- 시드를 지정하지 않은 난수 함수와 시간에 따라 달라지는 함수는 유효한 불안정성의 예입니다.
- DDL과 쿼리가 아닌 다른 문은 비쿼리 실행 경로를 통해 실행하세요.
- 옵티마이저 동작이 규약의 일부라면 프레임워크의 실행 계획 도우미로 실행 계획을 검증하세요.
- 방언이 지원한다면 여러 테스트 행에 하나의 `INSERT` 문을 사용하세요.
- 긴 SQL과 여러 줄의 예상 결과에는 여러 줄 문자열을 사용하세요.
- SQL 키워드는 일관되게, 가급적 대문자로 작성하세요.
- 해당 구문이 지원된다면 다섯 자리 이상의 리터럴에서 천 단위를 밑줄로 구분하세요.
## SQL 방언을 따르고 오류 위치를 정확한 문자에 맞추기
- 차원 수가 열 타입에 인코딩되는 경우 다차원 배열 타입을 서로 다른 타입으로 취급하세요.
- 동등한 형식을 섞지 말고 방언이 선호하는 캐스팅 구문을 일관되게 사용하세요.
- 숫자 구분자 지원이 파서, 구현 코드, 테스트에서 일치하도록 유지하세요.
- 표준 SQL 기능이 존재한다고 가정하지 말고, 지원되지 않는 작업을 문서화하고 테스트하세요.
- 행 삭제가 지원되지 않으면 애플리케이션 로직에서 소프트 삭제를 명시적으로 모델링하세요.
- 파티션 수준의 삭제 작업과 행 수준의 삭제는 범위와 안전성이 다르므로 구분하세요.
- 보고되는 SQL 오류 위치는 표현식의 시작이 아니라 정확히 문제가 된 문자를 가리키게 하세요.
- 파서 오류는 메시지와 정확한 위치를 모두 테스트하세요.
- 구문, 의미, 타입, 실행 오류의 차이를 유지하세요.
## 근거가 나올 때까지 실패한 테스트를 모두 실제 결함으로 조사하기
- 모든 실패한 테스트, 실패한 CI 작업, 예상 밖의 로그 항목을 근거가 반증할 때까지 현재 존재하는 결함으로 취급하세요.
- “기존에 존재함”, “간헐적임”, “관련 없음”, “알려진 문제”는 결론이 아니라 가설입니다.
- 관련 기준선에서 재현하고, 버전 기록을 조사하고, 시간 제약을 측정하고, 권위 있는 업스트림 보고서를 확인하세요.
- 근거가 해당 결론을 강제할 때만 실패를 보류하세요.
- 다른 리뷰어가 검증할 수 있도록 분류를 정당화한 근거를 보고하세요.
- 재실행이 성공했다는 사실만으로 실패가 무해했다고 입증하지 마세요.
- 여러 변경 사항이 하나의 CI 계보를 공유할 때 상호작용 실패를 조사하세요.
- 진단에 필요한 로그, 실패 입력, 가장 작은 신뢰할 수 있는 재현을 보존하세요.
- 수정은 입증된 원인에 집중하고, 수정 없이는 실패하는 회귀 테스트를 추가하세요.
## 브랜치와 풀 리퀘스트를 머지 방식과 CI 비용에 맞추기
- 브랜치와 풀 리퀘스트 전략을 저장소의 병합 모델과 CI 비용 구조에 맞추세요.
- squash merge 워크플로에서는 폐기될 브랜치 기록을 다듬는 데 노력을 쓰지 마세요.
- 보기 좋은 기록만을 위해 이전 커밋을 다시 작성하거나 강제 푸시하지 말고 명확한 수정 커밋을 추가하세요.
- 변경을 나누면 긴 CI 실행, 간헐적 실패 노출, 병합 조율이 늘어나는 경우 관련 수정 사항을 묶으세요.
- 사용자가 요청하거나 변경 사항을 독립적으로 병합 또는 되돌려야 하는 경우에만 변경을 분리하세요.
- 기존 풀 리퀘스트를 업데이트할 때는 원격 head와 동기화하고 해당 브랜치에 변경 사항을 추가한 뒤 메타데이터를 업데이트하세요.
- 같은 변경 계보의 검증을 다시 실행하기 위해 두 번째 풀 리퀘스트를 열지 마세요.
- 저장소 정책이 다른 브랜치를 표준 리뷰 상태로 정의한다면 리뷰용 worktree를 만들거나 브랜치를 체크아웃하지 마세요.
- diff만 필요하다면 브랜치를 전환하지 말고 풀 리퀘스트 diff를 가져오세요.
- 중첩 저장소를 내부에서 먼저 커밋한 후 상위 저장소의 서브모듈 포인터를 기록하세요.
## 풀 리퀘스트와 커밋에 장점과 단점을 똑같이 적기
- 저장소가 요구하는 풀 리퀘스트 제목 규칙을 사용하고 최종 사용자에게 의미 있는 설명을 작성하세요.
- 긍정적 효과, 부정적 효과, 회귀, 절충안을 같은 비중으로 설명하세요.
- 홍보성 표현, 최상급 표현, 선택적으로 제시한 지표, 장식용 강조를 피하세요.
- 풀 리퀘스트 본문 맨 위에서 수정한 이슈를 필수 종료 형식으로 참조하세요.
- 커밋 제목은 짧고 설명적이며 저장소가 요구하는 스타일을 따르게 하세요.
- 제목을 반복하지 말고 변경 사항을 설명하는 실질적인 커밋 본문을 포함하세요.
- 체크박스나 체크 표시가 금지된 경우 테스트 계획에 일반 글머리표를 사용하세요.
- 변경 영역과 제목에 맞는 레이블을 적용하세요.
- 커밋, 풀 리퀘스트, 코드 주석에서 능동태를 사용하세요.
- 수동태로 숨기지 말고 동작하는 클래스, 메서드, 호출자 또는 컴포넌트의 이름을 밝히세요.
## 환경을 먼저 확인하고 가장 작은 범위부터 빌드와 테스트하기
- 빌드하기 전에 필요한 언어 런타임, 빌드 도구, 아키텍처, 환경 변수를 확인하세요.
- 현재 변경 사항을 입증하는 가장 작은 빌드 프로파일을 선택한 뒤 웹 또는 네이티브 아티팩트가 영향을 받으면 더 완전한 프로파일을 사용하세요.
- 로컬 아티팩트 캐시에 오래된 클라이언트나 라이브러리가 있을 수 있다면 종속 모듈을 다시 빌드하세요.
- 병렬 빌드가 서로 간섭한다면 비용이 큰 테스트 호출을 순차적으로 실행하세요.
- 관련 범위가 가장 좁은 테스트 클래스나 메서드부터 시작한 뒤 위험과 저장소 정책에 따라 확대하세요.
- 컴파일만으로 런타임 동작이 입증되었다고 간주하지 마세요.
- 지원되는 시작 경로를 통해 서버를 검증하고 직접 영향을 받는 엔드포인트나 인터페이스를 확인하세요.
- 빌드 아티팩트는 지정된 모듈 소유 위치에 보관하세요.
- 빌드가 중단되면 실패한 정확한 명령과 조치 가능한 첫 번째 오류를 기록하세요.
## Rust 경고를 없애고 JNI를 거친 panic으로 JVM이 죽지 않게 하기
- Rust 작업을 완료하기 전에 crate 루트에서 포매팅, 모든 대상 컴파일, 린팅, 라이브러리 테스트를 실행하세요.
- 모든 필수 검사에서 오류 0개와 경고 0개를 요구하세요.
- 테스트를 추가하거나 변경한 뒤 커버리지를 측정하세요.
- 커버되지 않은 각 줄에는 테스트를 추가하거나 해당 줄에 도달할 수 없음을 입증하고 그 불변 조건을 명시적으로 표시하세요.
- 파일에서 가져오거나 외부에서 제공된 데이터에 `unwrap()` 또는 `expect()`를 호출하지 마세요.
- 복구 가능한 실패는 `Result`, `Option`, 언어의 표준 오류 전파 방식으로 전달하세요.
- JNI를 넘어가는 Rust panic은 복구 없이 JVM 전체를 중단시킬 수 있음을 기억하세요.
- 저장소의 릴리스 구성으로 네이티브 C 및 C++ 라이브러리를 빌드하고 예상 아티팩트를 확인하세요.
- FFI 소유권, 수명, 정렬, 오류 변환을 명시적인 규약으로 취급하세요.
- 변경의 영향을 받는 지원 대상 플랫폼마다 경계 실패를 테스트하세요.
## 힙 할당을 피하고 속도 향상은 벤치마크로 측정하기
- GC가 없는 동작이 아키텍처 요구사항인 데이터 경로에서는 힙 할당을 피하세요.
- 버퍼와 풀링된 객체를 재사용하고 소유권 이전을 명시하세요.
- 압축과 벡터화 연산이 해당 레이아웃에 의존한다면 분석 데이터를 열 단위로 저장하세요.
- SIMD, 메모리 관리, 플랫폼별 최적화를 좁은 네이티브 경계 뒤에 두세요.
- 저장, 파싱, 계획, 코드 생성, 실행, 프로토콜 처리, 백그라운드 작업을 분리하세요.
- 할당 및 정리 동작을 이해하고 테스트한 경우에만 사용자 정의 컬렉션을 사용하세요.
- 직관이 아니라 대표성 있는 벤치마크로 성능 변화를 측정하세요.
- 최적화에는 정확성 테스트, 리소스 검사, 문서화된 절충안을 함께 제공하세요.
- 측정되지 않은 속도 향상을 얻기 위해 호환성이나 오류 정밀도를 약화하지 마세요.
## 완료라고 말하기 전에 최종 diff를 확인하고 결과 보고하기
- 최종 diff에서 멤버 순서, 호환성 경계, NULL 동작, 리소스 소유권, 로그에 실수로 포함된 유니코드를 검토하세요.
- 변경의 영향을 받는 Java, SQL, Rust, 네이티브, 통합 검사를 집중적으로 실행하세요.
- 결정론적 쿼리가 재읽기를 포함한 강력한 어설션 경로를 사용하는지 확인하세요.
- 외부 입력이 복구 불가능한 네이티브 panic을 유발할 수 없는지 확인하세요.
- 조사한 모든 실패에 근거 기반 분류와 보고된 재현이 있는지 검증하세요.
- 풀 리퀘스트 메타데이터, 레이블, 테스트 계획, 커밋 문구, 이슈 참조가 저장소 정책과 일치하는지 확인하세요.
- 중첩 저장소와 상위 포인터가 올바른 순서로 커밋되었는지 확인하세요.
- 필수 검사에 오류나 경고가 있는 동안 완료를 선언하지 마세요.
- 실행한 명령, 관찰한 결과, 남은 위험, 의도적으로 테스트하지 않은 범위를 보고하세요.
