From dcc02628e8ce2d2fb8364e226080b0e7a8bd3e0b Mon Sep 17 00:00:00 2001 From: "donghyuck, son" Date: Thu, 30 Apr 2026 14:56:46 +0900 Subject: [PATCH] =?UTF-8?q?[ai-assisted]=20fix(vector):=20points=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20ORDER=20BY=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: - #384 Why: - Java text block의 줄 끝 공백 제거로 points 조회 SQL이 ORDER BYp.display_order 형태로 조립되어 PostgreSQL 문법 오류가 발생했다. What: - ORDER BY 절을 일반 문자열 helper로 생성해 ORDER BY와 정렬 표현식 사이 공백을 보장했다. - ORDER BY 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: proj-20260430044829-105b3fa0 points query가 ORDER BY 포함 상태로 5건 조회됨 --- .../JdbcVectorProjectionPointRepository.java | 2 +- .../ai/service/visualization/JdbcVectorProjectionSql.java | 4 ++++ .../visualization/JdbcVectorProjectionSqlTest.java | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionPointRepository.java b/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionPointRepository.java index 986c3719..0f1529d7 100644 --- a/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionPointRepository.java +++ b/starter/studio-platform-starter-ai/src/main/java/studio/one/platform/ai/service/visualization/JdbcVectorProjectionPointRepository.java @@ -93,7 +93,7 @@ SELECT COUNT(*) ON p.vector_item_id = """ + pointJoinExpression() + """ WHERE p.projection_id = :projectionId """ + where + """ - ORDER BY """ + JdbcVectorProjectionSql.orderByDisplayOrder(postgres) + """ + """ + JdbcVectorProjectionSql.orderByDisplayOrderClause(postgres) + """ LIMIT :limit OFFSET :offset """, params, rowMapper); return new ProjectionPointPage(total == null ? 0L : total, items); 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 4671d9c7..8315a461 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 @@ -48,4 +48,8 @@ static String orderByDisplayOrder(boolean postgres) { } return "p.display_order IS NULL, p.display_order, p.vector_item_id"; } + + static String orderByDisplayOrderClause(boolean postgres) { + return " ORDER BY " + orderByDisplayOrder(postgres); + } } 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 aa5ad10e..a100a6c7 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 @@ -29,4 +29,12 @@ void mysqlJsonTextUsesParameterizedPath() { assertThat(JdbcVectorProjectionSql.jsonText(null, ":filterKey0", false)) .isEqualTo("JSON_UNQUOTE(JSON_EXTRACT(metadata, CONCAT('$.', :filterKey0)))"); } + + @Test + void orderByDisplayOrderClauseKeepsSpaceAfterOrderBy() { + assertThat(JdbcVectorProjectionSql.orderByDisplayOrderClause(true)) + .isEqualTo(" ORDER BY p.display_order NULLS LAST, p.vector_item_id"); + assertThat("WHERE p.projection_id = :projectionId" + JdbcVectorProjectionSql.orderByDisplayOrderClause(true)) + .contains(" ORDER BY p.display_order"); + } }