441ec7ab39569a301912b2b08981747d98fdb752 hiram Fri Sep 11 15:11:40 2026 -0700 the exactNameSearch() was the wrong way to go, back that out and do this correctly from claude code review refs #38290 diff --git src/hg/hubApi/findGenome.c src/hg/hubApi/findGenome.c index c1226edd799..5553d96ec54 100644 --- src/hg/hubApi/findGenome.c +++ src/hg/hubApi/findGenome.c @@ -307,66 +307,30 @@ { dyStringClear(query); sqlDyStringPrintf(query, "SELECT * FROM %s ", asmListTable); sqlDyStringPrintf(query, "WHERE MATCH(name, commonName, scientificName, clade, description, refSeqCategory, versionStatus, assemblyLevel, haplotypes) AGAINST ('%s%s' IN BOOLEAN MODE)", searchWord, *prefixSearch ? "*" : ""); addConditions(query); /* add optional SELECT options */ sqlDyStringPrintf(query, " ORDER BY priority LIMIT %d;", maxItemsOutput); struct sqlResult *sr = sqlGetResult(conn, query->string); itemCount = sqlJsonOut(jw, sr); sqlFreeResult(&sr); dyStringFree(&query); } return itemCount; } /* static long long oneWordSearch(struct sqlConnection *conn, char *searchWord, struct jsonWrite *jw, boolean *prefixSearch) */ -static long long exactNameSearch(struct sqlConnection *conn, char *word, struct jsonWrite *jw, long long *totalMatchCount) -/* fast path for a single-word search: the great majority of single-word - * searches are an exact UCSC database name or NCBI/GenArk assembly - * accession (e.g. hg38, GCF_052040795.1) that is already present - * verbatim in the 'name' column, which is the table's PRIMARY KEY. - * Try that direct, indexed equality lookup first since it is an O(log n) - * B-TREE seek versus the much more expensive FULLTEXT boolean search in - * oneWordSearch(). Simply returns 0, with *totalMatchCount left at 0, - * when there is no exact match; the caller then falls back to - * oneWordSearch() for the usual FULLTEXT keyword search. - */ -{ -long long itemCount = 0; -*totalMatchCount = 0; - -struct dyString *query = sqlDyStringCreate("SELECT COUNT(*) FROM %s ", asmListTable); -sqlDyStringPrintf(query, "WHERE name='%s'", word); -addConditions(query); /* add optional SELECT options */ - -long long matchCount = sqlQuickLongLong(conn, query->string); -dyStringFree(&query); -if (matchCount < 1) // no exact match, let caller fall back to FULLTEXT search - return itemCount; -*totalMatchCount = matchCount; - -query = sqlDyStringCreate("SELECT * FROM %s ", asmListTable); -sqlDyStringPrintf(query, "WHERE name='%s'", word); -addConditions(query); /* add optional SELECT options */ -struct sqlResult *sr = sqlGetResult(conn, query->string); -itemCount = sqlJsonOut(jw, sr); -sqlFreeResult(&sr); -dyStringFree(&query); - -return itemCount; -} /* static long long exactNameSearch(struct sqlConnection *conn, char *word, struct jsonWrite *jw, long long *totalMatchCount) */ - #ifdef NOT // disabled 2025-10-22 static long elapsedTime(struct jsonWrite *jw) { long nowTime = clock1000(); long elapsedTimeMs = nowTime - enteredMainTime; jsonWriteNumber(jw, "elapsedTimeMs", elapsedTimeMs); return elapsedTimeMs; } #endif void apiFindGenome(char *pathString[MAX_PATH_INFO]) /* 'findGenome' function */ { char *searchString = cgiOptionalString(argQ); @@ -519,55 +483,47 @@ jsonWriteNumber(jw, argYear, specificYear); if (isNotEmpty(refSeqCategory)) jsonWriteString(jw, argCategory, refSeqCategory); if (isNotEmpty(versionStatus)) jsonWriteString(jw, argStatus, versionStatus); if (isNotEmpty(assemblyLevel)) jsonWriteString(jw, argLevel, assemblyLevel); jsonWriteString(jw, argLiftable, liftableStr); long long itemCount = 0; long long totalMatchCount = 0; char **words; AllocArray(words, wordCount); (void) chopByWhite(searchString, words, wordCount); if (1 == wordCount) - { - /* fast path: try an exact PRIMARY KEY match on 'name' first, since - * the great majority of single-word searches are an exact UCSC db - * name or assembly accession; itemCount stays 0 when there is no - * exact match, and the usual FULLTEXT search below runs as before */ - itemCount = exactNameSearch(conn, words[0], jw, &totalMatchCount); - if (itemCount < 1) { boolean doQuote = TRUE; /* already quoted, let it go as-is */ if (startsWith("\"", words[0]) && endsWith(words[0],"\"")) doQuote = FALSE; /* already wildcard, let it go as-is */ if (endsWith(words[0],"*")) doQuote = FALSE; if (doQuote && hasWordBreaks(words[0])) { char *quotedWords = quoteWords(words[0]); endResultSearchString = quotedWords; itemCount = oneWordSearch(conn, quotedWords, jw, &totalMatchCount, &prefixSearch); } else { itemCount = oneWordSearch(conn, words[0], jw, &totalMatchCount, &prefixSearch); } } - } else /* multiple word search */ itemCount = multipleWordSearch(conn, words, wordCount, jw, &totalMatchCount); if (prefixSearch) { struct dyString *addedStar = dyStringNew(64); dyStringPrintf(addedStar, "%s*", inputSearchString); endResultSearchString = dyStringCannibalize(&addedStar); jsonWriteString(jw, argQ, endResultSearchString); } else { jsonWriteString(jw, argQ, endResultSearchString); }