60e7358ad9239e80827ee2a9d95151ef5fc57946
angie
  Wed Sep 26 12:17:25 2018 -0700
Add fuzzy search of chromAlias to multi-region alt/fix autocomplete, so common haplotype name components like 'cox', 'apd', 'kir' can be matched.  refs #18544

diff --git src/hg/hgSuggest/hgSuggest.c src/hg/hgSuggest/hgSuggest.c
index ff81841..1e710fb 100644
--- src/hg/hgSuggest/hgSuggest.c
+++ src/hg/hgSuggest/hgSuggest.c
@@ -125,39 +125,39 @@
 {
 struct slName *match;
 for (match = matches; match != NULL; match = match->next)
     {
     if (strchr(match->name, '_'))
         {
         jsonWriteObjectStart(jw, NULL);
         jsonWriteString(jw, "value", match->name);
         if (isNotEmpty(category))
             jsonWriteString(jw, "category", category);
         jsonWriteObjectEnd(jw);
         }
     }
 }
 
-struct slPair *queryChromAlias(struct sqlConnection *conn, char *term)
+struct slPair *queryChromAlias(struct sqlConnection *conn, char *term, boolean prefixOnly)
 /* Search chromAlias for prefix matches for term. */
 {
 struct slPair *matches = NULL;
 if (sqlTableExists(conn, "chromAlias"))
     {
     char query[1024];
-    sqlSafef(query, sizeof query, "select chrom, alias from chromAlias where alias like '%s%%' "
-             "order by chrom", term);
+    sqlSafef(query, sizeof query, "select chrom, alias from chromAlias where alias like '%s%s%%' "
+             "order by chrom", (prefixOnly ? "" : "%"), term);
     matches = sqlQuickPairList(conn, query);
     }
 return matches;
 }
 
 void writeValLabelMatches(struct jsonWrite *jw, struct slPair *matches, char *category)
 /* Append JSON objects containing alt/fix seqs with extra label info & optional category. */
 {
 struct slPair *match;
 for (match = matches; match != NULL; match = match->next)
     {
     char *seqName = match->name;
     if (strchr(seqName, '_') && !endsWith(seqName, "_random") && !startsWith("chrUn", seqName))
         {
         jsonWriteObjectStart(jw, NULL);
@@ -189,32 +189,37 @@
 struct slName *altMatches = queryQNames(conn, "altSeqLiftOverPsl", term, TRUE);
 // Add category labels only if we get both types of matches.
 writeAltFixMatches(jw, fixMatches, altMatches ? "Fix Patches" : "");
 writeAltFixMatches(jw, altMatches, fixMatches ? "Alt Patches" : "");
 // If there are no prefix matches, look for partial matches
 if (fixMatches == NULL && altMatches == NULL)
     {
     fixMatches = queryQNames(conn, "fixSeqLiftOverPsl", term, FALSE);
     altMatches = queryQNames(conn, "altSeqLiftOverPsl", term, FALSE);
     writeAltFixMatches(jw, fixMatches, altMatches ? "Fix Patches" : "");
     writeAltFixMatches(jw, altMatches, fixMatches ? "Alt Patches" : "");
     }
 // If there are still no matches, try chromAlias.
 if (fixMatches == NULL && altMatches == NULL)
     {
-    struct slPair *aliasMatches = queryChromAlias(conn, term);
+    struct slPair *aliasMatches = queryChromAlias(conn, term, TRUE);
     writeValLabelMatches(jw, aliasMatches, "");
+    if (aliasMatches == NULL)
+        {
+        struct slPair *aliasMatches = queryChromAlias(conn, term, FALSE);
+        writeValLabelMatches(jw, aliasMatches, "");
+        }
     }
 hFreeConn(&conn);
 jsonWriteListEnd(jw);
 puts(jw->dy->string);
 jsonWriteFree(&jw);
 }
 
 char *checkParams(char *database, char *prefix, char *type)
 /* If we don't have valid CGI parameters, quit with a Bad Request HTTP response. */
 {
 pushWarnHandler(htmlVaBadRequestAbort);
 pushAbortHandler(htmlVaBadRequestAbort);
 if(prefix == NULL || database == NULL)
     errAbort("%s", "Missing prefix and/or db CGI parameter");
 if (! hDbIsActive(database))