-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Severity:
Description:
Queries that reference invalid foreign key GUIDs (GUIDs that don't exist in the referenced table) cause the driver to hang indefinitely instead of returning an error or empty result.
Symptoms:
- Query hangs indefinitely
- No error message or timeout
- Graceful shutdown fails (30s timeout)
- Connection remains open indefinitely
- Typically discovered during authentication or data retrieval
Minimal Reproduction:
-- Step 1: Insert user with invalid org_id (GUID doesn't exist in Organization table)
INSERT INTO GPC.Platform_User (
PUser_ID,
PUser_Name,
PUser_Organisation_ID
) VALUES (
NEWID(),
'testuser',
'00000000-0000-0000-0000-000000000000' -- Invalid org_id
)func authenticateUser(db *sql.DB, username string) error {
// Get user with invalid org_id
var orgID string
query1 := `SELECT PUser_Organisation_ID FROM GPC.Platform_User WHERE PUser_Name = ?`
db.QueryRow(query1, username).Scan(&orgID)
// orgID = "00000000-0000-0000-0000-000000000000" (doesn't exist in Organization table)
// This query hangs indefinitely
var orgName string
query2 := `SELECT Org_Name FROM GPC.Organization WHERE Org_ID = ?`
err := db.QueryRow(query2, orgID).Scan(&orgName)
// Expected: sql.ErrNoRows
// Actual: Hangs indefinitely ❌
return err
}Workaround:
Validate foreign keys exist before insert/update:
func createUser(db *sql.DB, userName, orgID string) error {
// Validate organization exists first
var count int
query := `SELECT COUNT(*) FROM GPC.Organization WHERE Org_ID = ?`
db.QueryRow(query, orgID).Scan(&count)
if count == 0 {
return errors.New("invalid organization ID - organization does not exist")
}
// Safe to insert user - org_id is valid
insertQuery := `
INSERT INTO GPC.Platform_User (PUser_ID, PUser_Name, PUser_Organisation_ID)
VALUES (NEWID(), ?, ?)
`
_, err := db.Exec(insertQuery, userName, orgID)
return err
}Finding Existing Invalid Data:
-- Find users with invalid org_id
SELECT u.PUser_ID, u.PUser_Name, u.PUser_Organisation_ID
FROM GPC.Platform_User u
LEFT JOIN GPC.Organization o ON u.PUser_Organisation_ID = o.Org_ID
WHERE u.PUser_Organisation_ID IS NOT NULL
AND o.Org_ID IS NULL;
-- Fix: Set to NULL or valid org_id
UPDATE GPC.Platform_User
SET PUser_Organisation_ID = NULL -- or a valid org_id
WHERE PUser_ID = '<user-guid>';Impact: High - can cause production authentication failures, requires foreign key validation before all inserts/updates.
Issue 8: UUID Field Type Warning Spam (Low Priority)
Severity: LOW (Cosmetic Only)
Description:
When reading UUID fields without CAST operations (which must be avoided due to Issue #1), the driver logs warnings for every UUID field read.
Warning Message:
fromODBC: invalid type: -11 - list.ListItem{size:0x24, itemType:0x1, data:[]uint8{...}}
Symptoms:
- Warning logged for every UUID field in every row
- Clutters console output and log files
- Does not affect functionality
Example:
func listOrganizations(db *sql.DB) error {
query := `SELECT Org_ID, Org_Name FROM GPC.Organization`
rows, _ := db.Query(query)
defer rows.Close()
for rows.Next() {
var orgID, orgName string
rows.Scan(&orgID, &orgName) // Logs warning for Org_ID field
}
// Console output:
// fromODBC: invalid type: -11 - list.ListItem{...}
// fromODBC: invalid type: -11 - list.ListItem{...}
// fromODBC: invalid type: -11 - list.ListItem{...}
// (repeated for every row)
return nil
}Workaround:
Implement filtered log writer to suppress these warnings:
type FilteredWriter struct {
writer io.Writer
}
func (fw *FilteredWriter) Write(p []byte) (n int, err error) {
logMessage := string(p)
// Filter out IRIS driver UUID warnings
if strings.Contains(logMessage, "fromODBC: invalid type: -11") {
return len(p), nil // Suppress this message
}
// Pass through all other log messages
return fw.writer.Write(p)
}
func main() {
// Set up filtered log output
log.SetOutput(&FilteredWriter{writer: os.Stdout})
// ... rest of application
}Impact: Low - cosmetic only, but significantly clutters logs in production.