/ Check-in [fdef2a92]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add ALWAYS() macros on results of sqlite3_aggregate_context() calls in xInverse() implements, since they can never fail.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:fdef2a921d451c66ca535021d08af3ec1ab53283da2d2979378a799fd8731ef9
User & Date: drh 2018-07-07 19:47:21
Context
2018-07-07
20:13
Fix an LSM problem caused by using the same cursor for equality and range scans. check-in: f05bead3 user: dan tags: trunk
19:47
Add ALWAYS() macros on results of sqlite3_aggregate_context() calls in xInverse() implements, since they can never fail. check-in: fdef2a92 user: drh tags: trunk
19:36
Add an assert() to help verify that OP_AggInverse is never called on an accumulator that has not previously been processed by OP_AggStep. check-in: 42138891 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/misc/json1.c.

1844
1845
1846
1847
1848
1849
1850
1851


1852
1853
1854
1855
1856
1857
1858
  sqlite3_value **argv
){
  int i;
  int inStr = 0;
  char *z;
  JsonString *pStr;
  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
  if( !pStr ) return;


  z = pStr->zBuf;
  for(i=1; z[i]!=',' || inStr; i++){
    assert( i<pStr->nUsed );
    if( z[i]=='"' ){
      inStr = !inStr;
    }else if( z[i]=='\\' ){
      i++;







|
>
>







1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
  sqlite3_value **argv
){
  int i;
  int inStr = 0;
  char *z;
  JsonString *pStr;
  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
  /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
  ** always have been called to initalize it */
  if( NEVER(!pStr) ) return;
  z = pStr->zBuf;
  for(i=1; z[i]!=',' || inStr; i++){
    assert( i<pStr->nUsed );
    if( z[i]=='"' ){
      inStr = !inStr;
    }else if( z[i]=='\\' ){
      i++;

Changes to src/func.c.

1517
1518
1519
1520
1521
1522
1523


1524
1525
1526
1527
1528
1529
1530
1531
....
1601
1602
1603
1604
1605
1606
1607

1608
1609
1610
1611
1612
1613
1614
1615
....
1720
1721
1722
1723
1724
1725
1726
1727


1728
1729
1730
1731
1732
1733
1734
static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){
  SumCtx *p;
  int type;
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  p = sqlite3_aggregate_context(context, sizeof(*p));
  type = sqlite3_value_numeric_type(argv[0]);


  if( p && type!=SQLITE_NULL ){
    p->cnt--;
    if( type==SQLITE_INTEGER ){
      i64 v = sqlite3_value_int64(argv[0]);
      p->rSum -= v;
      if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, -1*v) ){
        p->overflow = 1;
      }
................................................................................
  p = sqlite3_aggregate_context(context, 0);
  sqlite3_result_int64(context, p ? p->n : 0);
}
#ifndef SQLITE_OMIT_WINDOWFUNC
static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){
  CountCtx *p;
  p = sqlite3_aggregate_context(ctx, sizeof(*p));

  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
    p->n--;
#ifdef SQLITE_DEBUG
    p->bInverse = 1;
#endif
  }
}   
#else
................................................................................
  sqlite3_value **argv
){
  int n;
  assert( argc==1 || argc==2 );
  StrAccum *pAccum;
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
  if( pAccum ){


    n = sqlite3_value_bytes(argv[0]);
    if( argc==2 ){
      n += sqlite3_value_bytes(argv[1]);
    }else{
      n++;
    }
    if( n>=pAccum->nChar ){







>
>
|







 







>
|







 







|
>
>







1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
....
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
....
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){
  SumCtx *p;
  int type;
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  p = sqlite3_aggregate_context(context, sizeof(*p));
  type = sqlite3_value_numeric_type(argv[0]);
  /* p is always non-NULL because sumStep() will have been called first
  ** to initialize it */
  if( ALWAYS(p) && type!=SQLITE_NULL ){
    p->cnt--;
    if( type==SQLITE_INTEGER ){
      i64 v = sqlite3_value_int64(argv[0]);
      p->rSum -= v;
      if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, -1*v) ){
        p->overflow = 1;
      }
................................................................................
  p = sqlite3_aggregate_context(context, 0);
  sqlite3_result_int64(context, p ? p->n : 0);
}
#ifndef SQLITE_OMIT_WINDOWFUNC
static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){
  CountCtx *p;
  p = sqlite3_aggregate_context(ctx, sizeof(*p));
  /* p is always non-NULL since countStep() will have been called first */
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){
    p->n--;
#ifdef SQLITE_DEBUG
    p->bInverse = 1;
#endif
  }
}   
#else
................................................................................
  sqlite3_value **argv
){
  int n;
  assert( argc==1 || argc==2 );
  StrAccum *pAccum;
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
  /* pAccum is always non-NULL since groupConcatStep() will have always
  ** run frist to initialize it */
  if( ALWAYS(pAccum) ){
    n = sqlite3_value_bytes(argv[0]);
    if( argc==2 ){
      n += sqlite3_value_bytes(argv[1]);
    }else{
      n++;
    }
    if( n>=pAccum->nChar ){