f219460db8db952415b5201ba01df99ce4999004
braney
  Thu Sep 10 13:46:42 2026 -0700
genark: pass the liftOver accession list as an slName list, refs #38328

genarkLiftOverDbs() took a pre-quoted SQL fragment that its callers
assembled.  It now takes a struct slName list and builds the query
itself with sqlDyStringCreate, so no caller writes SQL text.
Accessions that do not start with GC are skipped, since nothing else
can match the table.  hdb.c and hgConvert.c updated for the new
signature.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

diff --git src/hg/lib/genark.c src/hg/lib/genark.c
index 93f3b0d8fb7..49e79910728 100644
--- src/hg/lib/genark.c
+++ src/hg/lib/genark.c
@@ -395,62 +395,93 @@
 
 dbDb->name = cloneString(row[0]);
 dbDb->nibPath = cloneString("genark"); 
 dbDb->description = cloneString(row[4]); // commonName
 dbDb->scientificName = cloneString(row[3]); 
 dbDb->taxId = atoi(row[5]); 
 dbDb->organism = dbDb->genome = hashFindVal(orgHash, row[0]);
 dbDb->orderKey = 99999;
 dbDb->defaultPos = "default";
 if (dbDb->genome == NULL)
     dbDb->organism = dbDb->genome = "Other";
 
 return dbDb;
 }
 
-struct dbDb *genarkLiftOverDbs(char *listOfAccs)
-/* return list of dbDb structures for the genark genomes that match listOfAccs */
+struct dbDb *genarkLiftOverDbs(struct slName *accList)
+/* return list of dbDb structures for the genark genomes named in accList */
 {
 if (!cfgOption("genarkLiftOver"))
     return NULL;
 struct dbDb *list = NULL;
-char query[64 * 1024];
+struct slName *acc;
+boolean any = FALSE;
+
+for (acc = accList; acc != NULL; acc = acc->next)
+    {
+    /* every accession in the genark table is a GC[AF]_ accession, so
+     * anything else cannot match and need not reach the query */
+    if (startsWith("GC", acc->name))
+        {
+        any = TRUE;
+        break;
+        }
+    }
+if (!any)
+    return NULL;
 
-safef(query, sizeof query, "NOSQLINJ select * from %s where gcAccession in (%s)", genarkTableName(), listOfAccs);
+/* the escaping in sqlDyStringPrintf needs a live connection, so connect
+ * before the query is built */
 struct sqlConnection *conn = hConnectCentral();
 struct sqlResult *sr;
 char **row;
+boolean first = TRUE;
 
-sr = sqlGetResult(conn, query);
+struct dyString *query = sqlDyStringCreate("select * from %s where gcAccession in (",
+    genarkTableName());
+for (acc = accList; acc != NULL; acc = acc->next)
+    {
+    if (!startsWith("GC", acc->name))
+        continue;
+    if (!first)
+        sqlDyStringPrintf(query, ",");
+    sqlDyStringPrintf(query, "'%s'", acc->name);
+    first = FALSE;
+    }
+sqlDyStringPrintf(query, ")");
+
+sr = sqlGetResult(conn, query->string);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     struct dbDb *dbDb = genarkMakeDbDb(row);
     slAddHead(&list, dbDb);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 hDisconnectCentral(&conn);
+dyStringFree(&query);
 return list;
 }
 
 struct dbDb *genarkLiftOverDb(char *acc)
 /* return dbDb structure for GC* acc */
 {
-char query[4096];
-safef(query, sizeof query, "'%s'", acc);
+struct slName *one = slNameNew(acc);
+struct dbDb *list = genarkLiftOverDbs(one);
 
-return genarkLiftOverDbs(query);
+slNameFreeList(&one);
+return list;
 }
 
 struct hash *genarkGetOrgHash()
 /* read table that maps gcAccession to UCSC org. */
 {
 static struct hash *orgHash = NULL;
 
 if (orgHash != NULL)
     return orgHash;
 char query[64 * 1024];
 
 sqlSafef(query, sizeof query, "select * from %s", "genarkOrg");
 struct sqlConnection *conn = hConnectCentral();
 struct sqlResult *sr;
 char **row;