4444c72fad0e597c0a616aeb37403c4468eedb87
galt
  Wed Dec 4 12:18:30 2013 -0800
fixes #12274. Fixes a new problem in hgTables caused by a recent bugfix. This makes it super specific so that even the exonCount, exonStarts, and exonEnds match.
diff --git src/hg/hgTables/gffOut.c src/hg/hgTables/gffOut.c
index cb0ff47..e44aba7 100644
--- src/hg/hgTables/gffOut.c
+++ src/hg/hgTables/gffOut.c
@@ -318,48 +318,76 @@
     itemCount++;
     if (exonFrames)
     	exonFrames = exonFrames->next;
     }
 hashFree(&nameHash);
 return itemCount;
 }
 
 static struct slName* getExonFrames(char *table, struct sqlConnection *conn, struct bed *bedList)
 /* get real exonFrames if they are available */
 {
 struct slName* list = NULL;
 struct bed *bed;
 for (bed = bedList;  bed != NULL;  bed = bed->next)
     {
-    char sql[1024];
+    // be super specific, the same name may align to multiple locations
+    //  or even the same location with alternate splicing or exon structure.
+    
+    // convert bed block coordinates to exonStarts, exonEnds
+    // TODO: do I have to do anything special for the negative strand?
+    int i;
+    struct dyString *exonStarts = newDyString(256);
+    struct dyString *exonEnds = newDyString(256);
+    for( i = 0 ; i < bed->blockCount; i++ )
+	{
+	int exonStart = bed->chromStart + bed->chromStarts[i];
+	int exonEnd = exonStart + bed->blockSizes[i];
+	dyStringPrintf(exonStarts, "%d,", exonStart);
+	dyStringPrintf(exonEnds,   "%d,", exonEnd);
+	}
+    char sql[4096+strlen(exonStarts->string)+strlen(exonEnds->string)];
+
     sqlSafef(sql, sizeof sql, "select exonFrames "
 	"from %s where " 
-	"name = '%s' and "  // be specific, the same name may align to multiple locations
+	"name = '%s' and "  
 	"chrom = '%s' and "
 	"strand = '%c' and "
 	"txStart = %d and "
-	"txEnd = %d"
+	"txEnd = %d and "
+	"cdsStart = %d and "
+	"cdsEnd = %d and "
+        "exonCount = %d and "
+        "exonStarts = '%s' and "
+        "exonEnds = '%s'"
 	, 
 	table, 
 	bed->name,
 	bed->chrom,
 	bed->strand[0],
 	bed->chromStart,
-	bed->chromEnd
+	bed->chromEnd,
+	bed->thickStart,
+	bed->thickEnd,
+	bed->blockCount,
+	exonStarts->string,
+	exonEnds->string
 	);
     char *exonFrames = sqlQuickString(conn, sql);
     slNameAddHead(&list, exonFrames);
+    dyStringFree(&exonStarts);
+    dyStringFree(&exonEnds);
     }
 slReverse(&list);
 return list;
 }
 
 void doOutGff(char *table, struct sqlConnection *conn, boolean outputGtf)
 /* Save as GFF/GTF. */
 {
 struct hTableInfo *hti = getHti(database, table, conn);
 struct bed *bedList;
 struct slName *exonFramesList = NULL;
 char source[HDB_MAX_TABLE_STRING];
 int itemCount;
 struct region *region, *regionList = getRegions();