Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Adding the sqlite3_stmt_readonly() interface. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
fd5b2f23dd5111d2f0934dd828bae36b |
User & Date: | drh 2010-11-16 23:10:26.000 |
Context
2010-11-17
| ||
02:02 | Restrict the scope of the sqlite3_stmt_readonly() interface to a specific subset of prepared statement types. (check-in: 919b06c3a8 user: drh tags: trunk) | |
2010-11-16
| ||
23:10 | Adding the sqlite3_stmt_readonly() interface. (check-in: fd5b2f23dd user: drh tags: trunk) | |
02:49 | Use the estimated number of rows computed for subqueries in the cost computations for outer queries. (check-in: 56bbc53924 user: drh tags: trunk) | |
Changes
Changes to src/sqlite.h.in.
︙ | ︙ | |||
2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 | ** ** ^This interface can be used to retrieve a saved copy of the original ** SQL text used to create a [prepared statement] if that statement was ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. */ const char *sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Dynamically Typed Value Object ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} ** ** SQLite uses the sqlite3_value object to represent all values ** that can be stored in a database table. SQLite uses dynamic typing ** for the values it stores. ^Values stored in sqlite3_value objects | > > > > > > > > > > > > > > > | 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 | ** ** ^This interface can be used to retrieve a saved copy of the original ** SQL text used to create a [prepared statement] if that statement was ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. */ const char *sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If An SQL Statement Writes The Database ** ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if ** the [prepared statement] X is guaranteed to leave the database file ** unmodified. ^If the sqlite3_stmt_readonly(X) interface returns false (zero) ** then evaluating the statement might change the database file, but this ** is not guaranteed as the write operation might be conditional and the ** condition might not be met. ^If X is a NULL pointer then ** sqlite3_stmt_readonly(X) returns true. If X is a non-NULL pointer but ** is not a pointer to a valid, unfinalized prepared statement, then the ** behavior is undefined and probably harmful. */ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); /* ** CAPI3REF: Dynamically Typed Value Object ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} ** ** SQLite uses the sqlite3_value object to represent all values ** that can be stored in a database table. SQLite uses dynamic typing ** for the values it stores. ^Values stored in sqlite3_value objects |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 | if( pStmt ){ if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; Tcl_AppendResult(interp, zBuf, 0); } return TCL_OK; } /* ** Usage: sqlite3_reset STMT ** ** Reset a statement handle. */ static int test_reset( | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 | if( pStmt ){ if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; Tcl_AppendResult(interp, zBuf, 0); } return TCL_OK; } /* ** Usage: sqlite3_stmt_readonly STMT ** ** Return true if STMT is a NULL pointer or a pointer to a statement ** that is guaranteed to leave the database unmodified. */ static int test_stmt_readonly( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_stmt *pStmt; int rc; if( objc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), " STMT", 0); return TCL_ERROR; } if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; rc = sqlite3_stmt_readonly(pStmt); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc)); return TCL_OK; } /* ** Usage: sqlite3_reset STMT ** ** Reset a statement handle. */ static int test_reset( |
︙ | ︙ | |||
5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 | { "sqlite3_reset", test_reset ,0 }, { "sqlite3_expired", test_expired ,0 }, { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, { "sqlite3_changes", test_changes ,0 }, { "sqlite3_step", test_step ,0 }, { "sqlite3_sql", test_sql ,0 }, { "sqlite3_next_stmt", test_next_stmt ,0 }, { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, { "sqlite3_pager_refcounts", test_pager_refcounts, 0}, { "sqlite3_load_extension", test_load_extension, 0}, | > | 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 | { "sqlite3_reset", test_reset ,0 }, { "sqlite3_expired", test_expired ,0 }, { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, { "sqlite3_changes", test_changes ,0 }, { "sqlite3_step", test_step ,0 }, { "sqlite3_sql", test_sql ,0 }, { "sqlite3_next_stmt", test_next_stmt ,0 }, { "sqlite3_stmt_readonly", test_stmt_readonly ,0 }, { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, { "sqlite3_pager_refcounts", test_pager_refcounts, 0}, { "sqlite3_load_extension", test_load_extension, 0}, |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 | ** in the argument belongs. This is the same database handle that was ** the first argument to the sqlite3_prepare() that was used to create ** the statement in the first place. */ sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->db : 0; } /* ** Return a pointer to the next prepared statement after pStmt associated ** with database connection pDb. If pStmt is NULL, return the first ** prepared statement for the database connection. Return NULL if there ** are no more. */ | > > > > > > > > | 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 | ** in the argument belongs. This is the same database handle that was ** the first argument to the sqlite3_prepare() that was used to create ** the statement in the first place. */ sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->db : 0; } /* ** Return true if the prepared statement is guaranteed to not modify the ** database. */ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; } /* ** Return a pointer to the next prepared statement after pStmt associated ** with database connection pDb. If pStmt is NULL, return the first ** prepared statement for the database connection. Return NULL if there ** are no more. */ |
︙ | ︙ |
Changes to test/capi3d.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2008 June 18 # # 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. # | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2008 June 18 # # 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. # # This file is devoted to testing the sqlite3_next_stmt and # sqlite3_stmt_readonly interfaces. # # $Id: capi3d.test,v 1.2 2008/07/14 15:11:20 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl |
︙ | ︙ | |||
84 85 86 87 88 89 90 | do_test capi3-1.2.$i.2 { foreach p [scramble $::stmtlist] { sqlite3_finalize $p } sqlite3_next_stmt db 0 } {} } | | > | > > > > > > > > > > > > > > > > > > > > > | 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 | do_test capi3-1.2.$i.2 { foreach p [scramble $::stmtlist] { sqlite3_finalize $p } sqlite3_next_stmt db 0 } {} } # Tests for the is-read-only interface. # proc test_is_readonly {testname sql truth} { do_test $testname [format { set DB [sqlite3_connection_pointer db] set STMT [sqlite3_prepare $DB {%s} -1 TAIL] set rc [sqlite3_stmt_readonly $STMT] sqlite3_finalize $STMT set rc } $sql] $truth } test_is_readonly capi3d-2.1 {SELECT * FROM sqlite_master} 1 test_is_readonly capi3d-2.2 {CREATE TABLE t1(x)} 0 db eval {CREATE TABLE t1(x)} test_is_readonly capi3d-2.3 {INSERT INTO t1 VALUES(5)} 0 test_is_readonly capi3d-2.4 {UPDATE t1 SET x=x+1 WHERE x<0} 0 test_is_readonly capi3d-2.5 {SELECT * FROM t1} 1 do_test capi3-2.99 { sqlite3_stmt_readonly 0 } 1 finish_test |