f00658c709d15ec0c48a2350bc5e44b744fa1d32
angie
  Fri Sep 11 13:29:40 2015 -0700
In case asFromTableDescriptions is called many times, cache the result of sqlTableExists to avoid unnecessary repeated queries.

diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index 60c3da2..8ccade1 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -8310,30 +8310,73 @@
 {
 if (pExtras != NULL)
     {
     struct extraField *extra = NULL;
     while (NULL != (extra  = slPopHead(pExtras)))
         {
         freeMem(extra->name);
         freeMem(extra->label);
         freeMem(extra);
         }
     *pExtras = NULL;
     }
 }
 #endif///def EXTRA_FIELDS_SUPPORT
 
+static boolean tableDescriptionsExists(struct sqlConnection *conn)
+/* Cache flag for whether tableDescriptions exists in conn, in case we will need to
+ * fetch a lot of descriptions from tableDescriptions. */
+{
+static struct hash *hash = NULL;
+if (hash == NULL)
+    hash = hashNew(0);
+char *db = sqlGetDatabase(conn);
+int exists =  hashIntValDefault(hash, db, -1);
+if (exists < 0)
+    {
+    exists = sqlTableExists(conn, "tableDescriptions");
+    hashAddInt(hash, db, exists);
+    }
+return (boolean)exists;
+}
+
+struct asObject *asFromTableDescriptions(struct sqlConnection *conn, char *table)
+// If there is a tableDescriptions table and it has an entry for table, return
+// a parsed autoSql object; otherwise return NULL.
+{
+struct asObject *asObj = NULL;
+if (tableDescriptionsExists(conn))
+    {
+    char query[PATH_LEN*2];
+    // Try unsplit table first.
+    sqlSafef(query, sizeof(query),
+             "select autoSqlDef from tableDescriptions where tableName='%s'", table);
+    char *asText = sqlQuickString(conn, query);
+    // If no result try split table.
+    if (asText == NULL)
+        {
+        sqlSafef(query, sizeof(query),
+                 "select autoSqlDef from tableDescriptions where tableName='chrN_%s'", table);
+        asText = sqlQuickString(conn, query);
+        }
+    if (isNotEmpty(asText))
+        asObj = asParseText(asText);
+    freez(&asText);
+    }
+return asObj;
+}
+
 static struct asObject *asForTdbOrDie(struct sqlConnection *conn, struct trackDb *tdb)
 // Get autoSQL description if any associated with tdb.
 // Abort if there's a problem
 {
 struct asObject *asObj = NULL;
 if (tdbIsBigBed(tdb))
     {
     char *fileName = hReplaceGbdb(tdbBigFileName(conn, tdb));
     asObj = bigBedFileAsObjOrDefault(fileName);
     freeMem(fileName);
     }
 // TODO: standardize to a wig as
 //else if (tdbIsBigWig(tdb))
 //    asObj = asObjFrombigBed(conn,tdb);
 else if (tdbIsBam(tdb))