gf icon indicating copy to clipboard operation
gf copied to clipboard

database/gdb: FieldsPrefix generates inconsistent SQL across different database drivers in JOIN queries

Open lingcoder opened this issue 4 months ago • 1 comments

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

lingcoder avatar Aug 06 '25 13:08 lingcoder

Image

lingcoder avatar Aug 06 '25 13:08 lingcoder