boxdb-sqlite-sys 0.4.0

BoxDB SQLite engine and native bindings (fork of libsqlite3-sys 0.38.2)
Documentation
static int boxdbSumUpdate(sqlite3_context *ctx, SumCtx *p, Mem *value, int op){
  char *error = 0;
  int rc;
  if( p->decimalMode==6 ){
    rc=boxdbNativeOp(&p->decimalSum,op,0,&p->decimalSum,value,&error);
    if( rc ){sqlite3_result_error(ctx,error ? error : "INTERVAL allocation failed",-1);sqlite3_free(error);}
    return rc;
  }
  if( p->approx && !p->ovrfl ){
    sqlite3_result_error(ctx, "DECIMAL aggregate requires an explicit REAL conversion", -1);
    return SQLITE_ERROR;
  }
  if( !boxdbIsDecimal(&p->decimalSum) ){
    p->decimalSum.db = sqlite3_context_db_handle(ctx);
    p->decimalSum.flags = MEM_Int;
    p->decimalSum.u.i = p->iSum;
  }
  rc = boxdbDecimalOp(&p->decimalSum, op, &p->decimalSum, value, &error);
  if( rc ){
    sqlite3_result_error(ctx, error ? error : "DECIMAL allocation failed", -1);
    sqlite3_free(error);
  }
  return rc;
}

/* Retain an exact overflow accumulator until a decimal promotes SUM/AVG.
** Pure integer aggregates still report SQLite's integer-overflow error. */
static int boxdbSumStep(sqlite3_context *ctx, SumCtx *p, Mem *value, int type){
  int kind=boxdbNativeKind(value);
  if( !p || type==SQLITE_NULL ) return 0;
  if( kind>=7 ){
    if( !p->decimalMode ) p->decimalMode=p->cnt ? 1 : 7;
    if( boxdbSumUpdate(ctx,p,value,1)==SQLITE_OK ){p->cnt++;p->approx=0;p->ovrfl=0;}
    return 1;
  }
  if( p->decimalMode==7 ){
    if( type!=SQLITE_NULL ) p->decimalMode=1;
  }
  if( kind || p->decimalMode==6 ){
    if( kind!=6 || strcmp(ctx->pFunc->zName,"total")==0 || (p->cnt && p->decimalMode!=6) ){
      sqlite3_result_error(ctx,"aggregate requires numeric inputs or homogeneous INTERVAL values",-1); return 1;
    }
    if( p->decimalMode!=6 ){
      static const char zero[17]="v";
      p->decimalSum.db=sqlite3_context_db_handle(ctx);
      if( sqlite3VdbeMemSetStr(&p->decimalSum,zero,17,0,SQLITE_STATIC) ){ sqlite3_result_error_nomem(ctx);return 1; }
      p->decimalMode=6;
    }
    if( boxdbSumUpdate(ctx,p,value,1)==SQLITE_OK ) p->cnt++;
    return 1;
  }
  if( strcmp(ctx->pFunc->zName,"total")==0 ) return 0;
  if( boxdbIsDecimal(value) || p->decimalMode ){
    p->decimalMode=1;
    if( boxdbSumUpdate(ctx,p,value,1)==SQLITE_OK ){
      p->cnt++;
      p->approx=0;
      p->ovrfl=0;
    }
    return 1;
  }
  if( boxdbIsDecimal(&p->decimalSum) ){
    if( type==SQLITE_INTEGER ){
      if( boxdbSumUpdate(ctx,p,value,1)!=SQLITE_OK ) return 1;
    }else{
      sqlite3VdbeMemSetNull(&p->decimalSum);
    }
  }
  return 0;
}

static int boxdbSumInverse(sqlite3_context *ctx, SumCtx *p, Mem *value, int type){
  if( !p || type==SQLITE_NULL || !boxdbKind(&p->decimalSum) ) return 0;
  if( boxdbSumUpdate(ctx,p,value,2)!=SQLITE_OK ) return 1;
  if( p->decimalMode ){ p->cnt--; return 1; }
  return 0;
}

static void boxdbAverage(sqlite3_context *ctx, SumCtx *p){
  Mem count, result;
  char *error = 0;
  memset(&count, 0, sizeof(count));
  memset(&result, 0, sizeof(result));
  count.flags = MEM_Int;
  count.u.i = p->cnt;
  result.db = sqlite3_context_db_handle(ctx);
  if( (p->decimalMode==6 ? boxdbNativeOp(&result,4,0,&p->decimalSum,&count,&error) : boxdbDecimalOp(&result, 4, &p->decimalSum, &count, &error)) ){
    sqlite3_result_error(ctx, error ? error : "DECIMAL allocation failed", -1);
    sqlite3_free(error);
  }else{
    sqlite3_result_value(ctx, &result);
  }
  sqlite3VdbeMemRelease(&result);
}

static void boxdbSumRelease(sqlite3_context *ctx){
  SumCtx *p = sqlite3_aggregate_context(ctx, 0);
  if( p ) sqlite3VdbeMemRelease(&p->decimalSum);
}