44b8e80672284df508a24fe193129c9673dc898d chmalee Fri Apr 1 11:43:20 2022 -0700 Fix hgVai bug where position flag resets some memory initialized elsewhere, and also handle NULL mysql result better, refs Lou email diff --git src/hg/cgilib/annoStreamDb.c src/hg/cgilib/annoStreamDb.c index fb5ff3e..173a8bd 100644 --- src/hg/cgilib/annoStreamDb.c +++ src/hg/cgilib/annoStreamDb.c @@ -111,30 +111,39 @@ self->mergeBins = FALSE; self->bigItemQueue = self->smallItemQueue = NULL; lmCleanup(&(self->qLm)); self->gotFinestBin = FALSE; } static void resetRowBuf(struct rowBuf *rowBuf) /* Reset temporary storage for chunked query rows. */ { rowBuf->buf = NULL; rowBuf->size = 0; rowBuf->ix = 0; lmCleanup(&(rowBuf->lm)); } +static void rowBufInit(struct rowBuf *rowBuf, int size) +/* Clean up rowBuf and give it a new lm and buffer[size]. */ +{ +resetRowBuf(rowBuf); +rowBuf->lm = lmInit(0); +rowBuf->size = size; +lmAllocArray(rowBuf->lm, rowBuf->buf, size); +} + static void resetChunkState(struct annoStreamDb *self) /* Reset members that track chunked queries. */ { self->queryChrom = NULL; self->eof = FALSE; self->doNextChunk = FALSE; self->needQuery = TRUE; resetRowBuf(&self->rowBuf); } static void startMerging(struct annoStreamDb *self) /* Set self->mergeBins flag and create self->qLm if necessary. */ { self->mergeBins = TRUE; self->gotFinestBin = FALSE; @@ -164,37 +173,45 @@ if (differentString(self->table, self->trackTable)) { char newSplitTable[PATH_LEN]; safef(newSplitTable, sizeof(newSplitTable), "%s_%s", chrom, self->trackTable); freeMem(self->table); self->table = cloneString(newSplitTable); } resetQueryState(self); asdUpdateBaselineQuery(self); } static char **nextRowFromSqlResult(struct annoStreamDb *self) /* Stream rows directly from self->sr, but copy into rowBuf in case we need extra columns for * hashJoin. */ { +// If we passed a position filter, we may have reset the rowBuf, so re-initialize +if (self->rowBuf.buf == NULL) + rowBufInit(&self->rowBuf, 1); // Use only the first row in rowBuf. if (self->rowBuf.buf[0] == NULL) lmAllocArray(self->rowBuf.lm, self->rowBuf.buf[0], self->bigRowSize); char **row = sqlNextRow(self->sr); +if (row) + { CopyArray(row, self->rowBuf.buf[0], self->sqlRowSize); return self->rowBuf.buf[0]; } +else + return NULL; +} INLINE boolean useSplitTable(struct annoStreamDb *self, struct joinerDtf *dtf) /* Return TRUE if dtf matches self->{db,table} and table is split. */ { return (sameString(dtf->database, self->db) && sameString(dtf->table, self->trackTable) && differentString(self->table, self->trackTable)); } static void appendFieldList(struct annoStreamDb *self, struct dyString *query) /* Append SQL field list to query. */ { struct joinerDtf *fieldList = self->joinMixer ? self->joinMixer->sqlFieldList : self->mainTableDtfList; struct joinerDtf *dtf; @@ -437,39 +454,30 @@ hasWhere); if (self->notSorted || self->hasLeftJoin) sqlDyStringPrintf(query, " order by %s.%s", self->table, self->startField); } else if (self->notSorted || self->hasLeftJoin) sqlDyStringPrintf(query, " order by %s.%s,%s.%s", self->table, self->chromField, self->table, self->startField); if (self->maxOutRows > 0) dyStringPrintf(query, " limit %d", self->maxOutRows); struct sqlResult *sr = sqlGetResult(self->conn, query->string); dyStringFree(&query); self->sr = sr; self->needQuery = FALSE; } -static void rowBufInit(struct rowBuf *rowBuf, int size) -/* Clean up rowBuf and give it a new lm and buffer[size]. */ -{ -resetRowBuf(rowBuf); -rowBuf->lm = lmInit(0); -rowBuf->size = size; -lmAllocArray(rowBuf->lm, rowBuf->buf, size); -} - static void updateNextChunkState(struct annoStreamDb *self, int queryMaxItems) /* If the just-fetched interval list was limited to ASD_CHUNK_SIZE, set doNextChunk * and trim the last row(s) so that when we query the next chunk, we don't get * repeat rows due to querying a start coord that was already returned. */ { struct rowBuf *rowBuf = &self->rowBuf; if (queryMaxItems == ASD_CHUNK_SIZE && rowBuf->size == ASD_CHUNK_SIZE) { self->doNextChunk = TRUE; // Starting at the last row in rowBuf, work back to find a value with a different start. int ix = rowBuf->size - 1; char **words = rowBuf->buf[ix]; int startIx = self->startIx + self->omitBin; uint lastStart = atoll(words[startIx]); for (ix = rowBuf->size - 2; ix >= 0; ix--)