SQLite

Check-in [65e02368e2]
Login

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

Overview
Comment:Add further tests for sqlite3rbu_bp_progress(). Fix a problem in handling WITHOUT ROWID tables in the same.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | rbu-percent-progress
Files: files | file ages | folders
SHA1: 65e02368e2b6cec349ea71af5a456d6783b0d15e
User & Date: dan 2016-03-18 20:12:28.661
Context
2016-03-19
15:34
Merge latest trunk changes, including fixes to test script rbudiff.test, into this branch. (check-in: 734fc68fb1 user: dan tags: rbu-percent-progress)
2016-03-18
20:12
Add further tests for sqlite3rbu_bp_progress(). Fix a problem in handling WITHOUT ROWID tables in the same. (check-in: 65e02368e2 user: dan tags: rbu-percent-progress)
18:56
Change the name of the new API on this branch to "sqlite3_bp_progress". Add tests and documentation for the same. (check-in: 1a1b69e87e user: dan tags: rbu-percent-progress)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/rbu/rbuprogress.test.
66
67
68
69
70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97

98
99
100
101
102
103
104

105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
proc do_sp_test {tn bReopen target rbu reslist} {
  uplevel [list do_test $tn [subst -nocommands {
    if {$bReopen==0} { sqlite3rbu rbu $target $rbu }
    set res [list]
    while 1 {
      if {$bReopen} { sqlite3rbu rbu $target $rbu }
      set rc [rbu step]
      if {[set rc] != "SQLITE_OK"} { error "error 1" }
      lappend res [lindex [rbu bp_progress] 0]
      if {[lindex [set res] end]==10000} break
      if {$bReopen} { rbu close }
    }
    if {[set res] != [list $reslist]} {

      error "1. reslist incorrect (expect=$reslist got=[set res])"
    }

    # One step to clean up the temporary tables used to update the only
    # target table in the rbu database. And one more to move the *-oal 
    # file to *-wal. After each of these steps, the progress remains
    # at "10000 0".
    #
    if {[lindex [list $reslist] 0]!=-1} {
      rbu step
      set res [rbu bp_progress]
      if {[set res] != [list 10000 0]} {

        error "2. reslist incorrect (expect=10000 0 got=[set res])"
      }
    }

    rbu step
    set res [rbu bp_progress]
    if {[set res] != [list 10000 0]} {

      error "3. reslist incorrect (expect=10000 0 got=[set res])"
    }

    # Do the checkpoint.
    while {[rbu step]=="SQLITE_OK"} { 
      foreach {a b} [rbu bp_progress] {}
      if {[set a]!=10000 || [set b]<=0 || [set b]>10000} {

        error "4. reslist incorrect (expect=10000 1..10000 got=[set a] [set b])"
      }
    }

    set res [rbu bp_progress]
    if {[set res] != [list 10000 10000]} {

      error "5. reslist is incorrect (expect=10000 10000 got=[set res])"
    }

    rbu close
  }] {SQLITE_DONE}]
}

foreach {bReopen} { 0 1 } {

  reset_db
  do_test 2.$bReopen.1.0 {
    execsql {
      CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
    }
    create_db_file rbu.db {
      CREATE TABLE data_t1(a, b, c, rbu_control);







|





>












>







>







>






>








<







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
proc do_sp_test {tn bReopen target rbu reslist} {
  uplevel [list do_test $tn [subst -nocommands {
    if {$bReopen==0} { sqlite3rbu rbu $target $rbu }
    set res [list]
    while 1 {
      if {$bReopen} { sqlite3rbu rbu $target $rbu }
      set rc [rbu step]
      if {[set rc] != "SQLITE_OK"} { rbu close ; error "error 1" }
      lappend res [lindex [rbu bp_progress] 0]
      if {[lindex [set res] end]==10000} break
      if {$bReopen} { rbu close }
    }
    if {[set res] != [list $reslist]} {
      rbu close
      error "1. reslist incorrect (expect=$reslist got=[set res])"
    }

    # One step to clean up the temporary tables used to update the only
    # target table in the rbu database. And one more to move the *-oal 
    # file to *-wal. After each of these steps, the progress remains
    # at "10000 0".
    #
    if {[lindex [list $reslist] 0]!=-1} {
      rbu step
      set res [rbu bp_progress]
      if {[set res] != [list 10000 0]} {
        rbu close
        error "2. reslist incorrect (expect=10000 0 got=[set res])"
      }
    }

    rbu step
    set res [rbu bp_progress]
    if {[set res] != [list 10000 0]} {
      rbu close
      error "3. reslist incorrect (expect=10000 0 got=[set res])"
    }

    # Do the checkpoint.
    while {[rbu step]=="SQLITE_OK"} { 
      foreach {a b} [rbu bp_progress] {}
      if {[set a]!=10000 || [set b]<=0 || [set b]>10000} {
        rbu close
        error "4. reslist incorrect (expect=10000 1..10000 got=[set a] [set b])"
      }
    }

    set res [rbu bp_progress]
    if {[set res] != [list 10000 10000]} {
      rbu close
      error "5. reslist is incorrect (expect=10000 10000 got=[set res])"
    }

    rbu close
  }] {SQLITE_DONE}]
}

foreach {bReopen} { 0 1 } {

  reset_db
  do_test 2.$bReopen.1.0 {
    execsql {
      CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
    }
    create_db_file rbu.db {
      CREATE TABLE data_t1(a, b, c, rbu_control);
283
284
285
286
287
288
289
290













































































































291
292
      INSERT INTO rbu_count VALUES('data_t3', 1);
      INSERT INTO rbu_count VALUES('data_t4', 1);
    }
  } {}
  do_phase2_test 3.$bReopen.1.1 $bReopen test.db rbu.db 5
}















































































































finish_test









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
      INSERT INTO rbu_count VALUES('data_t3', 1);
      INSERT INTO rbu_count VALUES('data_t4', 1);
    }
  } {}
  do_phase2_test 3.$bReopen.1.1 $bReopen test.db rbu.db 5
}


foreach {bReopen} { 0 1 } {
  foreach {tn tbl} {
    ipk { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) }
    wr  { CREATE TABLE t1(a INT PRIMARY KEY, b, c) WITHOUT ROWID }
    pk  { CREATE TABLE t1(a INT PRIMARY KEY, b, c) }
  } {

    foreach {tn2 rbusql r1 r3} {
      1 {
        CREATE TABLE data0_t1(a, b, c, rbu_control);
        INSERT INTO data0_t1 VALUES(15, 15, 15, 0);
        INSERT INTO data0_t1 VALUES(20, 20, 20, 0);
        CREATE TABLE rbu_count(tbl, cnt);
        INSERT INTO rbu_count VALUES('data0_t1', 2); 
      } 
      {2500 5000 7500 10000}
      {1666 3333 5000 6666 8333 10000}

      2 {
        CREATE TABLE data0_t1(a, b, c, rbu_control);
        INSERT INTO data0_t1 VALUES(10, 10, 10, 2);
        CREATE TABLE rbu_count(tbl, cnt);
        INSERT INTO rbu_count VALUES('data0_t1', 1); 
      } 
      {3333 6666 10000}
      {2000 4000 6000 8000 10000}

      3 {
        CREATE TABLE data0_t1(a, b, c, rbu_control);
        INSERT INTO data0_t1 VALUES(7, 7, 7, 2);
        INSERT INTO data0_t1 VALUES(10, 10, 10, 2);
        CREATE TABLE rbu_count(tbl, cnt);
        INSERT INTO rbu_count VALUES('data0_t1', 2); 
      } 
      {2500 4000 6000 8000 10000}
      {1666 2500 3750 5000 6250 7500 8750 10000}

    } {

      reset_db ; execsql $tbl
      do_test 4.$tn.$bReopen.$tn2.0 {
        execsql {
          CREATE INDEX t1c ON t1(c);
          INSERT INTO t1 VALUES(1, 1, 1);
          INSERT INTO t1 VALUES(5, 5, 5);
          INSERT INTO t1 VALUES(10, 10, 10);
        }
        create_db_file rbu.db $rbusql
      } {}

      set R(ipk) $r1
      set R(wr) $r1
      set R(pk) $r3
      do_sp_test 4.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn)
    }
  }
}

foreach {bReopen} { 0 1 } {
  foreach {tn tbl} {
    nopk { 
      CREATE TABLE t1(a, b, c);
      CREATE INDEX t1c ON t1(c);
    }
    vtab { 
      CREATE VIRTUAL TABLE t1 USING fts5(a, b, c);
    }
  } {

    foreach {tn2 rbusql r1 r2} {
      1 {
        CREATE TABLE data0_t1(a, b, c, rbu_rowid, rbu_control);
        INSERT INTO data0_t1 VALUES(15, 15, 15, 4, 0);
        INSERT INTO data0_t1 VALUES(20, 20, 20, 5, 0);
        CREATE TABLE rbu_count(tbl, cnt);
        INSERT INTO rbu_count VALUES('data0_t1', 2); 
      } 
      {2500 5000 7500 10000}
      {5000 10000}

      2 {
        CREATE TABLE data0_t1(rbu_rowid, a, b, c, rbu_control);
        INSERT INTO data0_t1 VALUES(0, 7, 7, 7, 2);
        INSERT INTO data0_t1 VALUES(2, 10, 10, 10, 2);
        CREATE TABLE rbu_count(tbl, cnt);
        INSERT INTO rbu_count VALUES('data0_t1', 2); 
      } 
      {2500 4000 6000 8000 10000}
      {5000 10000}
    } {

      reset_db ; execsql $tbl
      do_test 5.$tn.$bReopen.$tn2.0 {
        execsql {
          INSERT INTO t1 VALUES(1, 1, 1);
          INSERT INTO t1 VALUES(5, 5, 5);
          INSERT INTO t1 VALUES(10, 10, 10);
        }
        create_db_file rbu.db $rbusql
      } {}

      set R(nopk) $r1
      set R(vtab) $r2
      do_sp_test 5.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn)
    }
  }
}


finish_test

Changes to ext/rbu/sqlite3rbu.c.
1197
1198
1199
1200
1201
1202
1203





1204
1205
1206
1207
1208
1209
1210
      int iCid = sqlite3_column_int(pXInfo, 1);
      if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
    }
    rbuFinalize(p, pXInfo);
    bIndex = 1;
    pIter->nIndex++;
  }






  rbuFinalize(p, pList);
  if( bIndex==0 ) pIter->abIndexed = 0;
}


/*







>
>
>
>
>







1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
      int iCid = sqlite3_column_int(pXInfo, 1);
      if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
    }
    rbuFinalize(p, pXInfo);
    bIndex = 1;
    pIter->nIndex++;
  }

  if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
    /* "PRAGMA index_list" includes the main PK b-tree */
    pIter->nIndex--;
  }

  rbuFinalize(p, pList);
  if( bIndex==0 ) pIter->abIndexed = 0;
}


/*
1309
1310
1311
1312
1313
1314
1315

1316
1317
1318
1319
1320
1321
1322
        iOrder++;
      }
    }

    rbuFinalize(p, pStmt);
    rbuObjIterCacheIndexedCols(p, pIter);
    assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 );

  }

  return p->rc;
}

/*
** This function constructs and returns a pointer to a nul-terminated 







>







1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
        iOrder++;
      }
    }

    rbuFinalize(p, pStmt);
    rbuObjIterCacheIndexedCols(p, pIter);
    assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 );
    assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 );
  }

  return p->rc;
}

/*
** This function constructs and returns a pointer to a nul-terminated 
3118
3119
3120
3121
3122
3123
3124

3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
  sqlite3_stmt *pStmt = 0;
  char *zErrmsg = 0;
  int rc;

  assert( nVal==1 );
  
  rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, 

      sqlite3_mprintf("PRAGMA index_list = %Q", sqlite3_value_text(apVal[0]))
  );
  if( rc!=SQLITE_OK ){
    sqlite3_result_error(pCtx, zErrmsg, -1);
  }else{
    int nIndex = 0;
    while( SQLITE_ROW==sqlite3_step(pStmt) ){
      nIndex++;
    }
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ){
      sqlite3_result_int(pCtx, nIndex);
    }else{
      sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1);
    }







>
|





|
|







3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
  sqlite3_stmt *pStmt = 0;
  char *zErrmsg = 0;
  int rc;

  assert( nVal==1 );
  
  rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, 
      sqlite3_mprintf("SELECT count(*) FROM sqlite_master "
        "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
  );
  if( rc!=SQLITE_OK ){
    sqlite3_result_error(pCtx, zErrmsg, -1);
  }else{
    int nIndex = 0;
    if( SQLITE_ROW==sqlite3_step(pStmt) ){
      nIndex = sqlite3_column_int(pStmt, 0);
    }
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ){
      sqlite3_result_int(pCtx, nIndex);
    }else{
      sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1);
    }