4b2e806a0d57f97bbadf9a762778965ccd36989d
angie
  Fri Dec 21 13:57:15 2012 -0800
Bug #9860 (Table Browser paste identifiers button not working for 1000 genomes ph1 Accessible Regions):getExamples() was unaware of bigBed, so an illegal mysql query was constructed.
Fix: added randomBigBedIds().  While in there, enhanced ramdomVcfIds() to ignore
runs of identical IDs because those are placeholders, and might otherwise crowd
out a few meaningful IDs (#8886 note 28).

diff --git src/hg/hgTables/identifiers.c src/hg/hgTables/identifiers.c
index fedbe89..5c4ef05 100644
--- src/hg/hgTables/identifiers.c
+++ src/hg/hgTables/identifiers.c
@@ -48,116 +48,122 @@
     idField = words[1];
     aliasField = words[2];
     if (!sqlTableExists(conn, xrefTable) ||
 	sqlFieldIndex(conn, xrefTable, idField) < 0 ||
 	sqlFieldIndex(conn, xrefTable, aliasField) < 0)
 	xrefTable = idField = aliasField = NULL;
     }
 if (retXrefTable != NULL)
     *retXrefTable = xrefTable;
 if (retIdField != NULL)
     *retIdField = idField;
 if (retAliasField != NULL)
     *retAliasField = aliasField;
 }
 
-static struct slName *getExamples(struct sqlConnection *conn,
+static struct slName *getExamples(char *db, struct sqlConnection *conn,
 				  char *table, char *field, int count)
 /* Return a list of several example values of table.field. */
 {
 if (isBamTable(table))
     {
     assert(sameString(field, "qName"));
     return randomBamIds(table, conn, count);
     }
-if (isVcfTable(table))
+else if (isBigBed(db, table, curTrack, ctLookupName))
+    {
+    assert(sameString(field, "name"));
+    return randomBigBedIds(table, conn, count);
+    }
+else if (isVcfTable(table))
     {
     assert(sameString(field, "id"));
     return randomVcfIds(table, conn, count);
     }
 else
     {
     char fullTable[HDB_MAX_TABLE_STRING];
     char *c = strchr(table, '.');
     if (c || ! hFindSplitTable(database, NULL, table, fullTable, NULL))
 	safecpy(fullTable, sizeof(fullTable), table);
     return sqlRandomSampleConn(conn, fullTable, field, count);
     }
 }
 
-static void explainIdentifiers(struct sqlConnection *conn, char *idField)
+static void explainIdentifiers(char *db, struct sqlConnection *conn, char *idField)
 /* Tell the user what field(s) they may paste/upload values for, and give
  * some examples. */
 {
 char *xrefTable = NULL, *xrefIdField = NULL, *aliasField = NULL;
 getXrefInfo(conn, &xrefTable, &xrefIdField, &aliasField);
 hPrintf("The items must be values of the <B>%s</B> field of the currently "
 	"selected table, <B>%s</B>",
 	idField, curTable);
 if (aliasField != NULL)
     {
     if (sameString(curTable, xrefTable))
 	{
 	if (!sameString(idField, aliasField))
 	    hPrintf(", or the <B>%s</B> field.\n", aliasField);
 	else
 	    hPrintf(".\n");
 	}
     else
 	hPrintf(", or the <B>%s</B> field of the alias table <B>%s</B>.\n",
 		aliasField, xrefTable);
     }
 else
     hPrintf(".\n");
 hPrintf("(The \"describe table schema\" button shows more information about "
 	"the table fields.)\n");
 if (!isCustomTrack(curTable))
     {
     struct slName *exampleList = NULL, *ex;
     hPrintf("Some example values:<BR>\n");
-    exampleList = getExamples(conn, curTable, idField, 3);
+    exampleList = getExamples(db, conn, curTable, idField,
+			      aliasField != NULL ? 3 : 5);
     for (ex = exampleList;  ex != NULL;  ex = ex->next)
 	{
 	char *tmp = htmlEncode(ex->name);
 	hPrintf("<TT>%s</TT><BR>\n", tmp);
 	freeMem(tmp);
 	}
     if (aliasField != NULL)
 	{
 	char tmpTable[512];
 	char query[2048];
 	// do not use any db. prefix on curTable for name
 	char *plainCurTable = strrchr(curTable, '.');  
 	if (plainCurTable)
 	    plainCurTable++;
 	else
 	    plainCurTable = curTable;
 	safef(tmpTable, sizeof(tmpTable), "hgTemp.tmp%s%s", plainCurTable, xrefTable);
 	if (differentString(xrefTable, curTable))
 	    safef(query, sizeof(query),
 		  "create temporary table %s select %s.%s as %s from %s,%s "
 		  "where %s.%s = %s.%s and %s.%s != %s.%s limit 100000",
 		  tmpTable, xrefTable, aliasField, aliasField, xrefTable, curTable,
 		  xrefTable, xrefIdField, curTable, idField,
 		  xrefTable, xrefIdField, xrefTable, aliasField);
 	else
 	    safef(query, sizeof(query),
 		  "create temporary table %s select %s from %s "
 		  "where %s != %s limit 100000",
 		  tmpTable, aliasField, xrefTable, aliasField, xrefIdField);
 	sqlUpdate(conn, query);
-	exampleList = getExamples(conn, tmpTable, aliasField, 3);
+	exampleList = getExamples(db, conn, tmpTable, aliasField, 3);
 	for (ex = exampleList;  ex != NULL;  ex = ex->next)
 	    hPrintf("<TT>%s</TT><BR>\n", ex->name);
 	}
     hPrintf("\n");
     }
 }
 
 void doPasteIdentifiers(struct sqlConnection *conn)
 /* Respond to paste identifiers button. */
 {
 struct sqlConnection *alternateConn = conn;
 char *actualDb = database;
 if (sameWord(curTable, WIKI_TRACK_TABLE))
     {
     alternateConn = wikiConnect();
@@ -165,31 +171,31 @@
     }
 
 char *oldPasted = forCurTable() ?
     cartUsualString(cart, hgtaPastedIdentifiers, "") : "";
 struct hTableInfo *hti = maybeGetHti(actualDb, curTable, conn);
 char *idField = getIdField(actualDb, curTrack, curTable, hti);
 htmlOpen("Paste In Identifiers for %s", curTableLabel());
 if (idField == NULL)
     errAbort("Sorry, I can't tell which field of table %s to treat as the "
 	     "identifier field.", curTable);
 hPrintf("<FORM ACTION=\"%s\" METHOD=%s>\n", getScriptName(),
 	cartUsualString(cart, "formMethod", "POST"));
 cartSaveSession(cart);
 hPrintf("Please paste in the identifiers you want to include.\n");
 if (sqlDatabaseExists("hgTemp"))
-    explainIdentifiers(alternateConn, idField);
+    explainIdentifiers(actualDb, alternateConn, idField);
 else
     warn("No hgTemp database found for temporary tables.<br>Please src/product/README.mysql.setup for more information.");
 hPrintf("<BR>\n");
 cgiMakeTextArea(hgtaPastedIdentifiers, oldPasted, 10, 70);
 hPrintf("<BR>\n");
 cgiMakeButton(hgtaDoPastedIdentifiers, "submit");
 hPrintf(" ");
 cgiMakeButton(hgtaDoClearPasteIdentifierText, "clear");
 hPrintf(" ");
 cgiMakeButton(hgtaDoMainPage, "cancel");
 hPrintf("</FORM>");
 cgiDown(0.9);
 htmlClose();
 if (sameWord(curTable, WIKI_TRACK_TABLE))
     wikiDisconnect(&alternateConn);
@@ -198,31 +204,31 @@
 void doUploadIdentifiers(struct sqlConnection *conn)
 /* Respond to upload identifiers button. */
 {
 struct hTableInfo *hti = maybeGetHti(database, curTable, conn);
 char *idField = getIdField(database, curTrack, curTable, hti);
 htmlOpen("Upload Identifiers for %s", curTableLabel());
 if (idField == NULL)
     errAbort("Sorry, I can't tell which field of table %s to treat as the "
 	     "identifier field.", curTable);
 hPrintf("<FORM ACTION=\"%s\" METHOD=POST ENCTYPE=\"multipart/form-data\">\n",
 	getScriptName());
 cartSaveSession(cart);
 hPrintf("Please enter the name of a file from your computer that contains a ");
 hPrintf("space, tab, or ");
 hPrintf("line separated list of the items you want to include.\n");
-explainIdentifiers(conn, idField);
+explainIdentifiers(database, conn, idField);
 hPrintf("<BR>\n");
 hPrintf("<INPUT TYPE=FILE NAME=\"%s\"> ", hgtaPastedIdentifiers);
 hPrintf("<BR>\n");
 cgiMakeButton(hgtaDoPastedIdentifiers, "submit");
 hPrintf(" ");
 cgiMakeButton(hgtaDoMainPage, "cancel");
 hPrintf("</FORM>");
 cgiDown(0.9);
 htmlClose();
 }
 
 static void addPrimaryIdsToHash(struct sqlConnection *conn, struct hash *hash,
 				char *idField, struct slName *tableList,
 				struct lm *lm, char *extraWhere)
 /* For each table in tableList, query all idField values and add to hash,