Hello,

On 2018-01-29 18:08, Stephan Buchert wrote:
But then I have a related question: to get my hands on each row in SELECTs
with GROUP BY I could write an aggregate extension function. How do I see
there, when a group ends and a new one starts? I.e. How do I implement the
xStep and xFinal C functions as requested at

https://sqlite.org/c3ref/create_function.html

SQLite manages an area of memory called ``aggregate context''. When you call ``sqlite3_aggregate_context()'' from your ``xStep'' and/or ``xFinal'' then you will receive a pointer to that memory area, which is kept as long as an invocation of ``xStep''/``xFinal'' considers the same group of GROUP BY:

typedef struct myAggCtx {
  int notTheFirstTime;
  /* Other state variables follow */
} myAggCtx;

xStep(ctx, ...)
{
  myAggCtx *actx = sqlite3_aggregate_context(ctx, sizeof(myAggCtx));
  if ( 0 == actx->notTheFirstTime ) {
    /* Do your starting of group stuff */
    actx->notTheFirstTime = !0;
  }
  /* ... */
}

xFinal(ctx, ...)
  myAggCtx *actx = sqlite3_aggregate_context(ctx, sizeof(myAggCtx));
  if ( 0 == actx->notTheFirstTime ) {
    /* First time allocated context so there was no records in the group */
  }
  /* ... */
}

Beware of passing the same number of bytes each time, because ``sqlite3_aggregate_context()'' does not reallocates. If an aggregate context has been allocated previously, then ``sqlite3_aggregate_context()'' will returns the same memory area regardless of subsequent numbers of bytes passed. I.e. sqlite3_aggregate_context(ctx, 1) will return 1byte size memory -- subsequent call (while in the same group of GROUP BY) sqlite3_aggregate_context(ctx, 1000000) will return the same 1byte size memory.

-- best regards

Cezary H. Noweta
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to