From 3499ad6697e9e4d375287f54f0af8e88b0b649e8 Mon Sep 17 00:00:00 2001 From: "donghyuck, son" Date: Thu, 30 Apr 2026 15:24:56 +0900 Subject: [PATCH] =?UTF-8?q?[ai-assisted]=20fix(vector):=20item=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20SQL=20=EC=A1=B0=EB=A6=BD=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: - #386 Why: - Vector Map에서 Top-K 결과나 산점도 점 선택 시 item 상세 조회 SQL이 WHEREmetadata, chunkIdIN, OR'row-' 형태로 조립되어 PostgreSQL 문법 오류가 발생했다. What: - vector item id 매칭 WHERE 절을 일반 문자열 helper로 생성해 WHERE, IN, OR 주변 공백을 보장했다. - chunkId, row-{id}, documentId 매칭 clause 회귀 테스트를 추가했다. Validation: - ./gradlew :starter:studio-platform-starter-ai:test --tests '*JdbcVectorProjectionSqlTest' : PASS - ./gradlew :starter:studio-platform-starter-ai:test :starter:studio-platform-starter-ai-web:test && git diff --check : PASS - 로컬 PostgreSQL smoke: vectorItemId 6-18 상세 조회 조건이 1건 조회됨 --- .../visualization/JdbcExistingVectorItemRepository.java | 7 +------ .../ai/service/visualization/JdbcVectorProjectionSql.java | 6 ++++++ .../visualization/JdbcVectorProjectionSqlTest.java | 8 ++++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcExistingVectorItemRepository.java b/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcExistingVectorItemRepository.java index 5ca34abb..9e457171 100644 --- a/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcExistingVectorItemRepository.java +++ b/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcExistingVectorItemRepository.java @@ -81,12 +81,7 @@ public List findByVectorItemIds(Collection vectorItemIds) { return jdbcTemplate.query(""" SELECT id, object_type, object_id, chunk_index, text, embedding, metadata, created_at FROM tb_ai_document_chunk - WHERE """ + jsonText(null, "chunkId") + """ - IN (:ids) - OR """ + rowVectorItemId("id") + """ - IN (:ids) - OR """ + jsonText(null, "documentId") + """ - IN (:ids) + """ + JdbcVectorProjectionSql.vectorItemIdMatchClause(postgres) + """ ORDER BY object_type, object_id, chunk_index, id """, new MapSqlParameterSource("ids", ids), rowMapper); } diff --git a/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionSql.java b/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionSql.java index 8315a461..208cf226 100644 --- a/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionSql.java +++ b/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionSql.java @@ -52,4 +52,10 @@ static String orderByDisplayOrder(boolean postgres) { static String orderByDisplayOrderClause(boolean postgres) { return " ORDER BY " + orderByDisplayOrder(postgres); } + + static String vectorItemIdMatchClause(boolean postgres) { + return " WHERE " + jsonText(null, "chunkId", postgres) + " IN (:ids)" + + " OR " + rowVectorItemId("id", postgres) + " IN (:ids)" + + " OR " + jsonText(null, "documentId", postgres) + " IN (:ids)"; + } } diff --git a/starter/studio-platform-starter-ai/src/test/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionSqlTest.java b/starter/studio-platform-starter-ai/src/test/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionSqlTest.java index a100a6c7..310bbf5f 100644 --- a/starter/studio-platform-starter-ai/src/test/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionSqlTest.java +++ b/starter/studio-platform-starter-ai/src/test/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionSqlTest.java @@ -37,4 +37,12 @@ void orderByDisplayOrderClauseKeepsSpaceAfterOrderBy() { assertThat("WHERE p.projection_id = :projectionId" + JdbcVectorProjectionSql.orderByDisplayOrderClause(true)) .contains(" ORDER BY p.display_order"); } + + @Test + void vectorItemIdMatchClauseKeepsSpacesAroundWhereInAndOr() { + assertThat(JdbcVectorProjectionSql.vectorItemIdMatchClause(true)) + .isEqualTo(" WHERE metadata ->> 'chunkId' IN (:ids)" + + " OR 'row-' || id IN (:ids)" + + " OR metadata ->> 'documentId' IN (:ids)"); + } }