-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Go version
go version go1.24 windows/amd64
GoFrame version
v2.9.0
Can this bug be reproduced with the latest release?
Option Yes
What did you do?
I encountered inconsistent SQL generation when using
FieldsPrefix
in JOIN queries across different database drivers. The same GoFrame ORM code generates different field selections between MySQL and PostgreSQL drivers.
What did you see happen?
package main
import (
"context"
"fmt"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
)
func main() {
sqlstr, err := gdb.ToSQL(gctx.New(), func(ctx context.Context) error {
_, err := dao.OpenApp.Ctx(ctx).OmitEmpty().As("t1").
LeftJoin(dao.MemberInfo.Table(), "t2", "t1.app_id = t2.uid").
FieldsPrefix("t2", dao.MemberInfo.Columns().Id, dao.MemberInfo.Columns().DisplayName).
All()
return err
})
fmt.Println(sqlstr)Table Structures:
-- Verify search_path is set correctly
SHOW search_path; -- Should return: abc, public
-- Tables are in 'abc' schema
CREATE SCHEMA abc;
-- open_app table
CREATE TABLE abc.open_app (
id BIGINT PRIMARY KEY,
app_id VARCHAR(100),
deleted_at TIMESTAMP
);
-- member_info table
CREATE TABLE abc.member_info (
id BIGINT PRIMARY KEY,
uid VARCHAR(100),
display_name VARCHAR(100),
deleted_at TIMESTAMP
);Then I see:
SELECT * FROM "open_app" AS t1 LEFT JOIN "member_info" AS "t2" ON (t1.app_id = t2.uid) WHERE "t1"."deleted_at" IS NULL AND "t2"."deleted_at" IS NULL
Issue: The
FieldsPrefix("t2", dao.MemberInfo.Columns().Id, dao.MemberInfo.Columns().DisplayName)
is completely ignored.
Root Cause
GoFrame's
TableFields()
method only searches the public schema, ignoring the configured search_path. When tables are in a different schema (like abc), field validation fails and the query falls back to SELECT *.
Impact
Unnecessary SELECT * queries
Breaks schema-based multi-tenant applications
Workaround
Use explicit
Fields()
:
go
.Fields("t2.id", "t2.display_name")
What did you expect to see?
SELECT t2.id, t2.display_name FROM "open_app" AS t1
LEFT JOIN "member_info" AS "t2" ON (t1.app_id = t2.uid)
WHERE "t1"."deleted_at" IS NULL AND "t2"."deleted_at" IS NULL