Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Test cases and minor bugfixes for incremental blob APIs. (CVS 3907) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e12c522383bd40af375a52d2e68612c4 |
User & Date: | danielk1977 2007-05-03 16:31:26.000 |
Context
2007-05-03
| ||
16:55 | Get the amalgamation builder working with incremental I/O. (CVS 3908) (check-in: 92b5360165 user: drh tags: trunk) | |
16:31 | Test cases and minor bugfixes for incremental blob APIs. (CVS 3907) (check-in: e12c522383 user: danielk1977 tags: trunk) | |
13:11 | Fix a bug where accessPayload() was calling PagerWrite() on the wrong page handle. Ticket #2332. (CVS 3906) (check-in: cf9eeba7be user: danielk1977 tags: trunk) | |
Changes
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.204 2007/05/03 16:31:26 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 | ** ** When the virtual-table mechanism stablizes, we will declare the ** interface fixed, support it indefinitely, and remove this comment. ** ****** EXPERIMENTAL - subject to change without notice ************** */ typedef struct sqlite3_blob sqlite3_blob; int sqlite3_blob_open( sqlite3*, const char *zDb, const char *zTable, const char *zColumn, sqlite_int64 iRow, int flags, sqlite3_blob **ppBlob ); int sqlite3_blob_close(sqlite3_blob *); int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 | ** ** When the virtual-table mechanism stablizes, we will declare the ** interface fixed, support it indefinitely, and remove this comment. ** ****** EXPERIMENTAL - subject to change without notice ************** */ /* ** An instance of the following opaque structure is used to ** represent an open blob handle. */ typedef struct sqlite3_blob sqlite3_blob; /* ** Open a handle to the blob located in row iRow,, column zColumn, ** table zTable in database zDb. i.e. the same blob that would ** be selected by: ** ** "SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; ** ** If the flags parameter is non-zero, the blob is opened for ** read and write access. If it is zero, the blob is opened for read ** access. ** ** On success, SQLITE_OK is returned and the new blob-handle is ** written to *ppBlob. Otherwise an error code is returned and ** any value written to *ppBlob should not be used by the caller. ** This function sets the database-handle error code and message ** accessible via sqlite3_errcode() and sqlite3_errmsg(). */ int sqlite3_blob_open( sqlite3*, const char *zDb, const char *zTable, const char *zColumn, sqlite_int64 iRow, int flags, sqlite3_blob **ppBlob ); /* ** Close an open blob handle. */ int sqlite3_blob_close(sqlite3_blob *); /* ** Return the size in bytes of the blob accessible via the open ** blob-handle passed as an argument. */ int sqlite3_blob_bytes(sqlite3_blob *); /* ** This function is used to read data from an open blob-handle into ** a caller supplied buffer. n bytes of data are copied into buffer ** z from the open blob, starting at offset iOffset. ** ** On success, SQLITE_OK is returned. Otherwise, an SQLite error ** code. */ int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); /* ** This function is used to write data from an open blob-handle into ** a user supplied buffer. n bytes of data are copied from the buffer ** pointed to by z into the open blob, starting at offset iOffset. ** ** If the blob-handle passed as the first argument was not opened for ** writing (the flags parameter to sqlite3_blob_open was zero), this ** function returns SQLITE_READONLY. ** ** This function may only modify the contents of the blob, it is ** not possible to increase the size of a blob using this API. If ** offset iOffset is less than n bytes from the end of the blob, ** SQLITE_ERROR is returned and no data is written. ** ** On success, SQLITE_OK is returned. Otherwise, an SQLite error ** code. If an error occurs, this function sets the */ int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite. Append this file to sqlite3.c and ** compile the whole thing to build a TCL-enabled version of SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite. Append this file to sqlite3.c and ** compile the whole thing to build a TCL-enabled version of SQLite. ** ** $Id: tclsqlite.c,v 1.182 2007/05/03 16:31:26 danielk1977 Exp $ */ #include "tcl.h" #include <errno.h> /* ** Some additional include files are needed if this file is not ** appended to the amalgamation. |
︙ | ︙ | |||
295 296 297 298 299 300 301 | */ static int createIncrblobChannel( Tcl_Interp *interp, SqliteDb *pDb, const char *zDb, const char *zTable, const char *zColumn, | | > > | | | 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 | */ static int createIncrblobChannel( Tcl_Interp *interp, SqliteDb *pDb, const char *zDb, const char *zTable, const char *zColumn, sqlite_int64 iRow, int isReadonly ){ IncrblobChannel *p; sqlite3 *db = pDb->db; sqlite3_blob *pBlob; int rc; int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE); /* This variable is used to name the channels: "incrblob_[incr count]" */ static int count = 0; char zChannel[64]; rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); return TCL_ERROR; } p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel)); p->iSeek = 0; |
︙ | ︙ | |||
1845 1846 1847 1848 1849 1850 1851 | /* Must flush any cached statements */ flushStmtCache( pDb ); } break; } /* | | > > > > > | > | | | > > | 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 | /* Must flush any cached statements */ flushStmtCache( pDb ); } break; } /* ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID */ case DB_INCRBLOB: { int isReadonly = 0; const char *zDb = "main"; const char *zTable; const char *zColumn; sqlite_int64 iRow; /* Check for the -readonly option */ if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){ isReadonly = 1; } if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){ Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID"); return TCL_ERROR; } if( objc==(6+isReadonly) ){ zDb = Tcl_GetString(objv[2]); } zTable = Tcl_GetString(objv[objc-3]); zColumn = Tcl_GetString(objv[objc-2]); rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow); if( rc==TCL_OK ){ rc = createIncrblobChannel( interp, pDb, zDb, zTable, zColumn, iRow, isReadonly ); } break; } /* ** $db interrupt ** |
︙ | ︙ |
Changes to src/vdbeblob.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* ** 2007 May 1 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* ** 2007 May 1 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** $Id: vdbeblob.c,v 1.4 2007/05/03 16:31:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #ifndef SQLITE_OMIT_INCRBLOB |
︙ | ︙ | |||
39 40 41 42 43 44 45 | const char *zDb, const char *zTable, const char *zColumn, sqlite_int64 iRow, int flags, /* True -> read/write access, false -> read-only */ sqlite3_blob **ppBlob ){ | < | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | const char *zDb, const char *zTable, const char *zColumn, sqlite_int64 iRow, int flags, /* True -> read/write access, false -> read-only */ sqlite3_blob **ppBlob ){ int nAttempt = 0; int iCol; /* Index of zColumn in row-record */ /* This VDBE program seeks a btree cursor to the identified ** db/table/row entry. The reason for using a vdbe program instead ** of writing code to use the b-tree layer directly is that the ** vdbe program will take advantage of the various transaction, |
︙ | ︙ | |||
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | {OP_Column, 0, 0, 0}, /* 8 */ {OP_Callback, 0, 0, 0}, /* 9 */ {OP_Close, 0, 0, 0}, /* 10 */ {OP_Halt, 0, 0, 0}, /* 11 */ }; Vdbe *v = 0; do { Parse sParse; Table *pTab; memset(&sParse, 0, sizeof(Parse)); sParse.db = db; rc = sqlite3SafetyOn(db); if( rc!=SQLITE_OK ){ return rc; } pTab = sqlite3LocateTable(&sParse, zTable, zDb); if( !pTab ){ | > > | > > > | | < | 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 | {OP_Column, 0, 0, 0}, /* 8 */ {OP_Callback, 0, 0, 0}, /* 9 */ {OP_Close, 0, 0, 0}, /* 10 */ {OP_Halt, 0, 0, 0}, /* 11 */ }; Vdbe *v = 0; int rc = SQLITE_OK; char zErr[128] = {0}; do { Parse sParse; Table *pTab; memset(&sParse, 0, sizeof(Parse)); sParse.db = db; rc = sqlite3SafetyOn(db); if( rc!=SQLITE_OK ){ return rc; } pTab = sqlite3LocateTable(&sParse, zTable, zDb); if( !pTab ){ if( sParse.zErrMsg ){ sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg); zErr[sizeof(zErr)-1] = '\0'; } sqliteFree(sParse.zErrMsg); rc = SQLITE_ERROR; sqlite3SafetyOff(db); goto blob_open_out; } /* Now search pTab for the exact column. */ for(iCol=0; iCol < pTab->nCol; iCol++) { if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ break; } } if( iCol==pTab->nCol ){ sprintf(zErr, "no such column: \"%s\"", zColumn); rc = SQLITE_ERROR; sqlite3SafetyOff(db); goto blob_open_out; } v = sqlite3VdbeCreate(db); if( v ){ |
︙ | ︙ | |||
158 159 160 161 162 163 164 165 166 167 168 169 170 171 | } sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow); rc = sqlite3_step((sqlite3_stmt *)v); if( rc!=SQLITE_ROW ){ nAttempt++; rc = sqlite3_finalize((sqlite3_stmt *)v); v = 0; } } while( nAttempt<5 && rc==SQLITE_SCHEMA ); if( rc==SQLITE_ROW ){ /* The row-record has been opened successfully. Check that the ** column in question contains text or a blob. If it contains | > | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | } sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow); rc = sqlite3_step((sqlite3_stmt *)v); if( rc!=SQLITE_ROW ){ nAttempt++; rc = sqlite3_finalize((sqlite3_stmt *)v); sprintf(zErr, "no such rowid: %lld", iRow); v = 0; } } while( nAttempt<5 && rc==SQLITE_SCHEMA ); if( rc==SQLITE_ROW ){ /* The row-record has been opened successfully. Check that the ** column in question contains text or a blob. If it contains |
︙ | ︙ | |||
187 188 189 190 191 192 193 | pBlob->pCsr = v->apCsr[0]->pCursor; sqlite3BtreeCacheOverflow(pBlob->pCsr); pBlob->pStmt = (sqlite3_stmt *)v; pBlob->iOffset = v->apCsr[0]->aOffset[iCol]; pBlob->nByte = sqlite3VdbeSerialTypeLen(type); *ppBlob = (sqlite3_blob *)pBlob; rc = SQLITE_OK; | < | | < | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | pBlob->pCsr = v->apCsr[0]->pCursor; sqlite3BtreeCacheOverflow(pBlob->pCsr); pBlob->pStmt = (sqlite3_stmt *)v; pBlob->iOffset = v->apCsr[0]->aOffset[iCol]; pBlob->nByte = sqlite3VdbeSerialTypeLen(type); *ppBlob = (sqlite3_blob *)pBlob; rc = SQLITE_OK; }else if( rc==SQLITE_OK ){ rc = SQLITE_ERROR; } blob_open_out: if( rc!=SQLITE_OK || sqlite3MallocFailed() ){ sqlite3_finalize((sqlite3_stmt *)v); } sqlite3Error(db, rc, zErr); return sqlite3ApiExit(db, rc); } /* ** Close a blob handle. */ int sqlite3_blob_close(sqlite3_blob *pBlob){ |
︙ | ︙ |
Changes to test/incrblob.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2007 May 1 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 2007 May 1 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: incrblob.test,v 1.5 2007/05/03 16:31:26 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl do_test incrblob-1.1 { execsql { |
︙ | ︙ | |||
75 76 77 78 79 80 81 | } {....123456} do_test incrblob-1.3.10 { close $::blob } {} #------------------------------------------------------------------------ | > > | > | | < > > > > > | | | 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 | } {....123456} do_test incrblob-1.3.10 { close $::blob } {} #------------------------------------------------------------------------ # incrblob-2.*: # # Test that the following operations use ptrmap pages to reduce # unnecessary reads: # # * Reading near the end of a blob, # * Writing near the end of a blob, and # * SELECT a column value that is located on an overflow page. # proc nRead {db} { set bt [btree_from_db $db] array set stats [btree_pager_stats $bt] return $stats(read) } proc nWrite {db} { set bt [btree_from_db $db] array set stats [btree_pager_stats $bt] return $stats(write) } foreach AutoVacuumMode [list 0 1] { db close file delete -force test.db test.db-journal sqlite3 db test.db execsql "PRAGMA auto_vacuum = $AutoVacuumMode" do_test incrblob-2.$AutoVacuumMode.1 { set ::str [string repeat abcdefghij 2900] execsql { BEGIN; CREATE TABLE blobs(k PRIMARY KEY, v BLOB, i INTEGER); DELETE FROM blobs; INSERT INTO blobs VALUES('one', $::str || randstr(500,500), 45); COMMIT; } expr [file size test.db]/1024 } [expr 31 + $AutoVacuumMode] do_test incrblob-2.$AutoVacuumMode.2 { execsql { |
︙ | ︙ | |||
132 133 134 135 136 137 138 | # If the database is not in auto-vacuum mode, the whole of # the overflow-chain must be scanned. In auto-vacuum mode, # sqlite uses the ptrmap pages to avoid reading the other pages. # nRead db } [expr $AutoVacuumMode ? 4 : 30] | | | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | # If the database is not in auto-vacuum mode, the whole of # the overflow-chain must be scanned. In auto-vacuum mode, # sqlite uses the ptrmap pages to avoid reading the other pages. # nRead db } [expr $AutoVacuumMode ? 4 : 30] do_test incrblob-2.$AutoVacuumMode.4 { string range [db one {SELECT v FROM blobs}] end-19 end } $::fragment do_test incrblob-2.$AutoVacuumMode.5 { # Open and close the db to make sure the page cache is empty. db close sqlite3 db test.db # Write the second-to-last 20 bytes of the blob via a blob handle. # set ::blob [db incrblob blobs v 1] seek $::blob -40 end puts -nonewline $::blob "1234567890abcdefghij" flush $::blob # If the database is not in auto-vacuum mode, the whole of # the overflow-chain must be scanned. In auto-vacuum mode, # sqlite uses the ptrmap pages to avoid reading the other pages. # nRead db } [expr $AutoVacuumMode ? 4 : 30] # Pages 1 (the write-counter) and 32 (the blob data) were written. do_test incrblob-2.$AutoVacuumMode.6 { close $::blob nWrite db } 2 do_test incrblob-2.$AutoVacuumMode.7 { string range [db one {SELECT v FROM blobs}] end-39 end-20 } "1234567890abcdefghij" do_test incrblob-2.$AutoVacuumMode.8 { # Open and close the db to make sure the page cache is empty. db close sqlite3 db test.db execsql { SELECT i FROM blobs } } {45} do_test incrblob-2.$AutoVacuumMode.9 { nRead db } [expr $AutoVacuumMode ? 4 : 30] } #------------------------------------------------------------------------ # incrblob-3.*: # # Test the outcome of trying to write to a read-only blob handle. # # TODO: The following test only tests the tcl interface, not the # underlying sqlite3 interface. Need to find some other method # to call sqlite3_blob_write() on a readonly handle... # do_test incrblob-3.1 { set ::blob [db incrblob -readonly blobs v 1] seek $::blob -40 end read $::blob 20 } "1234567890abcdefghij" do_test incrblob-3.2 { seek $::blob 0 set rc [catch { puts -nonewline $::blob "helloworld" } msg] list $rc $msg } "1 {channel \"$::blob\" wasn't opened for writing}" #------------------------------------------------------------------------ # incrblob-4.*: # # Try a couple of error conditions: # # 4.1 - Attempt to open a row that does not exist. # 4.2 - Attempt to open a column that does not exist. # 4.3 - Attempt to open a table that does not exist. # 4.4 - Attempt to open a database that does not exist. # do_test incrblob-4.1 { set rc [catch { set ::blob [db incrblob blobs v 2] } msg ] list $rc $msg } {1 {no such rowid: 2}} do_test incrblob-4.2 { set rc [catch { set ::blob [db incrblob blobs blue 1] } msg ] list $rc $msg } {1 {no such column: "blue"}} do_test incrblob-4.3 { set rc [catch { set ::blob [db incrblob nosuchtable blue 1] } msg ] list $rc $msg } {1 {no such table: main.nosuchtable}} do_test incrblob-4.4 { set rc [catch { set ::blob [db incrblob nosuchdb blobs v 1] } msg ] list $rc $msg } {1 {no such table: nosuchdb.blobs}} finish_test |
Changes to test/tkt2332.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2007 May 3 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 2007 May 3 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: tkt2332.test,v 1.2 2007/05/03 16:31:26 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl do_test tkt2332.1 { execsql { |
︙ | ︙ | |||
52 53 54 55 56 57 58 59 | do_test tkt2332.$Len.5 { lindex [execsql {SELECT v FROM blobs WHERE k = $::iKey}] 0 } $::blobstr incr ::iKey } finish_test | > > > | 52 53 54 55 56 57 58 59 60 61 62 | do_test tkt2332.$Len.5 { lindex [execsql {SELECT v FROM blobs WHERE k = $::iKey}] 0 } $::blobstr incr ::iKey } # Free memory: unset ::blobstr finish_test |
Changes to test/types3.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus # of this file is testing the interaction of SQLite manifest types # with Tcl dual-representations. # | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus # of this file is testing the interaction of SQLite manifest types # with Tcl dual-representations. # # $Id: types3.test,v 1.6 2007/05/03 16:31:26 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # A variable with only a string representation comes in as TEXT do_test types3-1.1 { set V {} append V {} concat [tcl_variable_type V] [execsql {SELECT typeof(:V)}] } {string text} # A variable with an integer representation comes in as INTEGER do_test types3-1.2 { set V [expr {int(1+2)}] concat [tcl_variable_type V] [execsql {SELECT typeof(:V)}] } {int integer} do_test types3-1.3 { set V [expr {1+123456789012345}] concat [tcl_variable_type V] [execsql {SELECT typeof(:V)}] } {wideInt integer} |
︙ | ︙ |