9af188ea6147f9edb20bd531d3ec988501cf997c
chmalee
  Fri Feb 6 12:18:25 2026 -0800
Fix jsonOutputArrays columnTypes output when more than one track is requested with /getData/track. Leaves /list/schema alone. Add option to hgTracks Downloads -> Download track data in view menu to include column headers in output, refs #36858

diff --git src/hg/hubApi/list.c src/hg/hubApi/list.c
index c1ca666f008..1258a04abd8 100644
--- src/hg/hubApi/list.c
+++ src/hg/hubApi/list.c
@@ -448,31 +448,31 @@
     apiErrAbort(err400, err400Msg, "failed to find specified track=%s in genome=%s for endpoint '/list/schema'  given hubUrl='%s'", track, genome, hubUrl);
 
 char *bigDataUrl = hReplaceGbdb(trackDbSetting(thisTrack, "bigDataUrl"));
 if (NULL == bigDataUrl)
     apiErrAbort(err400, err400Msg, "failed to find bigDataUrl for specified track=%s in genome=%s for endpoint '/list/schema'  given hubUrl='%s'", track, genome, hubUrl);
 char *indexFileOrUrl = hReplaceGbdb(trackDbSetting(tdb, "bigDataIndex"));
 struct bbiFile *bbi = bigFileOpen(thisTrack->type, bigDataUrl);
 long long itemCount = bbiItemCount(bigDataUrl, thisTrack->type, indexFileOrUrl);
 
 outputTrackDbVars(jw, genome, thisTrack, itemCount);
 
 struct asObject *as = bigBedAsOrDefault(bbi);
 if (! as)
     apiErrAbort(err500, err500Msg, "can not find schema definition for bigDataUrl '%s', track=%s genome: '%s' for endpoint '/list/schema' given hubUrl='%s'", bigDataUrl, track, genome, hubUrl);
 struct sqlFieldType *fiList = sqlFieldTypesFromAs(as);
-bigColumnTypes(jw, fiList, as);
+bigColumnTypes(jw, fiList, as, "columnTypes");
 
 apiFinishOutput(0, NULL, jw);
 }	/* static void hubSchemaJsonOutput(FILE *f, char *hubUrl,
 	 *	char *genome, char *track) */
 
 static char *bigDataUrlFromTable(struct sqlConnection *conn, char *table)
 /* perhaps there is a bigDataUrl in a database table */
 {
 char *bigDataUrl = NULL;
 char query[4096];
 char quickReturn[2048];
 
 if (sqlColumnExists(conn, table, "fileName"))
     {
     sqlSafef(query, sizeof(query), "select fileName from %s", table);
@@ -577,70 +577,70 @@
 struct asObject *as = NULL;
 struct asColumn *columnEl = NULL;
 int asColumnCount = 0;
 long long itemCount = 0;
 
 if (bbi)
     {
     /* do not show itemCount for protected data */
     if (! protectedTrack(db, thisTrack, track))
 	{
 	char *indexFileOrUrl = hReplaceGbdb(trackDbSetting(thisTrack, "bigDataIndex"));
 	itemCount = bbiItemCount(bigDataUrl, thisTrack->type, indexFileOrUrl);
 	}
     if (startsWith("bigWig", thisTrack->type))
 	{
-	wigColumnTypes(jw);
+	wigColumnTypes(jw, "columnTypes");
 	}
     else
 	{
 	as = bigBedAsOrDefault(bbi);
 	if (! as)
 	    apiErrAbort(err500, err500Msg, "can not find schema definition for bigDataUrl '%s', track=%s genome: '%s' for endpoint '/list/schema'", bigDataUrl, track, db);
 	struct sqlFieldType *fiList = sqlFieldTypesFromAs(as);
-	bigColumnTypes(jw, fiList, as);
+	bigColumnTypes(jw, fiList, as, "columnTypes");
 	}
     }
 else
     {
     columnCount = tableColumns(conn, splitTableName, &columnNames, &columnTypes, &jsonTypes);
     as = asForTable(conn, splitTableName, thisTrack);
     if (! as)
 	apiErrAbort(err500, err500Msg, "can not find schema definition for table '%s', track=%s genome: '%s' for endpoint '/list/schema'", splitTableName, track, db);
     columnEl = as->columnList;
     asColumnCount = slCount(columnEl);
 
     /* do not show counts for protected data */
     if (! protectedTrack(db, thisTrack, track))
 	{
 	char query[2048];
 	sqlSafef(query, sizeof(query), "select count(*) from %s", splitTableName);
 	if (hti && hti->isSplit)	/* punting on split table item count */
 	    itemCount = 0;
 	else
 	    {
 	    itemCount = sqlQuickNum(conn, query);
 	    }
 	}
 hFreeConn(&conn);
 
 
 if (hti && (hti->isSplit || debug))
     jsonWriteBoolean(jw, "splitTable", hti->isSplit);
 
 outputSchema(thisTrack, jw, columnNames, columnTypes, jsonTypes, hti,
-  columnCount, asColumnCount, columnEl);
+  columnCount, asColumnCount, columnEl, "columnTypes");
     }
 
 outputTrackDbVars(jw, db, thisTrack, itemCount);
 
 apiFinishOutput(0, NULL, jw);
 
 }	/*	static void schemaJsonOutput(FILE *f, char *db, char *track) */
 
 /* typical rsync return
 columns: 0              1        2      3         4
 drwxrwxr-x            162 2022/10/18 16:58:16 .
 drwxrwxr-x          4,096 2023/03/27 16:01:41 bigZips
 -r--rw-r--          3,455 2022/08/11 03:26:26 bigZips/GCA_009914755.4_assembly_report.txt
 -rw-rw-r--              0 2022/07/18 12:06:00 bigZips/THIS_IS_GENOME_ASSEMBLY_T2T-CHM13v2.0
 -rw-rw-r--    812,327,608 2022/07/16 14:27:39 bigZips/hs1.2bit