-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Summary
When using soft-delete with cross-database JOINs, the generated WHERE condition for deleted_at is missing the table alias qualifier, causing Column 'deleted_at' in WHERE is ambiguous error. This affects all drivers that use information_schema for TableFields() (MariaDB, PgSQL, GaussDB, etc.), but NOT MySQL which uses SHOW FULL COLUMNS FROM.
Reproduction
Two tables with deleted_at columns in different databases:
// test1.demo_a has deleted_at
// test2.demo_b has deleted_at
all, err := db.Model("test1.demo_a").As("a").
LeftJoin("test2.demo_b b", "a.id=b.id").
Fields("a.id", "b.nickname").All()Expected SQL:
SELECT a.id,b.nickname FROM `test1`.`demo_a` AS a LEFT JOIN `test2`.`demo_b` b ON (a.id=b.id) WHERE `a`.`deleted_at` IS NULL AND `b`.`deleted_at` IS NULLActual SQL (MariaDB):
SELECT a.id,b.nickname FROM `test1`.`demo_a` AS a LEFT JOIN `test2`.`demo_b` b ON (a.id=b.id) WHERE `deleted_at` IS NULLError: Error 1052 (23000): Column 'deleted_at' in WHERE is ambiguous
Root Cause
In gdb_model_soft_time.go, getConditionOfTableStringForSoftDeleting() (line 245-269) parses table strings like `test1`.`demo_a` AS a and extracts schema/table names with quote characters intact (e.g., `test1` instead of test1).
These quoted names are passed to Model.TableFields() in gdb_model_utility.go (line 34-50). There, usedTable is properly unquoted via guessPrimaryTableName() (line 37), but usedSchema is NOT unquoted (line 38):
usedTable = m.db.GetCore().guessPrimaryTableName(tableStr) // strips quotes ✓
usedSchema = gutil.GetOrDefaultStr(m.schema, schema...) // keeps quotes ✗For drivers using information_schema queries (MariaDB, PgSQL, GaussDB), the quoted schema name is interpolated directly into SQL:
WHERE c.TABLE_SCHEMA = '`test1`' -- expects literal backtick charactersSince information_schema.COLUMNS stores schema names without quotes (test1), the query returns empty results. GetFieldInfo() then returns empty, and soft-delete falls back to single-table mode, generating an unqualified WHERE deleted_at IS NULL.
MySQL avoids this because SHOW FULL COLUMNS FROM doesn't use the schema parameter in its SQL query.
Affected Drivers
All drivers that override TableFields() with information_schema queries:
- MariaDB
- PgSQL (uses
"double quotes instead of backticks) - GaussDB
- Potentially others
Suggested Fix
In gdb_model_utility.go, strip quote characters from usedSchema the same way guessPrimaryTableName strips them from usedTable:
charL, charR := m.db.GetCore().db.GetChars()
usedSchema = gstr.Trim(usedSchema, charL+charR)ref #4689