Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Get the non-callback API working with the EXPLAIN keyword and for PRAGMAs. Tickets #258 and #257. Update the API documentation on the sqlite_changes() routine to explain how it works with the non-callback API. Ticket #250. (CVS 875) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
620e1065e978545dd7bf6fa6fad1e6b9 |
User & Date: | drh 2003-03-01 19:45:34.000 |
Context
2003-03-01
| ||
19:53 | Add more tests to make sure that sqlite_changes() works when using the non-callback API. Ticket #250. (CVS 876) (check-in: 13e501d190 user: drh tags: trunk) | |
19:45 | Get the non-callback API working with the EXPLAIN keyword and for PRAGMAs. Tickets #258 and #257. Update the API documentation on the sqlite_changes() routine to explain how it works with the non-callback API. Ticket #250. (CVS 875) (check-in: 620e1065e9 user: drh tags: trunk) | |
2003-02-26
| ||
13:52 | Fix a memory leak associated with PRIMARY KEY in a CREATE TABLE statement that fails. Ticket #249. (CVS 874) (check-in: 8e9dc56799 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.131 2003/03/01 19:45:34 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 | ** identifier, or a number. If minusFlag is true, then the value is ** a number that was preceded by a minus sign. */ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ char *zLeft = 0; char *zRight = 0; sqlite *db = pParse->db; zLeft = sqliteStrNDup(pLeft->z, pLeft->n); sqliteDequote(zLeft); if( minusFlag ){ zRight = 0; sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0); }else{ | > > | 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 | ** identifier, or a number. If minusFlag is true, then the value is ** a number that was preceded by a minus sign. */ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ char *zLeft = 0; char *zRight = 0; sqlite *db = pParse->db; Vdbe *v = sqliteGetVdbe(pParse); if( v==0 ) return; zLeft = sqliteStrNDup(pLeft->z, pLeft->n); sqliteDequote(zLeft); if( minusFlag ){ zRight = 0; sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0); }else{ |
︙ | ︙ | |||
2233 2234 2235 2236 2237 2238 2239 | { OP_Dup, 0, 0, 0}, { OP_Integer, 0, 0, 0}, { OP_Ne, 0, 6, 0}, { OP_Integer, MAX_PAGES,0, 0}, { OP_ColumnName, 0, 0, "cache_size"}, { OP_Callback, 1, 0, 0}, }; | < < | 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 | { OP_Dup, 0, 0, 0}, { OP_Integer, 0, 0, 0}, { OP_Ne, 0, 6, 0}, { OP_Integer, MAX_PAGES,0, 0}, { OP_ColumnName, 0, 0, "cache_size"}, { OP_Callback, 1, 0, 0}, }; if( pRight->z==pLeft->z ){ sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); }else{ int addr; int size = atoi(zRight); if( size<0 ) size = -size; sqliteBeginWriteOperation(pParse, 0, 0); |
︙ | ︙ | |||
2273 2274 2275 2276 2277 2278 2279 | ** N should be a positive integer. */ if( sqliteStrICmp(zLeft,"cache_size")==0 ){ static VdbeOp getCacheSize[] = { { OP_ColumnName, 0, 0, "cache_size"}, { OP_Callback, 1, 0, 0}, }; | < < | 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 | ** N should be a positive integer. */ if( sqliteStrICmp(zLeft,"cache_size")==0 ){ static VdbeOp getCacheSize[] = { { OP_ColumnName, 0, 0, "cache_size"}, { OP_Callback, 1, 0, 0}, }; if( pRight->z==pLeft->z ){ int size = db->cache_size;; if( size<0 ) size = -size; sqliteVdbeAddOp(v, OP_Integer, size, 0); sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); }else{ int size = atoi(zRight); |
︙ | ︙ | |||
2323 2324 2325 2326 2327 2328 2329 | { OP_Lt, 0, 5, 0}, { OP_AddImm, 1, 0, 0}, { OP_Callback, 1, 0, 0}, { OP_Halt, 0, 0, 0}, { OP_AddImm, -1, 0, 0}, /* 10 */ { OP_Callback, 1, 0, 0} }; | < < | 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 | { OP_Lt, 0, 5, 0}, { OP_AddImm, 1, 0, 0}, { OP_Callback, 1, 0, 0}, { OP_Halt, 0, 0, 0}, { OP_AddImm, -1, 0, 0}, /* 10 */ { OP_Callback, 1, 0, 0} }; if( pRight->z==pLeft->z ){ int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync); sqliteVdbeChangeP2(v, addr+3, addr+10); }else{ int addr; int size = db->cache_size; if( size<0 ) size = -size; |
︙ | ︙ | |||
2368 2369 2370 2371 2372 2373 2374 | ** opened. */ if( sqliteStrICmp(zLeft,"synchronous")==0 ){ static VdbeOp getSync[] = { { OP_ColumnName, 0, 0, "synchronous"}, { OP_Callback, 1, 0, 0}, }; | < < | 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 | ** opened. */ if( sqliteStrICmp(zLeft,"synchronous")==0 ){ static VdbeOp getSync[] = { { OP_ColumnName, 0, 0, "synchronous"}, { OP_Callback, 1, 0, 0}, }; if( pRight->z==pLeft->z ){ sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0); sqliteVdbeAddOpList(v, ArraySize(getSync), getSync); }else{ int size = db->cache_size; if( size<0 ) size = -size; db->safety_level = getSafetyLevel(zRight)+1; |
︙ | ︙ | |||
2442 2443 2444 2445 2446 2447 2448 | }else{ db->flags &= ~SQLITE_NullCallback; } }else if( sqliteStrICmp(zLeft, "table_info")==0 ){ Table *pTab; | < < | | 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 | }else{ db->flags &= ~SQLITE_NullCallback; } }else if( sqliteStrICmp(zLeft, "table_info")==0 ){ Table *pTab; pTab = sqliteFindTable(db, zRight); if( pTab ){ static VdbeOp tableInfoPreface[] = { { OP_ColumnName, 0, 0, "cid"}, { OP_ColumnName, 1, 0, "name"}, { OP_ColumnName, 2, 0, "type"}, { OP_ColumnName, 3, 0, "notnull"}, { OP_ColumnName, 4, 0, "dflt_value"}, }; |
︙ | ︙ | |||
2474 2475 2476 2477 2478 2479 2480 | } } }else if( sqliteStrICmp(zLeft, "index_info")==0 ){ Index *pIdx; Table *pTab; | < < | | 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 | } } }else if( sqliteStrICmp(zLeft, "index_info")==0 ){ Index *pIdx; Table *pTab; pIdx = sqliteFindIndex(db, zRight); if( pIdx ){ static VdbeOp tableInfoPreface[] = { { OP_ColumnName, 0, 0, "seqno"}, { OP_ColumnName, 1, 0, "cid"}, { OP_ColumnName, 2, 0, "name"}, }; int i; pTab = pIdx->pTable; |
︙ | ︙ | |||
2501 2502 2503 2504 2505 2506 2507 | } } }else if( sqliteStrICmp(zLeft, "index_list")==0 ){ Index *pIdx; Table *pTab; | < | | 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 | } } }else if( sqliteStrICmp(zLeft, "index_list")==0 ){ Index *pIdx; Table *pTab; pTab = sqliteFindTable(db, zRight); if( pTab ){ v = sqliteGetVdbe(pParse); pIdx = pTab->pIndex; } if( pTab && pIdx ){ int i = 0; static VdbeOp indexListPreface[] = { { OP_ColumnName, 0, 0, "seq"}, { OP_ColumnName, 1, 0, "name"}, { OP_ColumnName, 2, 0, "unique"}, }; |
︙ | ︙ | |||
2559 2560 2561 2562 2563 2564 2565 | { OP_Rewind, 1, 15, 0}, { OP_Column, 1, 3, 0}, /* 12 */ { OP_SetInsert, 1, 0, 0}, { OP_Next, 1, 12, 0}, { OP_IntegrityCk, 1, 1, 0}, /* 15 */ { OP_Callback, 1, 0, 0}, }; | < < | 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 | { OP_Rewind, 1, 15, 0}, { OP_Column, 1, 3, 0}, /* 12 */ { OP_SetInsert, 1, 0, 0}, { OP_Next, 1, 12, 0}, { OP_IntegrityCk, 1, 1, 0}, /* 15 */ { OP_Callback, 1, 0, 0}, }; sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb); }else {} sqliteFree(zLeft); sqliteFree(zRight); } |
Changes to src/vdbe.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.206 2003/03/01 19:45:34 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The makefile scans this source file and creates the following ** array of string constants which are the names of all VDBE opcodes. |
︙ | ︙ | |||
1296 1297 1298 1299 1300 1301 1302 | if( p->xCallback(p->pCbArg, 5, p->zStack, p->azColName) ){ p->rc = SQLITE_ABORT; } if( sqliteSafetyOn(db) ){ p->rc = SQLITE_MISUSE; } } | | | 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 | if( p->xCallback(p->pCbArg, 5, p->zStack, p->azColName) ){ p->rc = SQLITE_ABORT; } if( sqliteSafetyOn(db) ){ p->rc = SQLITE_MISUSE; } } return p->rc==SQLITE_OK ? SQLITE_DONE : SQLITE_ERROR; } /* ** The parameters are pointers to the head of two sorted lists ** of Sorter structures. Merge these two lists together and return ** a single sorted list. This routine forms the core of the merge-sort ** algorithm. |
︙ | ︙ |
Changes to test/capi2.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2003 January 29 # # 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2003 January 29 # # 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # # $Id: capi2.test,v 1.5 2003/03/01 19:45:35 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Check basic functionality # |
︙ | ︙ | |||
385 386 387 388 389 390 391 392 393 394 395 | } {1 {uniqueness constraint failed}} do_test capi2-6.28 { list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_ROW 1 13 {x counter}} do_test capi2-6.99 { list [catch {sqlite_finalize $VM1} msg] [set msg] } {0 {}} db2 close finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | } {1 {uniqueness constraint failed}} do_test capi2-6.28 { list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_ROW 1 13 {x counter}} do_test capi2-6.99 { list [catch {sqlite_finalize $VM1} msg] [set msg] } {0 {}} execsql {ROLLBACK} do_test capi2-7.1 { stepsql $DB { SELECT * FROM t1 } } {0 1 2 3} do_test capi2-7.2 { stepsql $DB { PRAGMA count_changes=on } } {0} do_test capi2-7.3 { stepsql $DB { UPDATE t1 SET a=a+10; } } {0 1} do_test capi2-7.4 { stepsql $DB { INSERT INTO t1 SELECT a+1,b+1,c+1 FROM t1; } } {0 1} do_test capi2-7.5 { stepsql $DB { UPDATE t1 SET a=a+10; } } {0 2} do_test capi2-7.6 { stepsql $DB { SELECT * FROM t1; } } {0 21 2 3 22 3 4} do_test capi2-7.7 { stepsql $DB { INSERT INTO t1 SELECT a+2,b+2,c+2 FROM t1; } } {0 2} do_test capi2-7.8 { stepsql $DB { SELECT * FROM t1; } } {0 21 2 3 22 3 4 23 4 5 24 5 6} do_test capi2-7.9 { stepsql $DB { UPDATE t1 SET a=a-20; SELECT * FROM t1; } } {0 4 1 2 3 2 3 4 3 4 5 4 5 6} do_test capi2-7.10 { set x [stepsql $DB {EXPLAIN SELECT * FROM t1}] lindex $x 0 } {0} db2 close finish_test |
Changes to test/tester.tcl.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # 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. # #*********************************************************************** # This file implements some common TCL routines used for regression # testing the SQLite library # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # 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. # #*********************************************************************** # This file implements some common TCL routines used for regression # testing the SQLite library # # $Id: tester.tcl,v 1.25 2003/03/01 19:45:35 drh Exp $ # Make sure tclsqlite was compiled correctly. Abort now with an # error message if not. # if {[sqlite -tcl-uses-utf]} { if {"\u1234"=="u1234"} { puts stderr "***** BUILD PROBLEM *****" |
︙ | ︙ | |||
209 210 211 212 213 214 215 216 217 218 219 220 221 222 | db eval $sql data { foreach f $data(*) { lappend result $f $data($f) } } return $result } # Delete a file or directory # proc forcedelete {filename} { if {[catch {file delete -force $filename}]} { exec rm -rf $filename } | > > > > > > > > > > > > > > > > > > > > | 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 | db eval $sql data { foreach f $data(*) { lappend result $f $data($f) } } return $result } # Use the non-callback API to execute multiple SQL statements # proc stepsql {dbptr sql} { set sql [string trim $sql] set r 0 while {[string length $sql]>0} { if {[catch {sqlite_compile $dbptr $sql sqltail} vm]} { return [list 1 $vm] } set sql [string trim $sqltail] while {[sqlite_step $vm N VAL COL]=="SQLITE_ROW"} { foreach v $VAL {lappend r $v} } if {[catch {sqlite_finalize $vm} errmsg]} { return [list 1 $errmsg] } } return $r } # Delete a file or directory # proc forcedelete {filename} { if {[catch {file delete -force $filename}]} { exec rm -rf $filename } |
︙ | ︙ |
Changes to www/c_interface.tcl.
1 2 3 | # # Run this Tcl script to generate the sqlite.html file. # | | | 1 2 3 4 5 6 7 8 9 10 11 | # # Run this Tcl script to generate the sqlite.html file. # set rcsid {$Id: c_interface.tcl,v 1.37 2003/03/01 19:45:35 drh Exp $} puts {<html> <head> <title>The C language interface to the SQLite library</title> </head> <body bgcolor=white> <h1 align=center> |
︙ | ︙ | |||
656 657 658 659 660 661 662 | for the most recent INSERT statement using the <b>sqlite_last_insert_rowid</b> API function.</p> <h3>3.2 The number of rows that changed</h3> <p>The <b>sqlite_changes</b> API function returns the number of rows that were inserted, deleted, or modified during the most recent | > | | 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | for the most recent INSERT statement using the <b>sqlite_last_insert_rowid</b> API function.</p> <h3>3.2 The number of rows that changed</h3> <p>The <b>sqlite_changes</b> API function returns the number of rows that were inserted, deleted, or modified during the most recent <b>sqlite_exec</b> call of by <b>sqlite_step</b> calls since the most recent <b>sqlite_compile</b>. The number reported includes any changes that were later undone by a ROLLBACK or ABORT. But rows that are deleted because of a DROP TABLE are <em>not</em> counted.</p> <p>SQLite implements the command "<b>DELETE FROM table</b>" (without a WHERE clause) by dropping the table then recreating it. This is much faster than deleting the elements of the table individually. But it also means that the value returned from <b>sqlite_changes</b> |
︙ | ︙ |