/ Check-in [0c8a5b88]
Login

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

Overview
Comment:Merge updates from trunk, and especially the ".mode quote" enhancement to the shell.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | est_count_pragma
Files: files | file ages | folders
SHA1:0c8a5b8844df3389881aecd8e853eb3c78edd954
User & Date: drh 2016-10-21 17:45:06
Context
2016-10-21
18:01
When reading from an index, the shared-cache lock must be on the corresponding table. check-in: 04fe12b5 user: drh tags: est_count_pragma
17:45
Merge updates from trunk, and especially the ".mode quote" enhancement to the shell. check-in: 0c8a5b88 user: drh tags: est_count_pragma
17:39
Add ".mode quote" to the command-line shell. check-in: c4f5fa78 user: drh tags: trunk
17:25
Add the btree_sample(INDEX,LOCATION,LIMIT) pragma. check-in: affc2ef5 user: drh tags: est_count_pragma
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added ext/rbu/rbudor.test.

            1  +# 2016 October 21
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This test file focuses on interactions between RBU and the feature
           13  +# enabled by SQLITE_DIRECT_OVERFLOW_READ - Direct Overflow Read.
           14  +#
           15  +
           16  +if {![info exists testdir]} {
           17  +  set testdir [file join [file dirname [info script]] .. .. test]
           18  +}
           19  +source $testdir/tester.tcl
           20  +set ::testprefix rbudor
           21  +
           22  +set bigA [string repeat a 5000]
           23  +set bigB [string repeat b 5000]
           24  +do_execsql_test 1.0 {
           25  +  PRAGMA page_size = 1024;
           26  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);
           27  +  INSERT INTO t1 VALUES(1, $bigA);
           28  +} {}
           29  +
           30  +do_test 1.1 {
           31  +  forcedelete rbu.db
           32  +  sqlite3 rbu rbu.db 
           33  +  rbu eval {
           34  +    CREATE TABLE data_t1(a, b, rbu_control);
           35  +    INSERT INTO data_t1 VALUES(2, $bigB, 0);
           36  +  }
           37  +  rbu close
           38  +} {}
           39  +
           40  +do_test 1.2 {
           41  +  sqlite3rbu rbu test.db rbu.db
           42  +  while {[rbu state]!="checkpoint"} {
           43  +    rbu step
           44  +  }
           45  +  rbu step
           46  +  db eval { SELECT * FROM t1 }
           47  +} [list 1 $bigA 2 $bigB]
           48  +
           49  +do_test 1.3 {
           50  +  while {[rbu step]=="SQLITE_OK"} {}
           51  +  rbu close
           52  +} {SQLITE_DONE}
           53  +
           54  +do_execsql_test 1.4 {
           55  +  SELECT * FROM t1 
           56  +} [list 1 $bigA 2 $bigB]
           57  +
           58  +finish_test
           59  +

Changes to src/btree.c.

  4604   4604           ** up loading large records that span many overflow pages.
  4605   4605           */
  4606   4606           if( (eOp&0x01)==0                                      /* (1) */
  4607   4607            && offset==0                                          /* (2) */
  4608   4608            && (bEnd || a==ovflSize)                              /* (6) */
  4609   4609            && pBt->inTransaction==TRANS_READ                     /* (4) */
  4610   4610            && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
  4611         -         && pBt->pPage1->aData[19]==0x01                       /* (5) */
         4611  +         && 0==sqlite3PagerUseWal(pBt->pPager)                 /* (5) */
  4612   4612            && &pBuf[-4]>=pBufStart                               /* (7) */
  4613   4613           ){
  4614   4614             u8 aSave[4];
  4615   4615             u8 *aWrite = &pBuf[-4];
  4616   4616             assert( aWrite>=pBufStart );                         /* hence (7) */
  4617   4617             memcpy(aSave, aWrite, 4);
  4618   4618             rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));

Changes to src/ctime.c.

    61     61     "DEBUG",
    62     62   #endif
    63     63   #if SQLITE_DEFAULT_LOCKING_MODE
    64     64     "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
    65     65   #endif
    66     66   #if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
    67     67     "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
           68  +#endif
           69  +#if SQLITE_DIRECT_OVERFLOW_READ
           70  +  "DIRECT_OVERFLOW_READ",
    68     71   #endif
    69     72   #if SQLITE_DISABLE_DIRSYNC
    70     73     "DISABLE_DIRSYNC",
    71     74   #endif
    72     75   #if SQLITE_DISABLE_LFS
    73     76     "DISABLE_LFS",
    74     77   #endif

Changes to src/pager.c.

   813    813   #define isOpen(pFd) ((pFd)->pMethods!=0)
   814    814   
   815    815   /*
   816    816   ** Return true if this pager uses a write-ahead log instead of the usual
   817    817   ** rollback journal. Otherwise false.
   818    818   */
   819    819   #ifndef SQLITE_OMIT_WAL
   820         -static int pagerUseWal(Pager *pPager){
          820  +int sqlite3PagerUseWal(Pager *pPager){
   821    821     return (pPager->pWal!=0);
   822    822   }
          823  +# define pagerUseWal(x) sqlite3PagerUseWal(x)
   823    824   #else
   824    825   # define pagerUseWal(x) 0
   825    826   # define pagerRollbackWal(x) 0
   826    827   # define pagerWalFrames(v,w,x,y) 0
   827    828   # define pagerOpenWalIfPresent(z) SQLITE_OK
   828    829   # define pagerBeginReadTransaction(z) SQLITE_OK
   829    830   #endif

Changes to src/pager.h.

   174    174   
   175    175   #ifndef SQLITE_OMIT_WAL
   176    176     int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
   177    177     int sqlite3PagerWalSupported(Pager *pPager);
   178    178     int sqlite3PagerWalCallback(Pager *pPager);
   179    179     int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
   180    180     int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
          181  +  int sqlite3PagerUseWal(Pager *pPager);
   181    182   # ifdef SQLITE_ENABLE_SNAPSHOT
   182    183     int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
   183    184     int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
   184    185   # endif
          186  +#else
          187  +# define sqlite3PagerUseWal(x) 0
   185    188   #endif
   186    189   
   187    190   #ifdef SQLITE_ENABLE_ZIPVFS
   188    191     int sqlite3PagerWalFramesize(Pager *pPager);
   189    192   #endif
   190    193   
   191    194   /* Functions used to query pager state and configuration. */

Changes to src/shell.c.

   664    664   */
   665    665   #define MODE_Line     0  /* One column per line.  Blank line between records */
   666    666   #define MODE_Column   1  /* One record per line in neat columns */
   667    667   #define MODE_List     2  /* One record per line with a separator */
   668    668   #define MODE_Semi     3  /* Same as MODE_List but append ";" to each line */
   669    669   #define MODE_Html     4  /* Generate an XHTML table */
   670    670   #define MODE_Insert   5  /* Generate SQL "insert" statements */
   671         -#define MODE_Tcl      6  /* Generate ANSI-C or TCL quoted elements */
   672         -#define MODE_Csv      7  /* Quote strings, numbers are plain */
   673         -#define MODE_Explain  8  /* Like MODE_Column, but do not truncate data */
   674         -#define MODE_Ascii    9  /* Use ASCII unit and record separators (0x1F/0x1E) */
   675         -#define MODE_Pretty  10  /* Pretty-print schemas */
          671  +#define MODE_Quote    6  /* Quote values as for SQL */
          672  +#define MODE_Tcl      7  /* Generate ANSI-C or TCL quoted elements */
          673  +#define MODE_Csv      8  /* Quote strings, numbers are plain */
          674  +#define MODE_Explain  9  /* Like MODE_Column, but do not truncate data */
          675  +#define MODE_Ascii   10  /* Use ASCII unit and record separators (0x1F/0x1E) */
          676  +#define MODE_Pretty  11  /* Pretty-print schemas */
   676    677   
   677    678   static const char *modeDescr[] = {
   678    679     "line",
   679    680     "column",
   680    681     "list",
   681    682     "semi",
   682    683     "html",
   683    684     "insert",
          685  +  "quote",
   684    686     "tcl",
   685    687     "csv",
   686    688     "explain",
   687    689     "ascii",
   688    690     "prettyprint",
   689    691   };
   690    692   
................................................................................
  1194   1196             output_csv(p, azArg[i], i<nArg-1);
  1195   1197           }
  1196   1198           utf8_printf(p->out, "%s", p->rowSeparator);
  1197   1199         }
  1198   1200         setTextMode(p->out, 1);
  1199   1201         break;
  1200   1202       }
         1203  +    case MODE_Quote:
  1201   1204       case MODE_Insert: {
  1202   1205         p->cnt++;
  1203   1206         if( azArg==0 ) break;
  1204         -      utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
  1205         -      if( p->showHeader ){
  1206         -        raw_printf(p->out,"(");
  1207         -        for(i=0; i<nArg; i++){
  1208         -          char *zSep = i>0 ? ",": "";
  1209         -          utf8_printf(p->out, "%s%s", zSep, azCol[i]);
         1207  +      if( p->cMode==MODE_Insert ){
         1208  +        utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
         1209  +        if( p->showHeader ){
         1210  +          raw_printf(p->out,"(");
         1211  +          for(i=0; i<nArg; i++){
         1212  +            char *zSep = i>0 ? ",": "";
         1213  +            utf8_printf(p->out, "%s%s", zSep, azCol[i]);
         1214  +          }
         1215  +          raw_printf(p->out,")");
  1210   1216           }
  1211         -        raw_printf(p->out,")");
         1217  +        raw_printf(p->out," VALUES(");
  1212   1218         }
  1213         -      raw_printf(p->out," VALUES(");
  1214   1219         for(i=0; i<nArg; i++){
  1215   1220           char *zSep = i>0 ? ",": "";
  1216   1221           if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
  1217   1222             utf8_printf(p->out,"%sNULL",zSep);
  1218   1223           }else if( aiType && aiType[i]==SQLITE_TEXT ){
  1219   1224             if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
  1220   1225             output_quoted_string(p->out, azArg[i]);
................................................................................
  1229   1234           }else if( isNumber(azArg[i], 0) ){
  1230   1235             utf8_printf(p->out,"%s%s",zSep, azArg[i]);
  1231   1236           }else{
  1232   1237             if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
  1233   1238             output_quoted_string(p->out, azArg[i]);
  1234   1239           }
  1235   1240         }
  1236         -      raw_printf(p->out,");\n");
         1241  +      raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n");
  1237   1242         break;
  1238   1243       }
  1239   1244       case MODE_Ascii: {
  1240   1245         if( p->cnt++==0 && p->showHeader ){
  1241   1246           for(i=0; i<nArg; i++){
  1242   1247             if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
  1243   1248             utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
................................................................................
  2173   2178     "                         ascii    Columns/rows delimited by 0x1F and 0x1E\n"
  2174   2179     "                         csv      Comma-separated values\n"
  2175   2180     "                         column   Left-aligned columns.  (See .width)\n"
  2176   2181     "                         html     HTML <table> code\n"
  2177   2182     "                         insert   SQL insert statements for TABLE\n"
  2178   2183     "                         line     One value per line\n"
  2179   2184     "                         list     Values delimited by .separator strings\n"
         2185  +  "                         quote    Escape answers as for SQL\n"
  2180   2186     "                         tabs     Tab-separated values\n"
  2181   2187     "                         tcl      TCL list elements\n"
  2182   2188     ".nullvalue STRING      Use STRING in place of NULL values\n"
  2183   2189     ".once FILENAME         Output for the next SQL command only to FILENAME\n"
  2184   2190     ".open ?--new? ?FILE?   Close existing database and reopen FILE\n"
  2185   2191     "                         The --new starts with an empty file\n"
  2186   2192     ".output ?FILENAME?     Send output to FILENAME or stdout\n"
................................................................................
  3973   3979         sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
  3974   3980       }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
  3975   3981         p->mode = MODE_List;
  3976   3982         sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
  3977   3983       }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
  3978   3984         p->mode = MODE_Insert;
  3979   3985         set_table_name(p, nArg>=3 ? azArg[2] : "table");
         3986  +    }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
         3987  +      p->mode = MODE_Quote;
  3980   3988       }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
  3981   3989         p->mode = MODE_Ascii;
  3982   3990         sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
  3983   3991         sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
  3984   3992       }else {
  3985   3993         raw_printf(stderr, "Error: mode should be one of: "
  3986   3994            "ascii column csv html insert line list tabs tcl\n");

Changes to test/ctime.test.

   220    220   do_test ctime-2.5.$tc {
   221    221     set N -1
   222    222     set ans [ catchsql {
   223    223       SELECT sqlite_compileoption_get($N);
   224    224     } ]
   225    225   } {0 {{}}}
   226    226   
          227  +#--------------------------------------------------------------------------
          228  +# Test that SQLITE_DIRECT_OVERFLOW_READ is reflected in the output of
          229  +# "PRAGMA compile_options".
          230  +#
          231  +ifcapable direct_read {
          232  +  set res 1
          233  +} else {
          234  +  set res 0
          235  +}
          236  +do_test ctime-3.0.1 {
          237  +  expr [lsearch [db eval {PRAGMA compile_options}] DIRECT_OVERFLOW_READ]>=0
          238  +} $res
   227    239   
   228    240   finish_test

Changes to test/incrblob4.test.

    82     82   do_test 3.3 {
    83     83     set new [string repeat % 900]
    84     84     execsql { UPDATE t1 SET v = $new WHERE k = 20 }
    85     85     execsql { DELETE FROM t1 WHERE k=19 }
    86     86     execsql { INSERT INTO t1(v) VALUES($new) }
    87     87   } {}
    88     88   
           89  +#-------------------------------------------------------------------------
           90  +# Test that it is not possible to DROP a table with an incremental blob
           91  +# cursor open on it.
           92  +#
           93  +do_execsql_test 4.1 {
           94  +  CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
           95  +  INSERT INTO t2 VALUES(456, '0123456789');
           96  +}
           97  +do_test 4.2 {
           98  +  set blob [db incrblob -readonly t2 b 456]
           99  +  read $blob 5
          100  +} {01234}
          101  +do_catchsql_test 4.3 {
          102  +  DROP TABLE t2
          103  +} {1 {database table is locked}}
          104  +do_test 4.4 {
          105  +  sqlite3_extended_errcode db
          106  +} {SQLITE_LOCKED}
          107  +close $blob
          108  +
    89    109   finish_test
          110  +