diff --git a/env/dos/dos.c b/env/dos/dos.c index ec9fd6c..7f02c21 100644 --- a/env/dos/dos.c +++ b/env/dos/dos.c @@ -67,7 +67,7 @@ int fputs_dos(const char *str, FILE *stream) { output = d_charsetEncode((char *)str, consoleEncoding, &len); /* eat last trailing newline (if we print something else we'll display it then) */ - if(output[len-1] == '\n') { + if(output && output[len-1] == '\n') { newline = TRUE; lastWasErr = stream == stderr; output[len-1] = '\0'; diff --git a/env/win32/win32.c b/env/win32/win32.c index fdc2d2c..cb16cd7 100644 --- a/env/win32/win32.c +++ b/env/win32/win32.c @@ -64,7 +64,7 @@ int fputs_w32(const char *str, FILE *stream) { output = d_charsetEncode((char *)str, ENC_UTF16LE, &len); - if(output[len-2] == '\n') { + if(output && output[len-2] == '\n') { newline = TRUE; len -= 2; } @@ -118,7 +118,7 @@ int fputs_w32(const char *str, FILE *stream) { output = d_charsetEncode((char *)str, consoleEncoding, &len); /* eat last trailing newline. If we print something else we'll display it at that time */ - if(output[len-1] == '\n') { + if(output && output[len-1] == '\n') { newline = TRUE; lastWasErr = stream == stderr; output[len-1] = '\0'; diff --git a/querycsv.h b/querycsv.h index b0539a9..eaa3fbd 100644 --- a/querycsv.h +++ b/querycsv.h @@ -80,6 +80,7 @@ #define TRE_BLACK 1 #define TRE_RED 2 #define TRE_CONVERTED 3 +#define TRE_SKIP 4 #define isRed(x) (x != NULL && x->type == TRE_RED) /* short codes for the character encodings we want to support */ diff --git a/split/groupResultsInner.c b/split/groupResultsInner.c index 5371b18..af7fa39 100644 --- a/split/groupResultsInner.c +++ b/split/groupResultsInner.c @@ -2,50 +2,39 @@ void groupResultsInner( struct qryData *query, struct resultColumnValue *columns, - int i + int i, + struct resultTree *item ) { - struct resultColumnValue *previousMatch; + struct resultTree *tempItem; MAC_YIELD - if(i == 0) { - updateRunningCounts(query, columns, TRUE); - - if(query->recordCount > 1) { - query->match = columns; - } - else { - addGroupedResult(query, columns); - } - - return; + if(item->type == TRE_SKIP) { + cleanup_matchValues(query, &columns); } + else { + query->groupCount = 0; - previousMatch = query->match; + updateRunningCounts(query, item); - /* if the current record to look at is identical to the previous one */ - /* if no group by clause then every record is part of one group */ - if( - query->groupByClause == NULL || + /* look at the next item */ + tempItem = item->link[1]; + + /* while the next nth result is part of the same group + as this result, add to the number of items to look ahead */ + while( + tempItem && recordCompare( - (void *)previousMatch, (void *)columns, + (void *)tempItem->columns, (void *)query - ) != 0 + ) == 0 ) { - addGroupedResult(query, previousMatch); - - updateRunningCounts(query, columns, TRUE); - - previousMatch = query->match = columns; - } - else { - updateRunningCounts(query, columns, FALSE); - - cleanup_matchValues(query, &columns); - } + updateRunningCounts(query, tempItem); + tempItem->type = TRE_SKIP; + tempItem = tempItem->link[1]; + } - if(i == query->recordCount - 1) { - addGroupedResult(query, previousMatch); + addGroupedResult(query, columns); } } diff --git a/split/outputResult.c b/split/outputResult.c index 198d2bb..4e4ff22 100644 --- a/split/outputResult.c +++ b/split/outputResult.c @@ -2,7 +2,8 @@ void outputResult( struct qryData *query, struct resultColumnValue *columns, - int currentIndex + int currentIndex, + struct resultTree *item ) { struct resultColumn *currentResultColumn; struct resultColumnValue *field; @@ -82,5 +83,4 @@ void outputResult( if(currentIndex > -1) { cleanup_matchValues(query, &columns); } - } diff --git a/split/runQuery.c b/split/runQuery.c index e1eeace..12fdd63 100644 --- a/split/runQuery.c +++ b/split/runQuery.c @@ -33,7 +33,7 @@ int runQuery(char *queryFileName) { while(getMatchingRecord(&query, match)) { /* print record to stdout */ query.recordCount++; - outputResult(&query, match, -1); + outputResult(&query, match, -1, NULL); } cleanup_matchValues(&query, &match); diff --git a/split/tree_walkAndCleanup.c b/split/tree_walkAndCleanup.c index 96ffee0..34909e1 100644 --- a/split/tree_walkAndCleanup.c +++ b/split/tree_walkAndCleanup.c @@ -4,7 +4,7 @@ void tree_walkAndCleanup( struct qryData *query, struct resultTree **root, - void (*callback)(struct qryData *, struct resultColumnValue *, int) + void (*callback)(struct qryData *, struct resultColumnValue *, int, struct resultTree *) ) { struct resultTree *currentResult; struct resultTree *tempResult; @@ -85,7 +85,8 @@ void tree_walkAndCleanup( callback( query, currentResult->columns, - i++ + i++, + currentResult ); tempResult = currentResult; diff --git a/split/updateRunningCounts.c b/split/updateRunningCounts.c index a40d7e8..59031ea 100644 --- a/split/updateRunningCounts.c +++ b/split/updateRunningCounts.c @@ -1,8 +1,10 @@ void updateRunningCounts( struct qryData *query, - struct resultColumnValue *match, - int startNewGroup + struct resultTree *item ) { + struct resultTree *tempItem; + struct resultColumnValue *match = item->columns; + struct columnRefHashEntry *currentHashEntry; struct columnReference *currentReference; struct resultColumn *currentResultColumn; @@ -34,7 +36,7 @@ void updateRunningCounts( ) { /* if query->groupCount = 1 then we're starting a new group */ - if(startNewGroup) { + if(query->groupCount == 1) { freeAndZero(currentResultColumn->groupText); currentResultColumn->groupNum = ctof(0); currentResultColumn->groupCount = 0; @@ -46,11 +48,12 @@ void updateRunningCounts( stringGet((unsigned char **)(&tempString), field, query->params); /* distinct groupings. only add to the count if the column value hasn't aready been seen */ - /* TODO: fix this code. we'll need to keep all results until the grouping is finished because of this */ - /*if(currentResultColumn->groupType > GRP_STAR) { + if(currentResultColumn->groupType > GRP_STAR) { /* distinct variants */ if(query->groupCount > 1) { + tempItem = item->link[0]; + for(j = 1; j < query->groupCount; j++) { - stringGet((unsigned char **)(&tempString2), &(match[(currentResultColumn->resultColumnIndex) - (query->columnCount)]), query->params); + stringGet((unsigned char **)(&tempString2), &(tempItem->columns[currentResultColumn->resultColumnIndex]), query->params); if(strCompare( (unsigned char **)(&tempString), @@ -64,12 +67,13 @@ void updateRunningCounts( } freeAndZero(tempString2); + tempItem = tempItem->link[0]; } } else { j = query->groupCount; } - }*/ + } switch(currentResultColumn->groupType) { case GRP_DIS_COUNT: {