Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
86219914
Commit
86219914
authored
Feb 14, 2026
by
yangjianbo
Browse files
fix(ops): 修复错误日志查询 q 过滤列名二义性
parent
57e8abcb
Changes
2
Hide whitespace changes
Inline
Side-by-side
backend/internal/repository/ops_repo.go
View file @
86219914
...
...
@@ -1194,7 +1194,7 @@ func buildOpsErrorLogsWhere(filter *service.OpsErrorLogFilter) (string, []any) {
}
// Keep list endpoints scoped to client errors unless explicitly filtering upstream phase.
if
phaseFilter
!=
"upstream"
{
clauses
=
append
(
clauses
,
"COALESCE(status_code, 0) >= 400"
)
clauses
=
append
(
clauses
,
"COALESCE(
e.
status_code, 0) >= 400"
)
}
if
filter
.
StartTime
!=
nil
&&
!
filter
.
StartTime
.
IsZero
()
{
...
...
@@ -1208,33 +1208,33 @@ func buildOpsErrorLogsWhere(filter *service.OpsErrorLogFilter) (string, []any) {
}
if
p
:=
strings
.
TrimSpace
(
filter
.
Platform
);
p
!=
""
{
args
=
append
(
args
,
p
)
clauses
=
append
(
clauses
,
"platform = $"
+
itoa
(
len
(
args
)))
clauses
=
append
(
clauses
,
"
e.
platform = $"
+
itoa
(
len
(
args
)))
}
if
filter
.
GroupID
!=
nil
&&
*
filter
.
GroupID
>
0
{
args
=
append
(
args
,
*
filter
.
GroupID
)
clauses
=
append
(
clauses
,
"group_id = $"
+
itoa
(
len
(
args
)))
clauses
=
append
(
clauses
,
"
e.
group_id = $"
+
itoa
(
len
(
args
)))
}
if
filter
.
AccountID
!=
nil
&&
*
filter
.
AccountID
>
0
{
args
=
append
(
args
,
*
filter
.
AccountID
)
clauses
=
append
(
clauses
,
"account_id = $"
+
itoa
(
len
(
args
)))
clauses
=
append
(
clauses
,
"
e.
account_id = $"
+
itoa
(
len
(
args
)))
}
if
phase
:=
phaseFilter
;
phase
!=
""
{
args
=
append
(
args
,
phase
)
clauses
=
append
(
clauses
,
"error_phase = $"
+
itoa
(
len
(
args
)))
clauses
=
append
(
clauses
,
"
e.
error_phase = $"
+
itoa
(
len
(
args
)))
}
if
filter
!=
nil
{
if
owner
:=
strings
.
TrimSpace
(
strings
.
ToLower
(
filter
.
Owner
));
owner
!=
""
{
args
=
append
(
args
,
owner
)
clauses
=
append
(
clauses
,
"LOWER(COALESCE(error_owner,'')) = $"
+
itoa
(
len
(
args
)))
clauses
=
append
(
clauses
,
"LOWER(COALESCE(
e.
error_owner,'')) = $"
+
itoa
(
len
(
args
)))
}
if
source
:=
strings
.
TrimSpace
(
strings
.
ToLower
(
filter
.
Source
));
source
!=
""
{
args
=
append
(
args
,
source
)
clauses
=
append
(
clauses
,
"LOWER(COALESCE(error_source,'')) = $"
+
itoa
(
len
(
args
)))
clauses
=
append
(
clauses
,
"LOWER(COALESCE(
e.
error_source,'')) = $"
+
itoa
(
len
(
args
)))
}
}
if
resolvedFilter
!=
nil
{
args
=
append
(
args
,
*
resolvedFilter
)
clauses
=
append
(
clauses
,
"COALESCE(resolved,false) = $"
+
itoa
(
len
(
args
)))
clauses
=
append
(
clauses
,
"COALESCE(
e.
resolved,false) = $"
+
itoa
(
len
(
args
)))
}
// View filter: errors vs excluded vs all.
...
...
@@ -1246,46 +1246,46 @@ func buildOpsErrorLogsWhere(filter *service.OpsErrorLogFilter) (string, []any) {
}
switch
view
{
case
""
,
"errors"
:
clauses
=
append
(
clauses
,
"COALESCE(is_business_limited,false) = false"
)
clauses
=
append
(
clauses
,
"COALESCE(
e.
is_business_limited,false) = false"
)
case
"excluded"
:
clauses
=
append
(
clauses
,
"COALESCE(is_business_limited,false) = true"
)
clauses
=
append
(
clauses
,
"COALESCE(
e.
is_business_limited,false) = true"
)
case
"all"
:
// no-op
default
:
// treat unknown as default 'errors'
clauses
=
append
(
clauses
,
"COALESCE(is_business_limited,false) = false"
)
clauses
=
append
(
clauses
,
"COALESCE(
e.
is_business_limited,false) = false"
)
}
if
len
(
filter
.
StatusCodes
)
>
0
{
args
=
append
(
args
,
pq
.
Array
(
filter
.
StatusCodes
))
clauses
=
append
(
clauses
,
"COALESCE(upstream_status_code, status_code, 0) = ANY($"
+
itoa
(
len
(
args
))
+
")"
)
clauses
=
append
(
clauses
,
"COALESCE(
e.
upstream_status_code,
e.
status_code, 0) = ANY($"
+
itoa
(
len
(
args
))
+
")"
)
}
else
if
filter
.
StatusCodesOther
{
// "Other" means: status codes not in the common list.
known
:=
[]
int
{
400
,
401
,
403
,
404
,
409
,
422
,
429
,
500
,
502
,
503
,
504
,
529
}
args
=
append
(
args
,
pq
.
Array
(
known
))
clauses
=
append
(
clauses
,
"NOT (COALESCE(upstream_status_code, status_code, 0) = ANY($"
+
itoa
(
len
(
args
))
+
"))"
)
clauses
=
append
(
clauses
,
"NOT (COALESCE(
e.
upstream_status_code,
e.
status_code, 0) = ANY($"
+
itoa
(
len
(
args
))
+
"))"
)
}
// Exact correlation keys (preferred for request↔upstream linkage).
if
rid
:=
strings
.
TrimSpace
(
filter
.
RequestID
);
rid
!=
""
{
args
=
append
(
args
,
rid
)
clauses
=
append
(
clauses
,
"COALESCE(request_id,'') = $"
+
itoa
(
len
(
args
)))
clauses
=
append
(
clauses
,
"COALESCE(
e.
request_id,'') = $"
+
itoa
(
len
(
args
)))
}
if
crid
:=
strings
.
TrimSpace
(
filter
.
ClientRequestID
);
crid
!=
""
{
args
=
append
(
args
,
crid
)
clauses
=
append
(
clauses
,
"COALESCE(client_request_id,'') = $"
+
itoa
(
len
(
args
)))
clauses
=
append
(
clauses
,
"COALESCE(
e.
client_request_id,'') = $"
+
itoa
(
len
(
args
)))
}
if
q
:=
strings
.
TrimSpace
(
filter
.
Query
);
q
!=
""
{
like
:=
"%"
+
q
+
"%"
args
=
append
(
args
,
like
)
n
:=
itoa
(
len
(
args
))
clauses
=
append
(
clauses
,
"(request_id ILIKE $"
+
n
+
" OR client_request_id ILIKE $"
+
n
+
" OR error_message ILIKE $"
+
n
+
")"
)
clauses
=
append
(
clauses
,
"(
e.
request_id ILIKE $"
+
n
+
" OR
e.
client_request_id ILIKE $"
+
n
+
" OR
e.
error_message ILIKE $"
+
n
+
")"
)
}
if
userQuery
:=
strings
.
TrimSpace
(
filter
.
UserQuery
);
userQuery
!=
""
{
like
:=
"%"
+
userQuery
+
"%"
args
=
append
(
args
,
like
)
n
:=
itoa
(
len
(
args
))
clauses
=
append
(
clauses
,
"u.email ILIKE $"
+
n
)
clauses
=
append
(
clauses
,
"
EXISTS (SELECT 1 FROM users u WHERE u.id = e.user_id AND
u.email ILIKE $"
+
n
+
")"
)
}
return
"WHERE "
+
strings
.
Join
(
clauses
,
" AND "
),
args
...
...
backend/internal/repository/ops_repo_error_where_test.go
0 → 100644
View file @
86219914
package
repository
import
(
"strings"
"testing"
"github.com/Wei-Shaw/sub2api/internal/service"
)
func
TestBuildOpsErrorLogsWhere_QueryUsesQualifiedColumns
(
t
*
testing
.
T
)
{
filter
:=
&
service
.
OpsErrorLogFilter
{
Query
:
"ACCESS_DENIED"
,
}
where
,
args
:=
buildOpsErrorLogsWhere
(
filter
)
if
where
==
""
{
t
.
Fatalf
(
"where should not be empty"
)
}
if
len
(
args
)
!=
1
{
t
.
Fatalf
(
"args len = %d, want 1"
,
len
(
args
))
}
if
!
strings
.
Contains
(
where
,
"e.request_id ILIKE $"
)
{
t
.
Fatalf
(
"where should include qualified request_id condition: %s"
,
where
)
}
if
!
strings
.
Contains
(
where
,
"e.client_request_id ILIKE $"
)
{
t
.
Fatalf
(
"where should include qualified client_request_id condition: %s"
,
where
)
}
if
!
strings
.
Contains
(
where
,
"e.error_message ILIKE $"
)
{
t
.
Fatalf
(
"where should include qualified error_message condition: %s"
,
where
)
}
}
func
TestBuildOpsErrorLogsWhere_UserQueryUsesExistsSubquery
(
t
*
testing
.
T
)
{
filter
:=
&
service
.
OpsErrorLogFilter
{
UserQuery
:
"admin@"
,
}
where
,
args
:=
buildOpsErrorLogsWhere
(
filter
)
if
where
==
""
{
t
.
Fatalf
(
"where should not be empty"
)
}
if
len
(
args
)
!=
1
{
t
.
Fatalf
(
"args len = %d, want 1"
,
len
(
args
))
}
if
!
strings
.
Contains
(
where
,
"EXISTS (SELECT 1 FROM users u WHERE u.id = e.user_id AND u.email ILIKE $"
)
{
t
.
Fatalf
(
"where should include EXISTS user email condition: %s"
,
where
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment