mirror of
https://github.com/iflytek/skillhub.git
synced 2026-08-28 11:25:00 +00:00
fix(namespace): stop the backfill from querying with a null keyword
The backfill preview returned 500 on PostgreSQL:
SQLState 42883: function lower(bytea) does not exist
It reused UserAccountRepository.search(keyword, status, pageable) with a
null keyword. That query compares the keyword with lower(...), and a null
bind leaves PostgreSQL to infer the parameter type as bytea, so lower()
has no matching signature.
Nothing had exercised that branch before: the admin user list goes through
AdminUserSearchRepository, and the member-candidate lookup always passes a
real keyword. The backfill was the first caller to pass null.
Give callers that want every account in a status a query without a keyword
to bind, rather than papering over the null with a cast or an empty string.
Neither test layer would have caught this. The unit tests mock the
repository, and the integration tests run on H2 in PostgreSQL mode, which
accepts the null-typed bind that PostgreSQL rejects. Verified instead
against a real PostgreSQL: preview, apply, and a second preview showing
alreadyProvisioned with nothing left to do, with namespace_member rows
confirming each owner holds OWNER on a TEAM namespace.
This commit is contained in:
parent
2d50437e4f
commit
639e081ca7
3 changed files with 13 additions and 2 deletions
|
|
@ -141,7 +141,7 @@ public class PersonalNamespaceProvisioningService {
|
|||
boolean truncated = false;
|
||||
|
||||
for (int page = 0; !truncated; page++) {
|
||||
Page<UserAccount> batch = userAccountRepository.search(null, UserStatus.ACTIVE,
|
||||
Page<UserAccount> batch = userAccountRepository.findByStatus(UserStatus.ACTIVE,
|
||||
PageRequest.of(page, BACKFILL_PAGE_SIZE, Sort.by("id")));
|
||||
if (batch.isEmpty()) {
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -14,5 +14,16 @@ public interface UserAccountRepository {
|
|||
List<UserAccount> findByIdIn(List<String> ids);
|
||||
Optional<UserAccount> findByEmailIgnoreCase(String email);
|
||||
Page<UserAccount> search(String keyword, UserStatus status, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Lists accounts in one status.
|
||||
*
|
||||
* <p>Separate from {@link #search} on purpose: that query compares the keyword with
|
||||
* {@code lower(...)}, and passing a null keyword leaves PostgreSQL to infer the bind type as
|
||||
* {@code bytea}, which fails with "function lower(bytea) does not exist". Callers that want
|
||||
* every account in a status have no keyword to give, so they get a query without one.
|
||||
*/
|
||||
Page<UserAccount> findByStatus(UserStatus status, Pageable pageable);
|
||||
|
||||
UserAccount save(UserAccount user);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class PersonalNamespaceProvisioningServiceTest {
|
|||
}
|
||||
|
||||
private void directoryContains(UserAccount... users) {
|
||||
when(userAccountRepository.search(isNull(), eq(UserStatus.ACTIVE), any()))
|
||||
when(userAccountRepository.findByStatus(eq(UserStatus.ACTIVE), any()))
|
||||
.thenReturn(new PageImpl<>(List.of(users)));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue