Skip to content

SQL Functions (UPPER/LOWER) + JOINs Cause Hang **Severity:** ⚠️ CRITICAL #6

@LukasGPC

Description

@LukasGPC

Severity: ⚠️ CRITICAL

Description:
Using SQL functions like UPPER() or LOWER() in WHERE clauses combined with JOIN operations causes the driver to hang indefinitely.

Symptoms:

  • Query hangs indefinitely
  • No error message or timeout
  • Application becomes unresponsive

Minimal Reproduction:

func authenticateUser(db *sql.DB, username string) error {
    // This query hangs indefinitely
    query := `
        SELECT
            u.PUser_ID, u.PUser_Name,
            ut.PUser_Type_Name,
            o.Org_Name
        FROM GPC.Platform_User u
        LEFT JOIN GPC.Platform_User_Type ut ON u.PUser_User_Type_ID = ut.PUser_Type_ID
        LEFT JOIN GPC.Organization o ON u.PUser_Organisation_ID = o.Org_ID
        WHERE UPPER(u.PUser_Name) = UPPER(?)
    `

    var userID, userName, typeName, orgName string
    err := db.QueryRow(query, username).Scan(&userID, &userName, &typeName, &orgName)
    // Hangs here - never returns

    return err
}

Workaround:
Split into separate queries - use functions only in queries without JOINs:

func authenticateUser(db *sql.DB, username string) error {
    // Query 1: Get user (no JOINs, UPPER() is safe)
    query1 := `
        SELECT PUser_ID, PUser_Name, PUser_User_Type_ID, PUser_Organisation_ID
        FROM GPC.Platform_User
        WHERE UPPER(PUser_Name) = UPPER(?)
    `
    var userID, userName, userTypeID, orgID string
    db.QueryRow(query1, username).Scan(&userID, &userName, &userTypeID, &orgID)

    // Query 2: Get user type name (separate, no JOIN)
    query2 := `SELECT PUser_Type_Name FROM GPC.Platform_User_Type WHERE PUser_Type_ID = ?`
    var typeName string
    db.QueryRow(query2, userTypeID).Scan(&typeName)

    // Query 3: Get org name (separate, no JOIN)
    query3 := `SELECT Org_Name FROM GPC.Organization WHERE Org_ID = ?`
    var orgName string
    db.QueryRow(query3, orgID).Scan(&orgName)

    return nil
}

Impact: High - requires splitting authentication/search queries into multiple round-trips, reduces performance.


Metadata

Metadata

Assignees

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