a4234f184e880692939c7dfe967d1d3b220399e6 angie Wed Sep 26 12:25:10 2018 -0700 In multi-region alt/fix autocomplete, escape search terms in the same way for chromAlias search as for {alt,fix}SeqLiftOverPsl. refs #18544 diff --git src/hg/hgSuggest/hgSuggest.c src/hg/hgSuggest/hgSuggest.c index 1e710fb..97a3a18 100644 --- src/hg/hgSuggest/hgSuggest.c +++ src/hg/hgSuggest/hgSuggest.c @@ -83,81 +83,86 @@ dyStringPrintf(str, "%s{\"value\": \"%s (%s)\", " "\"id\": \"%s:%d-%s\", " "\"geneSymbol\": \"%s\", " "\"internalId\": \"%s\"}", count == 1 ? "" : ",\n", row[0], jsonStringEscape(description), row[1], atoi(row[2])+1, row[3], jsonStringEscape(row[0]), jsonStringEscape(row[4])); } } hFreeConn(&conn); dyStringPrintf(str, "\n]\n"); puts(dyStringContents(str)); } -struct slName *queryQNames(struct sqlConnection *conn, char *table, char *term, boolean prefixOnly) -/* If table exists, return qNames in table that match term, otherwise NULL. Exclude items whose - * tName contains '_' so the mappings between _alt and _fix sequences don't sneak into the wrong - * category's results. */ -{ -struct slName *names = NULL; -if (sqlTableExists(conn, table)) +char *escapeAltFixTerm(char *term) +/* Special tweaks for SQL search of alt/fix terms that may include '.' and '_' characters. */ { // If there is a ".", make it into a single-character wildcard so that "GL383518.1" // can match "chr1_GL383518v1_alt". char termCpy[strlen(term)+1]; safecpy(termCpy, sizeof termCpy, term); subChar(termCpy, '.', '?'); // Escape '_' because that is an important character in alt/fix sequence names, and support // wildcards: - char *escapedTerm = sqlLikeFromWild(termCpy); +return sqlLikeFromWild(termCpy); +} + +struct slName *queryQNames(struct sqlConnection *conn, char *table, char *term, boolean prefixOnly) +/* If table exists, return qNames in table that match term, otherwise NULL. Exclude items whose + * tName contains '_' so the mappings between _alt and _fix sequences don't sneak into the wrong + * category's results. */ +{ +struct slName *names = NULL; +if (sqlTableExists(conn, table)) + { char query[2048]; sqlSafef(query, sizeof query, "select distinct(qName) from %s where qName like '%s%s%%' " "and tName not rlike '.*_.*' order by qName", - table, (prefixOnly ? "" : "%"), escapedTerm); + table, (prefixOnly ? "" : "%"), escapeAltFixTerm(term)); names = sqlQuickList(conn, query); } return names; } void writeAltFixMatches(struct jsonWrite *jw, struct slName *matches, char *category) /* Append JSON objects containing alt or fix patch sequence names & optional category. */ { 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, 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%s%%' " - "order by chrom", (prefixOnly ? "" : "%"), term); + "order by chrom", (prefixOnly ? "" : "%"), escapeAltFixTerm(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);