Frank Chang <frank_chan...@hotmail.com> wrote:
> void cIntersectingGroupCache::AGGREGATEBLOBFunc(sqlite3_context *context, int 
> argc, sqlite3_value **argv){

How come you only show one function? A user-defined aggregate function is 
actually represented by two C[++] functions - one that is called for every row 
and performs actual aggregation, and another that's called at the end of each 
group, reports the result and resets the state machine to prepare for the next 
group. You can use sqlite3_context to store state between invocations - see 
sqlite3_aggregate_context.

In light of this, it's not clear why you need PreviousFieldName.

> switch( sqlite3_value_type(argv[0]) ){

Why would argv[0] be anything other than a blob? Are you storing different 
types of data in Vertices column?

> case SQLITE_INTEGER: {
> iVal = sqlite3_value_int64(argv[0]);
> iVal = ( iVal > 0) ? 1: ( iVal < 0 ) ? -1: 0;
> sqlite3_result_int64(context, iVal);

Again - you are not supposed to report the result until you've seen all rows in 
a group (at which point your xFinal callback is called).

> case SQLITE_BLOB: {
> size = sqlite3_value_bytes(argv[0]);
> ip2 = (int *)sqlite3_value_blob(argv[0]);
> for (int i = 0; i < size/sizeof(int); i++){
> ((cIntersectingGroupCache*)(sqlite3_value_int(argv[2])))->Column3.push_back(ip2[i]);
> }

Assuming Column3 is a vector<int> (or a similar STL container), you can replace 
your loop with something like this:

vector<int>& v = 
((cIntersectingGroupCache*)(sqlite3_value_int(argv[2])))->Column3;
v.insert(v.end(), ip2, ip2 + size/sizeof(int));

> sqlite3_result_blob(context,blob,((cIntersectingGroupCache*)(sqlite3_value_int(argv[2])))->Column3.size()*sizeof(int),NULL);

And again - you shouldn't report the result until the whole group is processed 
and xFinal is called.
-- 
Igor Tandetnik

_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to