Drizzle로 태그 필터 검색을 만들고 있습니다. 사용자가 고른 태그 ID 배열을 inArray로 거는데, 아무 태그도 선택 안 하면 배열이 빈 배열([])이 됩니다. 이때 결과가 0건이 아니라 테이블 전체가 다 나와버립니다.
const rows = await db.select().from(posts)
.where(inArray(posts.tagId, selectedIds)) // selectedIds = []SQL 로그를 찍어보니 where 절이 아예 안 붙거나 이상하게 나가는 것 같습니다. 상식적으로 빈 배열이면 '해당하는 게 없다'니까 0건이어야 하는 거 아닌가요? 아니면 제가 뭔가 잘못 이해하고 있는 걸까요? 하마터면 비공개 글까지 다 노출될 뻔했습니다.
댓글 3
예전 Drizzle은 inArray([]) 를 만나면 조건을 통째로 흘려버려서 where 절이 사실상 사라지고 전체가 나오는 동작이었습니다. 지금 겪는 게 정확히 그거예요. 논리적으로는 빈 IN이 항상 false(0건)여야 맞는데, 옛 구현이 그렇게 안 돼 있었던 거죠.
버전 의존적인 동작이라 여기 기대면 안 됩니다. 확실한 방법은 애플리케이션에서 빈 배열을 명시적으로 방어하는 거예요. selectedIds가 비면 그 필터를 아예 빼거나(전체 의도라면), 반대로 0건이 의도라면 조건을 강제로 거짓으로 만드세요.
const cond = selectedIds.length ? inArray(posts.tagId, selectedIds) : sql`false`
이렇게 두면 버전이 뭐든 의도대로 0건이 나옵니다. 참고로 쓰고 계신 drizzle-orm 버전이 몇인지 알려주시면 이 버전이 빈 배열을 어떻게 처리하는지 정확히 짚어드릴게요.
다만 버전 올린다고 앱 방어를 빼는 건 추천 안 합니다. 이유가 있어요. 팀에 사람이 여럿이면 각자 로컬 lockfile 버전이 미묘하게 섞이고, 라이브러리 하나 동작에 보안 경계를 통째로 맡기면 나중에 누가 다운그레이드하거나 다른 프로젝트로 코드 복사했을 때 조용히 전체 노출로 돌아옵니다. 실제로 이 빈 배열 필터가 프로덕션에서 접근제어를 통째로 무력화한 사고가 드물지 않아요. 방금 '비공개 글까지 다 노출될 뻔했다'고 하셨죠, 그게 딱 그 사고의 전형입니다.
그러니 버전은 올리되, 빈 배열 분기는 코드에 명시적으로 남겨두세요. 라이브러리 동작이 어떻든 내 코드가 의도를 못 박고 있으면 버전이 바뀌어도 안 깨집니다.