/ Check-in [443f0c28]
Login

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

Overview
Comment:Remove some bad assert() statements from the implementations of window functions percent_rank() and cume_dist().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 443f0c286f1659937fd61b4ef2de17d0d015369e5ff5249a9e0c3d0ee4925158
User & Date: dan 2018-07-06 13:25:02
Context
2018-07-06
13:48
Prevent "UNBOUNDED FOLLOWING" from being used as the starting boundary of a window-frame. And "UNBOUNDED PRECEDING" from being used as the ending boundary. check-in: e51fdf66 user: dan tags: trunk
13:25
Remove some bad assert() statements from the implementations of window functions percent_rank() and cume_dist(). check-in: 443f0c28 user: dan tags: trunk
07:42
Return an error if DISTINCT is used with a window-function (e.g. "count(DISTINCT <expr>) OVER (...)"). check-in: d59bcc8e user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.h.

   239    239   void sqlite3VdbeResolveLabel(Vdbe*, int);
   240    240   #ifdef SQLITE_COVERAGE_TEST
   241    241     int sqlite3VdbeLabelHasBeenResolved(Vdbe*,int);
   242    242   #endif
   243    243   int sqlite3VdbeCurrentAddr(Vdbe*);
   244    244   #ifdef SQLITE_DEBUG
   245    245     int sqlite3VdbeAssertMayAbort(Vdbe *, int);
   246         -  int sqlite3VdbeAssertAggContext(sqlite3_context*);
   247    246   #endif
   248    247   void sqlite3VdbeResetStepResult(Vdbe*);
   249    248   void sqlite3VdbeRewind(Vdbe*);
   250    249   int sqlite3VdbeReset(Vdbe*);
   251    250   void sqlite3VdbeSetNumCols(Vdbe*,int);
   252    251   int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
   253    252   void sqlite3VdbeCountChanges(Vdbe*);

Changes to src/vdbeapi.c.

   820    820     if( (p->pMem->flags & MEM_Agg)==0 ){
   821    821       return createAggContext(p, nByte);
   822    822     }else{
   823    823       return (void*)p->pMem->z;
   824    824     }
   825    825   }
   826    826   
   827         -/*
   828         -** This function is only used within assert() statements to check that the
   829         -** aggregate context has already been allocated. i.e.:
   830         -**
   831         -**   assert( sqlite3VdbeAssertAggContext(p) );
   832         -*/
   833         -#ifdef SQLITE_DEBUG
   834         -int sqlite3VdbeAssertAggContext(sqlite3_context *p){
   835         -  return ((p->pMem->flags & MEM_Agg)!=0);
   836         -}
   837         -#endif /* SQLITE_DEBUG */
   838         -
   839    827   /*
   840    828   ** Return the auxiliary data pointer, if any, for the iArg'th argument to
   841    829   ** the user-function defined by pCtx.
   842    830   **
   843    831   ** The left-most argument is 0.
   844    832   **
   845    833   ** Undocumented behavior:  If iArg is negative then access a cache of

Changes to src/window.c.

   251    251     sqlite3_context *pCtx, 
   252    252     int nArg,
   253    253     sqlite3_value **apArg
   254    254   ){
   255    255     struct CallCount *p;
   256    256     assert( nArg==1 );
   257    257   
   258         -  assert( sqlite3VdbeAssertAggContext(pCtx) );
   259    258     p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   260         -  if( ALWAYS(p) ){
          259  +  if( p ){
   261    260       if( p->nTotal==0 ){
   262    261         p->nTotal = sqlite3_value_int64(apArg[0]);
   263    262       }
   264    263       p->nStep++;
   265    264       if( p->nValue==0 ){
   266    265         p->nValue = p->nStep;
   267    266       }
................................................................................
   297    296     sqlite3_context *pCtx, 
   298    297     int nArg,
   299    298     sqlite3_value **apArg
   300    299   ){
   301    300     struct CallCount *p;
   302    301     assert( nArg==1 );
   303    302   
   304         -  assert( sqlite3VdbeAssertAggContext(pCtx) );
   305    303     p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   306         -  if( ALWAYS(p) ){
          304  +  if( p ){
   307    305       if( p->nTotal==0 ){
   308    306         p->nTotal = sqlite3_value_int64(apArg[0]);
   309    307       }
   310    308       p->nStep++;
   311    309     }
   312    310   }
   313    311   static void cume_distInvFunc(

Changes to test/window4.tcl.

   327    327   execsql_test 9.4 {
   328    328     SELECT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2
   329    329   }
   330    330   
   331    331   execsql_test 9.5 {
   332    332     SELECT DISTINCT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2
   333    333   }
          334  +
          335  +execsql_float_test 9.6 {
          336  +  SELECT percent_rank() OVER () FROM t1
          337  +}
          338  +
          339  +execsql_float_test 9.7 {
          340  +  SELECT cume_dist() OVER () FROM t1
          341  +}
   334    342   
   335    343   finish_test
   336    344   

Changes to test/window4.test.

  1229   1229     SELECT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2
  1230   1230   } {1 1   1 1   1 1   4 4   4 4   6 6   7 7}
  1231   1231   
  1232   1232   do_execsql_test 9.5 {
  1233   1233     SELECT DISTINCT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2
  1234   1234   } {1 1   4 4   6 6   7 7}
  1235   1235   
         1236  +do_test 9.6 {
         1237  +  set myres {}
         1238  +  foreach r [db eval {SELECT percent_rank() OVER () FROM t1}] {
         1239  +    lappend myres [format %.2f [set r]]
         1240  +  }
         1241  +  set myres
         1242  +} {0.00 0.00 0.00}
         1243  +
         1244  +do_test 9.7 {
         1245  +  set myres {}
         1246  +  foreach r [db eval {SELECT cume_dist() OVER () FROM t1}] {
         1247  +    lappend myres [format %.2f [set r]]
         1248  +  }
         1249  +  set myres
         1250  +} {1.00 1.00 1.00}
         1251  +
  1236   1252   finish_test

Changes to test/windowfault.test.

   124    124       FROM t1
   125    125       WINDOW win1 AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),
   126    126              win2 AS (ORDER BY a)
   127    127     }
   128    128   } -test {
   129    129     faultsim_test_result {0 {5 1 9 5 9 9}}
   130    130   }
          131  +
          132  +do_faultsim_test 6 -faults oom-* -prep {
          133  +  faultsim_restore_and_reopen
          134  +} -body {
          135  +  execsql {
          136  +    SELECT percent_rank() OVER (), cume_dist() OVER () FROM t1
          137  +  }
          138  +} -test {
          139  +  faultsim_test_result {0 {0.0 1.0 0.0 1.0 0.0 1.0}}
          140  +}
   131    141   
   132    142   finish_test
   133    143