Files
3x-ui/database/dialect.go
MHSanaei 8a28373a01 fix(nodes): use GREATEST for last_online merge on PostgreSQL
setRemoteTrafficLocked merged last_online with MAX(last_online, ?), which
is SQLite's two-argument scalar max. PostgreSQL's MAX() is aggregate-only,
so node traffic sync failed every cycle with "function max(bigint, unknown)
does not exist (SQLSTATE 42883)", flooding the logs.

Add a dialect-aware database.GreatestExpr helper (GREATEST on Postgres,
MAX on SQLite) and use it for the last_online merge. last_online is a
non-null int64, so the two functions are semantically identical here.

Closes #4633
2026-05-29 02:04:02 +02:00

29 lines
865 B
Go

package database
import "fmt"
// JSONClientsFromInbound returns the FROM clause that yields one row per element
// of inbounds.settings -> clients, with a column named `client.value` whose text
// fields can be read with JSONFieldText("client.value", "<key>").
func JSONClientsFromInbound() string {
if IsPostgres() {
return "FROM inbounds, jsonb_array_elements(inbounds.settings::jsonb -> 'clients') AS client(value)"
}
return "FROM inbounds, JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client"
}
func JSONFieldText(expr, key string) string {
if IsPostgres() {
return fmt.Sprintf("(%s ->> '%s')", expr, key)
}
return fmt.Sprintf("TRIM(JSON_EXTRACT(%s, '$.%s'), '\"')", expr, key)
}
func GreatestExpr(a, b string) string {
if IsPostgres() {
return fmt.Sprintf("GREATEST(%s, %s)", a, b)
}
return fmt.Sprintf("MAX(%s, %s)", a, b)
}