fix: jsonb_set 嵌套路径无法创建多层 key 的问题

PostgreSQL jsonb_set 在 create_if_missing=true 时无法一次性创建多层嵌套路径。
例如设置 {antigravity_quota_scopes,gemini_image} 时,如果 antigravity_quota_scopes 不存在,
jsonb_set 不会自动创建外层 key,导致更新静默失败(affected=1 但数据未变)。

修复方案:嵌套两次 jsonb_set,先确保外层 key 存在,再设置内层值。

影响范围:
- SetAntigravityQuotaScopeLimit: Antigravity 平台按模型 scope 限流
- SetModelRateLimit: Anthropic 平台 Sonnet 模型限流
This commit is contained in:
song
2026-01-26 23:40:48 +08:00
parent e316a923d4
commit 4b57e80e6a

View File

@@ -809,12 +809,21 @@ func (r *accountRepository) SetAntigravityQuotaScopeLimit(ctx context.Context, i
return err return err
} }
path := "{antigravity_quota_scopes," + string(scope) + "}" scopeKey := string(scope)
client := clientFromContext(ctx, r.client) client := clientFromContext(ctx, r.client)
result, err := client.ExecContext( result, err := client.ExecContext(
ctx, ctx,
"UPDATE accounts SET extra = jsonb_set(COALESCE(extra, '{}'::jsonb), $1::text[], $2::jsonb, true), updated_at = NOW(), last_used_at = NOW() WHERE id = $3 AND deleted_at IS NULL", `UPDATE accounts SET
path, extra = jsonb_set(
jsonb_set(COALESCE(extra, '{}'::jsonb), '{antigravity_quota_scopes}'::text[], COALESCE(extra->'antigravity_quota_scopes', '{}'::jsonb), true),
ARRAY['antigravity_quota_scopes', $1]::text[],
$2::jsonb,
true
),
updated_at = NOW(),
last_used_at = NOW()
WHERE id = $3 AND deleted_at IS NULL`,
scopeKey,
raw, raw,
id, id,
) )
@@ -829,6 +838,7 @@ func (r *accountRepository) SetAntigravityQuotaScopeLimit(ctx context.Context, i
if affected == 0 { if affected == 0 {
return service.ErrAccountNotFound return service.ErrAccountNotFound
} }
if err := enqueueSchedulerOutbox(ctx, r.sql, service.SchedulerOutboxEventAccountChanged, &id, nil, nil); err != nil { if err := enqueueSchedulerOutbox(ctx, r.sql, service.SchedulerOutboxEventAccountChanged, &id, nil, nil); err != nil {
log.Printf("[SchedulerOutbox] enqueue quota scope failed: account=%d err=%v", id, err) log.Printf("[SchedulerOutbox] enqueue quota scope failed: account=%d err=%v", id, err)
} }
@@ -849,12 +859,19 @@ func (r *accountRepository) SetModelRateLimit(ctx context.Context, id int64, sco
return err return err
} }
path := "{model_rate_limits," + scope + "}"
client := clientFromContext(ctx, r.client) client := clientFromContext(ctx, r.client)
result, err := client.ExecContext( result, err := client.ExecContext(
ctx, ctx,
"UPDATE accounts SET extra = jsonb_set(COALESCE(extra, '{}'::jsonb), $1::text[], $2::jsonb, true), updated_at = NOW() WHERE id = $3 AND deleted_at IS NULL", `UPDATE accounts SET
path, extra = jsonb_set(
jsonb_set(COALESCE(extra, '{}'::jsonb), '{model_rate_limits}'::text[], COALESCE(extra->'model_rate_limits', '{}'::jsonb), true),
ARRAY['model_rate_limits', $1]::text[],
$2::jsonb,
true
),
updated_at = NOW()
WHERE id = $3 AND deleted_at IS NULL`,
scope,
raw, raw,
id, id,
) )