Skip to content

database/gdb: soft-delete WHERE condition missing table alias in cross-database JOIN for non-MySQL drivers #4725

@lingcoder

Description

@lingcoder

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 NULL

Actual 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 NULL

Error: 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 characters

Since 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions