Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch column-text-blob-v2 Excluding Merge-Ins
This is equivalent to a diff from 960a8e6fc9 to f73460d4f0
2025-07-04
| ||
11:48 | Remove an ALWAYS() added by [960a8e6fc91f4] that turns out to be false in some cases of malformed SQL. (check-in: cc8171461b user: drh tags: trunk) | |
10:17 | Merge trunk into column-text-blob-v2 branch. (Leaf check-in: f73460d4f0 user: stephan tags: column-text-blob-v2) | |
10:10 | Tweak for coverage testing of valueToTextV2(). This changes passes through coverage testing but doesn't look quite right to me, in that this part now differs from its counterpart in valueToText() (which doesn't need this to get coverage for what amounts to the same path). (check-in: dae572912f user: stephan tags: column-text-blob-v2) | |
2025-07-03
| ||
20:51 | Merge the latest trunk fixes and enhancements into the empty-table-optimizations branch (check-in: d4f47e04f5 user: drh tags: empty-table-optimizations) | |
16:05 | Fix a few cases where LIMIT clauses that were part of scalar sub-queries on virtual tables were not being passed to xBestIndex methods correctly. (check-in: 960a8e6fc9 user: dan tags: trunk) | |
15:50 | Improvements to sqlite3_vtab_rhs_value() logging in the ext/misc/vtablog.c extension. (Closed-Leaf check-in: 25131ee84f user: drh tags: vtab-limit-fixes) | |
14:10 | Enhancements to the xBestIndex output from the ext/misc/vtablog.c extension. (check-in: 8b31acc0b1 user: drh tags: trunk) | |
Changes to ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras.
︙ | ︙ | |||
60 61 62 63 64 65 66 | _sqlite3session_indirect _sqlite3session_isempty _sqlite3session_memory_used _sqlite3session_object_config _sqlite3session_patchset _sqlite3session_patchset_strm _sqlite3session_table_filter | > > > > | 60 61 62 63 64 65 66 67 68 69 70 | _sqlite3session_indirect _sqlite3session_isempty _sqlite3session_memory_used _sqlite3session_object_config _sqlite3session_patchset _sqlite3session_patchset_strm _sqlite3session_table_filter _sqlite3_value_blob_v2 _sqlite3_value_text_v2 _sqlite3_column_blob_v2 _sqlite3_column_text_v2 |
Changes to ext/wasm/api/sqlite3-api-glue.c-pp.js.
︙ | ︙ | |||
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | /* sqlite3_cancel_auto_extension() has a hand-written binding. */ /* sqlite3_close_v2() is implemented by hand to perform some extra work. */ ["sqlite3_changes", "int", "sqlite3*"], ["sqlite3_clear_bindings","int", "sqlite3_stmt*"], ["sqlite3_collation_needed", "int", "sqlite3*", "*", "*"/*=>v(ppis)*/], ["sqlite3_column_blob","*", "sqlite3_stmt*", "int"], ["sqlite3_column_bytes","int", "sqlite3_stmt*", "int"], ["sqlite3_column_count", "int", "sqlite3_stmt*"], ["sqlite3_column_decltype", "string", "sqlite3_stmt*", "int"], ["sqlite3_column_double","f64", "sqlite3_stmt*", "int"], ["sqlite3_column_int","int", "sqlite3_stmt*", "int"], ["sqlite3_column_name","string", "sqlite3_stmt*", "int"], ["sqlite3_column_text","string", "sqlite3_stmt*", "int"], ["sqlite3_column_type","int", "sqlite3_stmt*", "int"], ["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"], ["sqlite3_commit_hook", "void*", [ "sqlite3*", new wasm.xWrap.FuncPtrAdapter({ name: 'sqlite3_commit_hook', signature: 'i(p)', | > > | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | /* sqlite3_cancel_auto_extension() has a hand-written binding. */ /* sqlite3_close_v2() is implemented by hand to perform some extra work. */ ["sqlite3_changes", "int", "sqlite3*"], ["sqlite3_clear_bindings","int", "sqlite3_stmt*"], ["sqlite3_collation_needed", "int", "sqlite3*", "*", "*"/*=>v(ppis)*/], ["sqlite3_column_blob","*", "sqlite3_stmt*", "int"], ["sqlite3_column_blob_v2", "int", "sqlite3_stmt*", "int", "**", "*"], ["sqlite3_column_bytes","int", "sqlite3_stmt*", "int"], ["sqlite3_column_count", "int", "sqlite3_stmt*"], ["sqlite3_column_decltype", "string", "sqlite3_stmt*", "int"], ["sqlite3_column_double","f64", "sqlite3_stmt*", "int"], ["sqlite3_column_int","int", "sqlite3_stmt*", "int"], ["sqlite3_column_name","string", "sqlite3_stmt*", "int"], ["sqlite3_column_text","string", "sqlite3_stmt*", "int"], ["sqlite3_column_text_v2", "int", "sqlite3_stmt*", "int", "**", "*"], ["sqlite3_column_type","int", "sqlite3_stmt*", "int"], ["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"], ["sqlite3_commit_hook", "void*", [ "sqlite3*", new wasm.xWrap.FuncPtrAdapter({ name: 'sqlite3_commit_hook', signature: 'i(p)', |
︙ | ︙ | |||
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 | their first C-string arguments, so we cannot perform any value conversion on those. */ ["sqlite3_uri_boolean", "int", "sqlite3_filename", "string", "int"], ["sqlite3_uri_key", "string", "sqlite3_filename", "int"], ["sqlite3_uri_parameter", "string", "sqlite3_filename", "string"], ["sqlite3_user_data","void*", "sqlite3_context*"], ["sqlite3_value_blob", "*", "sqlite3_value*"], ["sqlite3_value_bytes","int", "sqlite3_value*"], ["sqlite3_value_double","f64", "sqlite3_value*"], ["sqlite3_value_dup", "sqlite3_value*", "sqlite3_value*"], ["sqlite3_value_free", undefined, "sqlite3_value*"], ["sqlite3_value_frombind", "int", "sqlite3_value*"], ["sqlite3_value_int","int", "sqlite3_value*"], ["sqlite3_value_nochange", "int", "sqlite3_value*"], ["sqlite3_value_numeric_type", "int", "sqlite3_value*"], ["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"], ["sqlite3_value_subtype", "int", "sqlite3_value*"], ["sqlite3_value_text", "string", "sqlite3_value*"], ["sqlite3_value_type", "int", "sqlite3_value*"], ["sqlite3_vfs_find", "*", "string"], ["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"], ["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"] ]/*wasm.bindingSignatures*/; if( !!wasm.exports.sqlite3_progress_handler ){ | > > | 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 | their first C-string arguments, so we cannot perform any value conversion on those. */ ["sqlite3_uri_boolean", "int", "sqlite3_filename", "string", "int"], ["sqlite3_uri_key", "string", "sqlite3_filename", "int"], ["sqlite3_uri_parameter", "string", "sqlite3_filename", "string"], ["sqlite3_user_data","void*", "sqlite3_context*"], ["sqlite3_value_blob", "*", "sqlite3_value*"], ["sqlite3_value_blob_v2", "int", "sqlite3_value*", "**", "*"], ["sqlite3_value_bytes","int", "sqlite3_value*"], ["sqlite3_value_double","f64", "sqlite3_value*"], ["sqlite3_value_dup", "sqlite3_value*", "sqlite3_value*"], ["sqlite3_value_free", undefined, "sqlite3_value*"], ["sqlite3_value_frombind", "int", "sqlite3_value*"], ["sqlite3_value_int","int", "sqlite3_value*"], ["sqlite3_value_nochange", "int", "sqlite3_value*"], ["sqlite3_value_numeric_type", "int", "sqlite3_value*"], ["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"], ["sqlite3_value_subtype", "int", "sqlite3_value*"], ["sqlite3_value_text", "string", "sqlite3_value*"], ["sqlite3_value_text_v2", "int", "sqlite3_value*", "**", "*"], ["sqlite3_value_type", "int", "sqlite3_value*"], ["sqlite3_vfs_find", "*", "string"], ["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"], ["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"] ]/*wasm.bindingSignatures*/; if( !!wasm.exports.sqlite3_progress_handler ){ |
︙ | ︙ |
Changes to ext/wasm/common/whwasmutil.js.
1 2 3 4 5 6 7 8 9 10 11 12 | /** 2022-07-08 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 | /** 2022-07-08 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. *********************************************************************** whwasmutil.js is developed in conjunction with the Jaccwabyt project: https://fossil.wanderinghorse.net/r/jaccwabyt and sqlite3: https://sqlite.org |
︙ | ︙ | |||
36 37 38 39 40 41 42 | can be used in arbitrary WASM environments built with toolchains other than Emscripten. As of this writing, this code is capable of acting as a replacement for Emscripten's generated glue code _except_ that the latter installs handlers for Emscripten-provided APIs such as its "FS" (virtual filesystem) API. Loading of such things still requires using Emscripten's glue, but the post-load utility APIs provided by this code are still usable as replacements | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | can be used in arbitrary WASM environments built with toolchains other than Emscripten. As of this writing, this code is capable of acting as a replacement for Emscripten's generated glue code _except_ that the latter installs handlers for Emscripten-provided APIs such as its "FS" (virtual filesystem) API. Loading of such things still requires using Emscripten's glue, but the post-load utility APIs provided by this code are still usable as replacements (not necessarily drop-in) for their Emscripten counterparts. Intended usage: ``` globalThis.WhWasmUtilInstaller(appObject); delete globalThis.WhWasmUtilInstaller; ``` |
︙ | ︙ | |||
115 116 117 118 119 120 121 | `Module['asm']` (versions <=3.1.43) or `wasmExports` (versions >=3.1.44). The exports object must contain a minimum of the following symbols: - `memory`: a WebAssembly.Memory object representing the WASM memory. _Alternately_, the `memory` property can be set as `target.memory`, in particular if the WASM heap memory is | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | `Module['asm']` (versions <=3.1.43) or `wasmExports` (versions >=3.1.44). The exports object must contain a minimum of the following symbols: - `memory`: a WebAssembly.Memory object representing the WASM memory. _Alternately_, the `memory` property can be set as `target.memory`, in particular if the WASM heap memory is initialized in JS and _imported_ into WASM, as opposed to being initialized in WASM and exported to JS. - `__indirect_function_table`: the WebAssembly.Table object which holds WASM-exported functions. This API does not strictly require that the table be able to grow but it will throw if its `installFunction()` is called and the table cannot grow. |
︙ | ︙ | |||
316 317 318 319 320 321 322 | - A integer-type TypedArray constructor: Int8Array, Int16Array, Int32Array, or their Uint counterparts. If this.bigIntEnabled is true, it also accepts the value 64 or a BigInt64Array/BigUint64Array, else it throws if passed 64 or one of those constructors. | | | | | | | | < | | 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 | - A integer-type TypedArray constructor: Int8Array, Int16Array, Int32Array, or their Uint counterparts. If this.bigIntEnabled is true, it also accepts the value 64 or a BigInt64Array/BigUint64Array, else it throws if passed 64 or one of those constructors. Returns an integer-based TypedArray view of the WASM heap memory buffer associated with the given block size. If passed an integer as the first argument and unsigned is truthy then the "U" (unsigned) variant of that view is returned, else the signed variant is returned. If passed a TypedArray value, the 2nd argument is ignored. Float32Array and Float64Array views are not supported by this function. Note that growth of the heap will invalidate any references to this heap, so do not hold a reference longer than needed and do not use a reference after any operation which may allocate. Instead, re-fetch the reference by calling this function again. Throws if passed an invalid n. Pedantic side note: the name "heap" is a bit of a misnomer. In a WASM environment, the stack and heap memory are all accessed via the same view(s) of the memory. */ target.heapForSize = function(n,unsigned = true){ let ctor; const c = heapWrappers(); switch(n){ case Int8Array: return c.HEAP8; case Uint8Array: return c.HEAP8U; case Int16Array: return c.HEAP16; case Uint16Array: return c.HEAP16U; case Int32Array: return c.HEAP32; case Uint32Array: return c.HEAP32U; case 8: return unsigned ? c.HEAP8U : c.HEAP8; case 16: return unsigned ? c.HEAP16U : c.HEAP16; case 32: return unsigned ? c.HEAP32U : c.HEAP32; |
︙ | ︙ | |||
403 404 405 406 407 408 409 | result type and letters in the parens (if any) represent the argument types. Functions with no arguments use `x()`. See below. Supported letters: - `i` = int32 | | | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | result type and letters in the parens (if any) represent the argument types. Functions with no arguments use `x()`. See below. Supported letters: - `i` = int32 - `p` = int32 ("pointer") unless configured for 64-bit pointers - `j` = int64 - `f` = float32 - `d` = float64 - `v` = void, only legal for use as the result type It throws if an invalid signature letter is used. |
︙ | ︙ | |||
431 432 433 434 435 436 437 | /** Attribution: adapted up from Emscripten-generated glue code, refactored primarily for efficiency's sake, eliminating call-local functions and superfluous temporary arrays. */ if(!f._){/*static init...*/ f._ = { // Map of signature letters to type IR values sigTypes: Object.assign(Object.create(null),{ | | | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | /** Attribution: adapted up from Emscripten-generated glue code, refactored primarily for efficiency's sake, eliminating call-local functions and superfluous temporary arrays. */ if(!f._){/*static init...*/ f._ = { // Map of signature letters to type IR values sigTypes: Object.assign(Object.create(null),{ i: 'i32', p: ptrIR, P: ptrIR, s: ptrIR, j: 'i64', f: 'f32', d: 'f64' }), // Map of type IR values to WASM type code values typeCodes: Object.assign(Object.create(null),{ f64: 0x7c, f32: 0x7d, i64: 0x7e, i32: 0x7f }), /** Encodes n, which must be <2^14 (16384), into target array |
︙ | ︙ | |||
745 746 747 748 749 750 751 | ACHTUNG: calling this often, e.g. in a loop to populate a large chunk of memory, can have a noticably painful impact on performance. Rather than doing so, use heapForSize() to fetch the heap object and assign directly to it or use the heap's set() method. */ target.poke = function(ptr, value, type='i8'){ | | | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | ACHTUNG: calling this often, e.g. in a loop to populate a large chunk of memory, can have a noticably painful impact on performance. Rather than doing so, use heapForSize() to fetch the heap object and assign directly to it or use the heap's set() method. */ target.poke = function(ptr, value, type='i8'){ if(type.endsWith('*')) type = ptrIR; const c = (cache.memory && cache.heapSize === cache.memory.buffer.byteLength) ? cache : heapWrappers(); for(const p of (Array.isArray(ptr) ? ptr : [ptr])){ switch (type) { case 'i1': case 'i8': c.HEAP8[p>>0] = value; continue; case 'i16': c.HEAP16[p>>1] = value; continue; |
︙ | ︙ |
Changes to ext/wasm/tester1.c-pp.js.
︙ | ︙ | |||
3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 | .assert( "$a"===capi.sqlite3_bind_parameter_name(stmt, 1) ) .assert( null===capi.sqlite3_bind_parameter_name(stmt, 0) ) .assert( "$a"===stmt.getParamName(1) ) .assert( null===stmt.getParamName(0) ); stmt.finalize(); db.close(); }) /** Ensure that certain Stmt members throw when called via DB.exec(). */ .t('locked-by-exec() APIs', function(sqlite3){ const db = new sqlite3.oo1.DB(); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 | .assert( "$a"===capi.sqlite3_bind_parameter_name(stmt, 1) ) .assert( null===capi.sqlite3_bind_parameter_name(stmt, 0) ) .assert( "$a"===stmt.getParamName(1) ) .assert( null===stmt.getParamName(0) ); stmt.finalize(); db.close(); }) //////////////////////////////////////////////////////////////////// .t("value_text_v2() and friends...", function(sqlite3){ const db = new sqlite3.oo1.DB(); db.exec(["create table t(a,b); insert into t(a,b) ", "values(1,123),(2,null),(3,'hi world'),(4,X'232A'),(5,'')"]); const P = wasm.pstack; const stack = P.pointer; let q; try { let sv, rc; q = db.prepare("select a, b from t order by a"); let [ppOut, pnOut] = P.allocPtr(2); const clearPtrs = ()=>{ wasm.pokePtr(ppOut, 0).poke32(pnOut, 0); }; const next = ()=>{ T.assert( q.step() ); sv = capi.sqlite3_column_value(q, 1); T.assert( sv ); clearPtrs(); rc = capi.sqlite3_value_text_v2(sv, ppOut, pnOut); T.assert( 0===rc ); return sv; }; const cmp = function(expect){ const blob = wasm.peekPtr(ppOut); const len = wasm.peek32(pnOut); //log("blob=",wasm.cstrToJs(blob)); const str = wasm.cstrToJs(blob); if( !blob ){ T.assert( null===expect ) .assert( 0===len ); return; } T.assert(len === expect.length, "Lengths don't match: got ["+str +"] expected ["+expect+"]") .assert( str===expect, "String mismatch: got [" +str+"] expected ["+expect+"]"); }; const cmp2 = (expect)=>{ next(); cmp(expect); clearPtrs(); const rc = capi.sqlite3_column_text_v2(q, 1, ppOut, pnOut); T.assert( 0==rc, "expecting column_text_v2() rc 0 but got "+rc ); cmp(expect); }; cmp2('123'); cmp2(null); cmp2('hi world'); cmp2('#*'); cmp2(''); // empty strings are not null const checkRc = (name, descr, rc)=>{ T.assert( capi[name] === rc, descr+": expecting "+name+"("+ capi[name]+") but got "+rc); }; /** The following tests cover the same code paths for both text_v2 and blob_v2, so are elided from the blob_v2 checks in the next test group. */ // This does not set a persistent error flag on q: checkRc('SQLITE_RANGE', "column_text_v2() bad index", capi.sqlite3_column_text_v2(q, 11, ppOut, pnOut) ); checkRc('SQLITE_OK', "column_text_v2() valid index", capi.sqlite3_column_text_v2(q, 1, ppOut, 0)); checkRc('SQLITE_OK', "column null pnOut", capi.sqlite3_column_text_v2(q, 1, ppOut, 0)); /* The MISUSE returns only apply because we build with SQLITE_ENABLE_API_ARMOR. Without API_ARMOR, these result in null pointer dereferences. */ checkRc('SQLITE_MISUSE', "value null ppOut", capi.sqlite3_value_text_v2(sv, 0, pnOut)); checkRc('SQLITE_MISUSE', "value null arg0", capi.sqlite3_value_text_v2(0, ppOut, pnOut)); checkRc('SQLITE_MISUSE', "column null ppOut", capi.sqlite3_column_text_v2(q, 1, 0, pnOut)); }finally{ if( q ) q.finalize(); db.close(); P.restore(stack); } }) //////////////////////////////////////////////////////////////////// .t("value_blob_v2() and friends...", function(sqlite3){ const db = new sqlite3.oo1.DB(); db.exec(["create table t(a,b); insert into t(a,b) ", "values(1,123),(2,null),(3,'hi'),(4,X'23002A'),(5,'')"]); const P = wasm.pstack; const stack = P.pointer; let q; try { let sv, rc; q = db.prepare("select a, b from t order by a"); let [ppOut, pnOut] = P.allocPtr(2); const clearPtrs = ()=>{ wasm.pokePtr(ppOut, 0).poke32(pnOut, 0); }; const next = ()=>{ ++next.n; T.assert( q.step() ); sv = capi.sqlite3_column_value(q, 1); T.assert( sv ); clearPtrs(); T.assert( !wasm.peekPtr(ppOut) ); rc = capi.sqlite3_value_blob_v2(sv, ppOut, pnOut); T.assert( 0==rc, "expecting value_blob_v2() rc 0 but got "+rc ); return sv; }; next.n = 0; const cmp = (byteList)=>{ const blob = wasm.peekPtr(ppOut); const len = wasm.peek32(pnOut); T.assert(len === byteList.length, "Lengths don't match: " +len +" != " + byteList.length) for( let i = 0; i < len; ++i ){ T.assert( byteList[i] === wasm.peek8(blob+i), "mismatch at offset "+i+": "+byteList[i] +"!=="+wasm.peek8(blob+i) ); } }; const cmp2 = (byteList)=>{ next(); cmp(byteList); clearPtrs(); const rc = capi.sqlite3_column_blob_v2(q, 1, ppOut, pnOut); T.assert( 0==rc, "expecting column_blob_v2() rc 0 but got "+rc); cmp(byteList); }; cmp2([49,50,51]); // 123 cmp2([]); // null T.assert( !wasm.peekPtr(ppOut), "Expecting NULL in row "+next.n); cmp2([104,105]); // "hi" cmp2([0x23, 0, 0x2a]); // X'23002A' cmp2([]) /* length-0 blob */; T.assert( wasm.peekPtr(ppOut), "Expecting non-NULL in row "+next.n); /** Tests which cover the same code paths for both text_v2 and blob_v2 are in the previous test group. */ }finally{ if( q ) q.finalize(); db.close(); P.restore(stack); } }) /** Ensure that certain Stmt members throw when called via DB.exec(). */ .t('locked-by-exec() APIs', function(sqlite3){ const db = new sqlite3.oo1.DB(); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 | ** CAPI3REF: Result Values From A Query ** KEYWORDS: {column access functions} ** METHOD: sqlite3_stmt ** ** <b>Summary:</b> ** <blockquote><table border=0 cellpadding=0 cellspacing=0> ** <tr><td><b>sqlite3_column_blob</b><td>→<td>BLOB result ** <tr><td><b>sqlite3_column_double</b><td>→<td>REAL result ** <tr><td><b>sqlite3_column_int</b><td>→<td>32-bit INTEGER result ** <tr><td><b>sqlite3_column_int64</b><td>→<td>64-bit INTEGER result ** <tr><td><b>sqlite3_column_text</b><td>→<td>UTF-8 TEXT result ** <tr><td><b>sqlite3_column_text16</b><td>→<td>UTF-16 TEXT result ** <tr><td><b>sqlite3_column_value</b><td>→<td>The result as an ** [sqlite3_value|unprotected sqlite3_value] object. ** <tr><td> <td> <td> ** <tr><td><b>sqlite3_column_bytes</b><td>→<td>Size of a BLOB ** or a UTF-8 TEXT result in bytes ** <tr><td><b>sqlite3_column_bytes16 </b> | > > | 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 | ** CAPI3REF: Result Values From A Query ** KEYWORDS: {column access functions} ** METHOD: sqlite3_stmt ** ** <b>Summary:</b> ** <blockquote><table border=0 cellpadding=0 cellspacing=0> ** <tr><td><b>sqlite3_column_blob</b><td>→<td>BLOB result ** <tr><td><b>sqlite3_column_blob_v2</b><td>→<td>BLOB result ** <tr><td><b>sqlite3_column_double</b><td>→<td>REAL result ** <tr><td><b>sqlite3_column_int</b><td>→<td>32-bit INTEGER result ** <tr><td><b>sqlite3_column_int64</b><td>→<td>64-bit INTEGER result ** <tr><td><b>sqlite3_column_text</b><td>→<td>UTF-8 TEXT result ** <tr><td><b>sqlite3_column_text_v2</b><td>→<td>UTF-8 TEXT result ** <tr><td><b>sqlite3_column_text16</b><td>→<td>UTF-16 TEXT result ** <tr><td><b>sqlite3_column_value</b><td>→<td>The result as an ** [sqlite3_value|unprotected sqlite3_value] object. ** <tr><td> <td> <td> ** <tr><td><b>sqlite3_column_bytes</b><td>→<td>Size of a BLOB ** or a UTF-8 TEXT result in bytes ** <tr><td><b>sqlite3_column_bytes16 </b> |
︙ | ︙ | |||
5295 5296 5297 5298 5299 5300 5301 | ** If any of these routines are called after [sqlite3_reset()] or ** [sqlite3_finalize()] or after [sqlite3_step()] has returned ** something other than [SQLITE_ROW], the results are undefined. ** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] ** are called from a different thread while any of these routines ** are pending, then the results are undefined. ** | | > > > > > | | 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 | ** If any of these routines are called after [sqlite3_reset()] or ** [sqlite3_finalize()] or after [sqlite3_step()] has returned ** something other than [SQLITE_ROW], the results are undefined. ** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] ** are called from a different thread while any of these routines ** are pending, then the results are undefined. ** ** The interfaces (_blob, _double, _int, _int64, _text, and _text16) ** each return the value of a result column in a specific data format. If ** the result column is not initially in the requested format (for example, ** if the query returns an integer but the sqlite3_column_text() interface ** is used to extract the value) then an automatic type conversion is performed. ** ** ^The (_blob_v2, _text_v2) interfaces behave like ** sqlite3_value_blob_v2() and sqlite3_value_text_v2(), with one ** exception: they return SQLITE_RANGE if the column index is out of ** bounds. ** ** ^The sqlite3_column_type() routine returns the ** [SQLITE_INTEGER | datatype code] for the initial data type ** of the result column. ^The returned value is one of [SQLITE_INTEGER], ** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. ** The return value of sqlite3_column_type() can be used to decide which ** of the first six interface should be used to extract the column value. ** The value returned by sqlite3_column_type() is only meaningful if no ** automatic type conversions have occurred for the value in question. ** After a type conversion, the result of calling sqlite3_column_type() ** is undefined, though harmless. Future ** versions of SQLite may change the behavior of sqlite3_column_type() ** following a type conversion. ** ** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes() ** or sqlite3_column_bytes16() interfaces can be used to determine the size |
︙ | ︙ | |||
5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 | ** In other words, you should call sqlite3_column_text(), ** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result ** into the desired format, then invoke sqlite3_column_bytes() or ** sqlite3_column_bytes16() to find the size of the result. Do not mix calls ** to sqlite3_column_text() or sqlite3_column_blob() with calls to ** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() ** with calls to sqlite3_column_bytes(). ** ** ^The pointers returned are valid until a type conversion occurs as ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or ** [sqlite3_finalize()] is called. ^The memory space used to hold strings ** and BLOBs is freed automatically. Do not pass the pointers returned ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into ** [sqlite3_free()]. ** ** As long as the input parameters are correct, these routines will only ** fail if an out-of-memory error occurs during a format conversion. ** Only the following subset of interfaces are subject to out-of-memory ** errors: ** ** <ul> ** <li> sqlite3_column_blob() ** <li> sqlite3_column_text() ** <li> sqlite3_column_text16() ** <li> sqlite3_column_bytes() ** <li> sqlite3_column_bytes16() ** </ul> ** ** If an out-of-memory error occurs, then the return value from these ** routines is the same as if the column had contained an SQL NULL value. ** Valid SQL NULL returns can be distinguished from out-of-memory errors ** by invoking the [sqlite3_errcode()] immediately after the suspect ** return value is obtained and before any ** other SQLite interface is called on the same [database connection]. */ const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); double sqlite3_column_double(sqlite3_stmt*, int iCol); int sqlite3_column_int(sqlite3_stmt*, int iCol); sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); int sqlite3_column_bytes(sqlite3_stmt*, int iCol); int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); int sqlite3_column_type(sqlite3_stmt*, int iCol); /* | > > > > > > > > > > > > | 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 | ** In other words, you should call sqlite3_column_text(), ** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result ** into the desired format, then invoke sqlite3_column_bytes() or ** sqlite3_column_bytes16() to find the size of the result. Do not mix calls ** to sqlite3_column_text() or sqlite3_column_blob() with calls to ** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() ** with calls to sqlite3_column_bytes(). ** ** The sqlite3_column_text_v2() and sqlite3_column_blob_v2() ** interfaces optionally return the byte length and column data type ** via output pointers. ** ** ^The pointers returned are valid until a type conversion occurs as ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or ** [sqlite3_finalize()] is called. ^The memory space used to hold strings ** and BLOBs is freed automatically. Do not pass the pointers returned ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into ** [sqlite3_free()]. ** ** As long as the input parameters are correct, these routines will only ** fail if an out-of-memory error occurs during a format conversion. ** Only the following subset of interfaces are subject to out-of-memory ** errors: ** ** <ul> ** <li> sqlite3_column_blob() ** <li> sqlite3_column_blob_v2() ** <li> sqlite3_column_text() ** <li> sqlite3_column_text_v2() ** <li> sqlite3_column_text16() ** <li> sqlite3_column_bytes() ** <li> sqlite3_column_bytes16() ** </ul> ** ** If an out-of-memory error occurs, then the return value from these ** routines is the same as if the column had contained an SQL NULL value. ** Valid SQL NULL returns can be distinguished from out-of-memory errors ** by invoking the [sqlite3_errcode()] immediately after the suspect ** return value is obtained and before any ** other SQLite interface is called on the same [database connection]. ** ** The previous paragraph does not apply to the text_v2 and blob_v2 ** interfaces, which return SQLITE_NOMEM to the client for ** out-of-memory conditions. */ const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); int sqlite3_column_blob_v2(sqlite3_stmt*, int iCol, const void **, int*); double sqlite3_column_double(sqlite3_stmt*, int iCol); int sqlite3_column_int(sqlite3_stmt*, int iCol); sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); int sqlite3_column_text_v2(sqlite3_stmt*, int iCol, const unsigned char **, int*); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); int sqlite3_column_bytes(sqlite3_stmt*, int iCol); int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); int sqlite3_column_type(sqlite3_stmt*, int iCol); /* |
︙ | ︙ | |||
5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 | /* ** CAPI3REF: Obtaining SQL Values ** METHOD: sqlite3_value ** ** <b>Summary:</b> ** <blockquote><table border=0 cellpadding=0 cellspacing=0> ** <tr><td><b>sqlite3_value_blob</b><td>→<td>BLOB value ** <tr><td><b>sqlite3_value_double</b><td>→<td>REAL value ** <tr><td><b>sqlite3_value_int</b><td>→<td>32-bit INTEGER value ** <tr><td><b>sqlite3_value_int64</b><td>→<td>64-bit INTEGER value ** <tr><td><b>sqlite3_value_pointer</b><td>→<td>Pointer value ** <tr><td><b>sqlite3_value_text</b><td>→<td>UTF-8 TEXT value ** <tr><td><b>sqlite3_value_text16</b><td>→<td>UTF-16 TEXT value in ** the native byteorder ** <tr><td><b>sqlite3_value_text16be</b><td>→<td>UTF-16be TEXT value ** <tr><td><b>sqlite3_value_text16le</b><td>→<td>UTF-16le TEXT value ** <tr><td> <td> <td> ** <tr><td><b>sqlite3_value_bytes</b><td>→<td>Size of a BLOB ** or a UTF-8 TEXT in bytes | > > | 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 | /* ** CAPI3REF: Obtaining SQL Values ** METHOD: sqlite3_value ** ** <b>Summary:</b> ** <blockquote><table border=0 cellpadding=0 cellspacing=0> ** <tr><td><b>sqlite3_value_blob</b><td>→<td>BLOB value ** <tr><td><b>sqlite3_value_blob_v2</b><td>→<td>BLOB value ** <tr><td><b>sqlite3_value_double</b><td>→<td>REAL value ** <tr><td><b>sqlite3_value_int</b><td>→<td>32-bit INTEGER value ** <tr><td><b>sqlite3_value_int64</b><td>→<td>64-bit INTEGER value ** <tr><td><b>sqlite3_value_pointer</b><td>→<td>Pointer value ** <tr><td><b>sqlite3_value_text</b><td>→<td>UTF-8 TEXT value ** <tr><td><b>sqlite3_value_text_v2</b><td>→<td>UTF-8 TEXT value ** <tr><td><b>sqlite3_value_text16</b><td>→<td>UTF-16 TEXT value in ** the native byteorder ** <tr><td><b>sqlite3_value_text16be</b><td>→<td>UTF-16be TEXT value ** <tr><td><b>sqlite3_value_text16le</b><td>→<td>UTF-16le TEXT value ** <tr><td> <td> <td> ** <tr><td><b>sqlite3_value_bytes</b><td>→<td>Size of a BLOB ** or a UTF-8 TEXT in bytes |
︙ | ︙ | |||
5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 | ** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^ ** Other interfaces might change the datatype for an sqlite3_value object. ** For example, if the datatype is initially SQLITE_INTEGER and ** sqlite3_value_text(V) is called to extract a text value for that ** integer, then subsequent calls to sqlite3_value_type(V) might return ** SQLITE_TEXT. Whether or not a persistent internal datatype conversion ** occurs is undefined and may change from one release of SQLite to the next. ** ** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If ** such a conversion is possible without loss of information (in other ** words, if the value is a string that looks like a number) ** then the conversion is performed. Otherwise no conversion occurs. | > > > > > > > > > > | 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 | ** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^ ** Other interfaces might change the datatype for an sqlite3_value object. ** For example, if the datatype is initially SQLITE_INTEGER and ** sqlite3_value_text(V) is called to extract a text value for that ** integer, then subsequent calls to sqlite3_value_type(V) might return ** SQLITE_TEXT. Whether or not a persistent internal datatype conversion ** occurs is undefined and may change from one release of SQLite to the next. ** ** ^sqlite3_value_blob_v2() and sqlite3_value_text_v2() interfaces ** return their content via their 2nd and 3rd arguments, output ** pointers. They behave the same as their "v1" counterparts with one ** exception: sqlite3_value_blob_v2() resolves length-0 blobs to an ** opaque non-NULL pointer instead of NULL. Their 3rd argument, if not ** NULL, will get the length of the returned blob assigned to it. If ** these functions fail they return non-0 and do not modify their ** output pointers. On success they return 0 and will update their 2nd ** and (if not NULL) 3rd output pointer arguments. ** ** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If ** such a conversion is possible without loss of information (in other ** words, if the value is a string that looks like a number) ** then the conversion is performed. Otherwise no conversion occurs. |
︙ | ︙ | |||
5943 5944 5945 5946 5947 5948 5949 | ** ** ^The sqlite3_value_frombind(X) interface returns non-zero if the ** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()] ** interfaces. ^If X comes from an SQL literal value, or a table column, ** or an expression, then sqlite3_value_frombind(X) returns zero. ** ** Please pay particular attention to the fact that the pointer returned | | > | > > > > > > > > | 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 | ** ** ^The sqlite3_value_frombind(X) interface returns non-zero if the ** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()] ** interfaces. ^If X comes from an SQL literal value, or a table column, ** or an expression, then sqlite3_value_frombind(X) returns zero. ** ** Please pay particular attention to the fact that the pointer returned ** from [sqlite3_value_blob()], [sqlite3_value_blob_v2()], ** [sqlite3_value_text()], [sqlite3_value_text_v2()], or ** [sqlite3_value_text16()] can be invalidated by a subsequent call to ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], ** [sqlite3_value_text_v2()], or [sqlite3_value_text16()]. ** ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. ** ** As long as the input parameter is correct, these routines can only ** fail if an out-of-memory error occurs during a format conversion. ** Only the following subset of interfaces are subject to out-of-memory ** errors: ** ** <ul> ** <li> sqlite3_value_blob_v2() ** <li> sqlite3_value_blob() ** <li> sqlite3_value_text() ** <li> sqlite3_value_text_v2() ** <li> sqlite3_value_text16() ** <li> sqlite3_value_text16le() ** <li> sqlite3_value_text16be() ** <li> sqlite3_value_bytes() ** <li> sqlite3_value_bytes16() ** </ul> ** ** If an out-of-memory error occurs, then the return value from these ** routines is the same as if the column had contained an SQL NULL value. ** Valid SQL NULL returns can be distinguished from out-of-memory errors ** by invoking the [sqlite3_errcode()] immediately after the suspect ** return value is obtained and before any ** other SQLite interface is called on the same [database connection]. ** ** The previous paragraph does not apply to the text_v2 and blob_v2 ** interfaces, which return SQLITE_NOMEM to the client for ** out-of-memory conditions. */ const void *sqlite3_value_blob(sqlite3_value*); int sqlite3_value_blob_v2(sqlite3_value*, const void **, int*); double sqlite3_value_double(sqlite3_value*); int sqlite3_value_int(sqlite3_value*); sqlite3_int64 sqlite3_value_int64(sqlite3_value*); void *sqlite3_value_pointer(sqlite3_value*, const char*); const unsigned char *sqlite3_value_text(sqlite3_value*); int sqlite3_value_text_v2(sqlite3_value*, const unsigned char **, int*); const void *sqlite3_value_text16(sqlite3_value*); const void *sqlite3_value_text16le(sqlite3_value*); const void *sqlite3_value_text16be(sqlite3_value*); int sqlite3_value_bytes(sqlite3_value*); int sqlite3_value_bytes16(sqlite3_value*); int sqlite3_value_type(sqlite3_value*); int sqlite3_value_numeric_type(sqlite3_value*); |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 | void sqlite3FileSuffix3(const char*, char*); #else # define sqlite3FileSuffix3(X,Y) #endif u8 sqlite3GetBoolean(const char *z,u8); const void *sqlite3ValueText(sqlite3_value*, u8); int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*)); int sqlite3ValueBytes(sqlite3_value*, u8); void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); void sqlite3ValueSetNull(sqlite3_value*); void sqlite3ValueFree(sqlite3_value*); #ifndef SQLITE_UNTESTABLE | > > | 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 | void sqlite3FileSuffix3(const char*, char*); #else # define sqlite3FileSuffix3(X,Y) #endif u8 sqlite3GetBoolean(const char *z,u8); const void *sqlite3ValueText(sqlite3_value*, u8); int sqlite3ValueTextV2(sqlite3_value*, u8, const void **, int*); int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*)); int sqlite3ValueBytes(sqlite3_value*, u8); void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); void sqlite3ValueSetNull(sqlite3_value*); void sqlite3ValueFree(sqlite3_value*); #ifndef SQLITE_UNTESTABLE |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 | if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; len = sqlite3_column_bytes(pStmt, col); pBlob = sqlite3_column_blob(pStmt, col); Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); return TCL_OK; } /* ** Usage: sqlite3_column_double STMT column ** ** Return the data in column 'column' of the current row cast as a double. */ static int SQLITE_TCLAPI test_column_double( | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 | if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; len = sqlite3_column_bytes(pStmt, col); pBlob = sqlite3_column_blob(pStmt, col); Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); return TCL_OK; } /* ** Usage: sqlite3_column_blob_v2 STMT column */ static int SQLITE_TCLAPI test_column_blob_v2( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_stmt *pStmt; int col; int rc; int len = 0; const void *pBlob = 0; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "STMT column"); return TCL_ERROR; } if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; rc = sqlite3_column_blob_v2(pStmt, col, &pBlob, &len); if( rc ) return TCL_ERROR; Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); return TCL_OK; } /* ** Usage: sqlite3_column_double STMT column ** ** Return the data in column 'column' of the current row cast as a double. */ static int SQLITE_TCLAPI test_column_double( |
︙ | ︙ | |||
5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 | if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; if( xFunc==sqlite3_column_name || xFunc==sqlite3_column_decltype ){ zRet = xFunc(pStmt, col); }else{ zRet = (const char*)xFuncU(pStmt, col); } if( zRet ){ Tcl_SetResult(interp, (char *)zRet, 0); } return TCL_OK; } static int SQLITE_TCLAPI test_global_recover( | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 | if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; if( xFunc==sqlite3_column_name || xFunc==sqlite3_column_decltype ){ zRet = xFunc(pStmt, col); }else{ zRet = (const char*)xFuncU(pStmt, col); } if( zRet ){ Tcl_SetResult(interp, (char *)zRet, 0); } return TCL_OK; } /* ** Usage: sqlite3_column_text_v2 STMT column */ static int SQLITE_TCLAPI test_stmt_utf8_v2( void * clientData, /* Pointer to SQLite API function to be invoke */ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_stmt *pStmt; int col; int len = 0; const unsigned char *zRet = 0; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "STMT column"); return TCL_ERROR; } if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; if( sqlite3_column_text_v2(pStmt, col, &zRet, &len) ){ return TCL_ERROR; } if( zRet ){ Tcl_SetResult(interp, (char *)zRet, 0); } return TCL_OK; } static int SQLITE_TCLAPI test_global_recover( |
︙ | ︙ | |||
9017 9018 9019 9020 9021 9022 9023 9024 9025 | { "tcl_objproc", runAsObjProc, 0 }, /* sqlite3_column_*() API */ { "sqlite3_column_count", test_column_count ,0 }, { "sqlite3_data_count", test_data_count ,0 }, { "sqlite3_column_type", test_column_type ,0 }, { "sqlite3_column_blob", test_column_blob ,0 }, { "sqlite3_column_double", test_column_double ,0 }, { "sqlite3_column_int64", test_column_int64 ,0 }, | > | > | | | | 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 | { "tcl_objproc", runAsObjProc, 0 }, /* sqlite3_column_*() API */ { "sqlite3_column_count", test_column_count ,0 }, { "sqlite3_data_count", test_data_count ,0 }, { "sqlite3_column_type", test_column_type ,0 }, { "sqlite3_column_blob", test_column_blob ,0 }, { "sqlite3_column_blob_v2", test_column_blob_v2,0 }, { "sqlite3_column_double", test_column_double ,0 }, { "sqlite3_column_int64", test_column_int64 ,0 }, { "sqlite3_column_text", test_stmt_utf8, (void*)sqlite3_column_text }, { "sqlite3_column_text_v2", test_stmt_utf8_v2, 0 }, { "sqlite3_column_name", test_stmt_utf8, (void*)sqlite3_column_name }, { "sqlite3_column_int", test_stmt_int, (void*)sqlite3_column_int }, { "sqlite3_column_bytes", test_stmt_int, (void*)sqlite3_column_bytes}, #ifndef SQLITE_OMIT_DECLTYPE { "sqlite3_column_decltype",test_stmt_utf8,(void*)sqlite3_column_decltype}, #endif #ifdef SQLITE_ENABLE_COLUMN_METADATA { "sqlite3_column_database_name",test_stmt_utf8,(void*)sqlite3_column_database_name}, { "sqlite3_column_table_name",test_stmt_utf8,(void*)sqlite3_column_table_name}, { "sqlite3_column_origin_name",test_stmt_utf8,(void*)sqlite3_column_origin_name}, |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
170 171 172 173 174 175 176 | if( p->expmask ){ p->expired = 1; } sqlite3_mutex_leave(mutex); return rc; } | < > > > > > > > > > > > > > > > > > > > | 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 | if( p->expmask ){ p->expired = 1; } sqlite3_mutex_leave(mutex); return rc; } /**************************** sqlite3_value_ ******************************* ** The following routines extract information from a Mem or sqlite3_value ** structure. */ const void *sqlite3_value_blob(sqlite3_value *pVal){ Mem *p = (Mem*)pVal; if( p->flags & (MEM_Blob|MEM_Str) ){ if( ExpandBlob(p)!=SQLITE_OK ){ assert( p->flags==MEM_Null && p->z==0 ); return 0; } p->flags |= MEM_Blob; return p->n ? p->z : 0; }else{ return sqlite3_value_text(pVal); } } int sqlite3_value_blob_v2(sqlite3_value *pVal, const void **pOut, int *pnOut){ static const unsigned char aZeroLength[] = {0,0}; Mem *p = (Mem*)pVal; #ifdef SQLITE_ENABLE_API_ARMOR if( pVal==0 || pOut==0 ) return SQLITE_MISUSE_BKPT; #endif if( p->flags & (MEM_Blob|MEM_Str) ){ if( ExpandBlob(p)!=SQLITE_OK ){ assert( p->flags==MEM_Null && p->z==0 ); return SQLITE_NOMEM_BKPT; } p->flags |= MEM_Blob; *pOut = p->n ? p->z : (const void *)&aZeroLength[0]; if( pnOut ) *pnOut = p->n; return 0; } return sqlite3_value_text_v2(pVal, (const unsigned char **)pOut, pnOut); } int sqlite3_value_bytes(sqlite3_value *pVal){ return sqlite3ValueBytes(pVal, SQLITE_UTF8); } int sqlite3_value_bytes16(sqlite3_value *pVal){ return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); } |
︙ | ︙ | |||
222 223 224 225 226 227 228 229 230 231 232 233 234 235 | return (void*)p->z; }else{ return 0; } } const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } #ifndef SQLITE_OMIT_UTF16 const void *sqlite3_value_text16(sqlite3_value* pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); } const void *sqlite3_value_text16be(sqlite3_value *pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16BE); | > > > > > > > > > | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | return (void*)p->z; }else{ return 0; } } const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } int sqlite3_value_text_v2(sqlite3_value *pVal, const unsigned char **pOut, int *pnOut){ int n = 0; #ifdef SQLITE_ENABLE_API_ARMOR if( pVal==0 || pOut==0 ) return SQLITE_MISUSE_BKPT; #endif return sqlite3ValueTextV2(pVal, SQLITE_UTF8, (const void **)pOut, pnOut ? pnOut : &n); } #ifndef SQLITE_OMIT_UTF16 const void *sqlite3_value_text16(sqlite3_value* pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); } const void *sqlite3_value_text16be(sqlite3_value *pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16BE); |
︙ | ︙ | |||
1299 1300 1301 1302 1303 1304 1305 | return &nullMem; } /* ** Check to see if column iCol of the given statement is valid. If ** it is, return a pointer to the Mem for the value of that column. ** If iCol is not valid, return a pointer to a Mem which has a value | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 | return &nullMem; } /* ** Check to see if column iCol of the given statement is valid. If ** it is, return a pointer to the Mem for the value of that column. ** If iCol is not valid, return a pointer to a Mem which has a value ** of NULL and set the db's eror code to SQLITE_RANGE. */ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ Vdbe *pVm; Mem *pOut; pVm = (Vdbe *)pStmt; if( pVm==0 ) return (Mem*)columnNullValue(); assert( pVm->db ); sqlite3_mutex_enter(pVm->db->mutex); if( pVm->pResultRow!=0 && i<pVm->nResColumn && i>=0 ){ pOut = &pVm->pResultRow[i]; }else{ sqlite3Error(pVm->db, SQLITE_RANGE); pOut = (Mem*)columnNullValue(); } return pOut; } /* ** A variant of columnMem(pStmt,iCol) with the following differences: ** ** 1. On success it returns 0 and stores a pointer to the underlying ** memory in *pOut and its length to *pnOut (if not NULL). On error ** it returns non-0 and does not modifiy *pOut or *pnOut. ** ** 2. It does not record an out-of-bounds iCol as a persistent ** SQLITE_RANGE error. ** ** A NULL pStmt or pOut results in SQLITE_MISUSE but a NULL pnOut is ** legal. ** ** If bBlob is true, sqlite3_value_blob_v2() is used for the ** extraction, else sqlite3_value_text_v2() is used. ** ** This is expected to only be called by sqlite3_column_blob_v2(), ** sqlite3_column_text_v2(), or APIs with similar semantics. ** ** Design notes based on /chat discussions: ** ** sqlite3_column_text/blob_v2() can report SQLITE_RANGE and ** SQLITE_MISUSE, but must not perist those errors and must not take ** prior error state into account (e.g. do not propagate a ** SQLITE_RANGE error across calls). They unavoidably persist ** SQLITE_NOMEM errors via deeper APIs. This routine specifically does ** not call columnMallocFailure() to avoid calling sqlite3ApiExit(). */ static int columnMemV2(sqlite3_stmt *pStmt, int iCol, int bBlob, const void **pOut, int * pnOut){ int rc = 0; Vdbe * const pVm = (Vdbe*)pStmt; #ifdef SQLITE_ENABLE_API_ARMOR if( pVm==0 || pOut==0 ) return SQLITE_MISUSE_BKPT; #endif assert( pVm->db ); sqlite3_mutex_enter(pVm->db->mutex); if( pVm->pResultRow!=0 && iCol<pVm->nResColumn && iCol>=0 ){ Mem * const pMem = &pVm->pResultRow[iCol]; rc = bBlob ? sqlite3_value_blob_v2(pMem, pOut, pnOut) : sqlite3_value_text_v2(pMem, (const unsigned char **)pOut, pnOut); }else{ rc = pVm->pResultRow==0 ? SQLITE_MISUSE_BKPT : SQLITE_RANGE; } sqlite3_mutex_leave(pVm->db->mutex); return rc; } /* ** This function is called after invoking an sqlite3_value_XXX function on a ** column value (i.e. a value returned by evaluating an SQL expression in the ** select list of a SELECT statement) that may cause a malloc() failure. If ** malloc() has failed, the thread's mallocFailed flag is cleared and the result ** code of statement pStmt set to SQLITE_NOMEM. ** ** Specifically, this is called from within: ** ** sqlite3_column_int() ** sqlite3_column_int64() ** sqlite3_column_text() |
︙ | ︙ | |||
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 | val = sqlite3_value_blob( columnMem(pStmt,i) ); /* Even though there is no encoding conversion, value_blob() might ** need to call malloc() to expand the result of a zeroblob() ** expression. */ columnMallocFailure(pStmt); return val; } int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ int val = sqlite3_value_bytes( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ | > > > > | 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 | val = sqlite3_value_blob( columnMem(pStmt,i) ); /* Even though there is no encoding conversion, value_blob() might ** need to call malloc() to expand the result of a zeroblob() ** expression. */ columnMallocFailure(pStmt); return val; } int sqlite3_column_blob_v2(sqlite3_stmt *pStmt, int iCol, const void **pOut, int *pnOut){ return columnMemV2(pStmt, iCol, 1, pOut, pnOut); } int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ int val = sqlite3_value_bytes( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ |
︙ | ︙ | |||
1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 | return val; } const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ Mem *pOut = columnMem(pStmt, i); if( pOut->flags&MEM_Static ){ pOut->flags &= ~MEM_Static; pOut->flags |= MEM_Ephem; } columnMallocFailure(pStmt); | > > > > | 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 | return val; } const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } int sqlite3_column_text_v2(sqlite3_stmt *pStmt, int iCol, const unsigned char **pOut, int *pnOut){ return columnMemV2(pStmt, iCol, 0, (const void **)pOut, pnOut); } sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ Mem *pOut = columnMem(pStmt, i); if( pOut->flags&MEM_Static ){ pOut->flags &= ~MEM_Static; pOut->flags |= MEM_Ephem; } columnMallocFailure(pStmt); |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 | if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ assert( sqlite3VdbeMemValidStrRep(pVal) ); return pVal->z; }else{ return 0; } } /* This function is only available internally, it is not part of the ** external API. It works in a similar way to sqlite3_value_text(), ** except the data returned is in the encoding specified by the second ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or ** SQLITE_UTF8. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 | if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ assert( sqlite3VdbeMemValidStrRep(pVal) ); return pVal->z; }else{ return 0; } } /* ** This works like valueToText() but returns its result using ** different semantics. On success, return 0, set *pOut to a ** zero-terminated version of that string, and set *pnOut (which must ** not be NULL to the string-length of that memory. ** ** On error, return non-0 and do not modify pOut or pnOut. ** ** Maintenance note: this is almost a copy/paste clone of ** valueToText(), but the two should probably not be consolidated. The ** initial version of this API did so in [730c6a623e29b59b] and the ** CPU cycles doubled. */ static SQLITE_NOINLINE int valueToTextV2(sqlite3_value* pVal, u8 enc, const void **pOut, int *pnOut){ assert( pVal!=0 ); assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); assert( !sqlite3VdbeMemIsRowSet(pVal) ); assert( (pVal->flags & (MEM_Null))==0 ); assert( pOut!=0 ); assert( pnOut!=0 ); if( pVal->flags & (MEM_Blob|MEM_Str) ){ if( ExpandBlob(pVal) ){ return SQLITE_NOMEM_BKPT; } pVal->flags |= MEM_Str; if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); } if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){ assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); const int rc = sqlite3VdbeMemMakeWriteable(pVal); if( rc!=SQLITE_OK ){ assert( SQLITE_NOMEM==rc ); return SQLITE_NOMEM_BKPT; } } if ( sqlite3VdbeMemNulTerminate(pVal) ){ /* IMP: R-31275-44060 */ return SQLITE_NOMEM_BKPT; } }else{ sqlite3VdbeMemStringify(pVal, enc, 0); assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); } if( pVal->db && pVal->db->mallocFailed ){ return SQLITE_NOMEM_BKPT; } assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0); if( ALWAYS(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED)) ){ assert( sqlite3VdbeMemValidStrRep(pVal) ); *pOut = pVal->z; *pnOut = pVal->n; return 0; } assert( pVal->db==0 ); return SQLITE_ERROR; } /* This function is only available internally, it is not part of the ** external API. It works in a similar way to sqlite3_value_text(), ** except the data returned is in the encoding specified by the second ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or ** SQLITE_UTF8. ** |
︙ | ︙ | |||
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 | return pVal->z; } if( pVal->flags&MEM_Null ){ return 0; } return valueToText(pVal, enc); } /* Return true if sqlit3_value object pVal is a string or blob value ** that uses the destructor specified in the second argument. ** ** TODO: Maybe someday promote this interface into a published API so ** that third-party extensions can get access to it? */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 | return pVal->z; } if( pVal->flags&MEM_Null ){ return 0; } return valueToText(pVal, enc); } /* This works similarly to sqlite3ValueText() but returns its result ** with different semantics. ** ** On success, returns 0, sets *pOut to the underlying value (or NULL ** in the case of NULL), and sets *pnOut to the memory's usable ** length. On error, neither *pOut nor *pnOut are modified. ** ** Results are undefined if pVal, pOut, or pnOut are NULL. */ int sqlite3ValueTextV2(sqlite3_value* pVal, u8 enc, const void **pOut, int *pnOut){ /*if( !pVal ) return SQLITE_MISUSE_BKPT;*/ assert( pVal!=0 ); assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); assert( !sqlite3VdbeMemIsRowSet(pVal) ); assert( pOut!=0 ); assert( pnOut!=0 ); if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ assert( sqlite3VdbeMemValidStrRep(pVal) ); *pOut = pVal->z; *pnOut = pVal->n; return 0; } if( pVal->flags&MEM_Null ){ *pOut = 0; *pnOut = 0; return 0; } return valueToTextV2(pVal, enc, pOut, pnOut); } /* Return true if sqlit3_value object pVal is a string or blob value ** that uses the destructor specified in the second argument. ** ** TODO: Maybe someday promote this interface into a published API so ** that third-party extensions can get access to it? */ |
︙ | ︙ |
Changes to test/capi2.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 | # $Id: capi2.test,v 1.37 2008/12/30 17:55:00 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Return the text values from the current row pointed at by STMT as a list. | > | | > > > > > > > > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | # $Id: capi2.test,v 1.37 2008/12/30 17:55:00 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Return the text values from the current row pointed at by STMT as a list. # $getter is the column-get-text function to invoke. proc get_row_values_impl {getter STMT} { set VALUES [list] for {set i 0} {$i < [sqlite3_data_count $STMT]} {incr i} { lappend VALUES [$getter $STMT $i] } return $VALUES } proc get_row_values {STMT} { get_row_values_impl sqlite3_column_text $STMT } # Must produce the same result as get_row_values(). proc get_row_values_v2 {STMT} { get_row_values_impl sqlite3_column_text_v2 $STMT } # Return the column names followed by declaration types for the result set # of the SQL statement STMT. # # i.e. for: # CREATE TABLE abc(a text, b integer); # SELECT * FROM abc; |
︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 | } {SQLITE_ROW} do_test capi2-1.3 { sqlite3_data_count $VM } {2} do_test capi2-1.4 { get_row_values $VM } {t1 1} do_test capi2-1.5 { get_column_names $VM } {name rowid TEXT INTEGER} do_test capi2-1.6 { sqlite3_step $VM } {SQLITE_DONE} do_test capi2-1.7 { | > > > | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | } {SQLITE_ROW} do_test capi2-1.3 { sqlite3_data_count $VM } {2} do_test capi2-1.4 { get_row_values $VM } {t1 1} do_test capi2-1.4_v2 { get_row_values_v2 $VM } {t1 1} do_test capi2-1.5 { get_column_names $VM } {name rowid TEXT INTEGER} do_test capi2-1.6 { sqlite3_step $VM } {SQLITE_DONE} do_test capi2-1.7 { |
︙ | ︙ | |||
120 121 122 123 124 125 126 | lappend r [sqlite3_column_count $VM] \ [get_row_values $VM] \ [get_column_names $VM] } {SQLITE_ROW 2 {t1 1} {name rowid TEXT INTEGER}} do_test capi2-2.3 { set r [sqlite3_step $VM] lappend r [sqlite3_column_count $VM] \ | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | lappend r [sqlite3_column_count $VM] \ [get_row_values $VM] \ [get_column_names $VM] } {SQLITE_ROW 2 {t1 1} {name rowid TEXT INTEGER}} do_test capi2-2.3 { set r [sqlite3_step $VM] lappend r [sqlite3_column_count $VM] \ [get_row_values_v2 $VM] \ [get_column_names $VM] } {SQLITE_DONE 2 {} {name rowid TEXT INTEGER}} do_test capi2-2.4 { sqlite3_finalize $VM } {SQLITE_OK} do_test capi2-2.5 { set VM [sqlite3_prepare $DB $SQL -1 SQL] |
︙ | ︙ | |||
187 188 189 190 191 192 193 | sqlite3_prepare $DB {select 5/0;} -1 TAIL } VM] lappend rc $TAIL } {0 {}} do_test capi2-3.7 { list [sqlite3_step $VM] \ [sqlite3_column_count $VM] \ | | | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | sqlite3_prepare $DB {select 5/0;} -1 TAIL } VM] lappend rc $TAIL } {0 {}} do_test capi2-3.7 { list [sqlite3_step $VM] \ [sqlite3_column_count $VM] \ [get_row_values_v2 $VM] \ [get_column_names $VM] } {SQLITE_ROW 1 {{}} {5/0 {}}} do_test capi2-3.8 { sqlite3_finalize $VM } {SQLITE_OK} do_test capi2-3.9 { execsql {CREATE UNIQUE INDEX i1 ON t1(a)} |
︙ | ︙ | |||
543 544 545 546 547 548 549 | INSERT INTO t1 VALUES(2,3,4); SELECT * FROM t1; } } {1 3 3 2 3 4} do_test capi2-6.26 { list [sqlite3_step $VM1] \ [sqlite3_column_count $VM1] \ | | | | 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | INSERT INTO t1 VALUES(2,3,4); SELECT * FROM t1; } } {1 3 3 2 3 4} do_test capi2-6.26 { list [sqlite3_step $VM1] \ [sqlite3_column_count $VM1] \ [get_row_values_v2 $VM1] \ [get_column_names $VM1] } {SQLITE_ROW 1 12 {x counter}} do_test capi2-6.27 { catchsql { INSERT INTO t1 VALUES(2,4,5); SELECT * FROM t1; } } {1 {UNIQUE constraint failed: t1.a}} do_test capi2-6.28 { list [sqlite3_step $VM1] \ [sqlite3_column_count $VM1] \ [get_row_values_v2 $VM1] \ [get_column_names $VM1] } {SQLITE_ROW 1 13 {x counter}} do_test capi2-6.99 { sqlite3_finalize $VM1 } {SQLITE_OK} catchsql {ROLLBACK} |
︙ | ︙ |
Changes to test/capi3.test.
︙ | ︙ | |||
509 510 511 512 513 514 515 516 517 518 519 520 521 522 | # Blob do_test $test.5 { set utf8 [list] foreach i $idxlist {lappend utf8 [sqlite3_column_blob $STMT $i]} set utf8 } $strings # UTF-8 do_test $test.6 { set utf8 [list] foreach i $idxlist {lappend utf8 [sqlite3_column_text $STMT $i]} set utf8 } $strings | > > > > > > | 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | # Blob do_test $test.5 { set utf8 [list] foreach i $idxlist {lappend utf8 [sqlite3_column_blob $STMT $i]} set utf8 } $strings do_test $test.5_v2 { set utf8 [list] foreach i $idxlist {lappend utf8 [sqlite3_column_blob_v2 $STMT $i]} set utf8 } $strings # UTF-8 do_test $test.6 { set utf8 [list] foreach i $idxlist {lappend utf8 [sqlite3_column_text $STMT $i]} set utf8 } $strings |
︙ | ︙ | |||
1257 1258 1259 1260 1261 1262 1263 | do_test 20.2 { set stmt [sqlite3_prepare db "SELECT * FROM t4" -1 dummy] sqlite3_step $stmt } {SQLITE_ROW} do_test 20.3 { sqlite3_column_type $stmt 0 } {TEXT} do_test 20.4 { sqlite3_column_blob $stmt 0 } {abcdefghij} do_test 20.5 { sqlite3_column_type $stmt 0 } {TEXT} | > > | | 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 | do_test 20.2 { set stmt [sqlite3_prepare db "SELECT * FROM t4" -1 dummy] sqlite3_step $stmt } {SQLITE_ROW} do_test 20.3 { sqlite3_column_type $stmt 0 } {TEXT} do_test 20.4 { sqlite3_column_blob $stmt 0 } {abcdefghij} do_test 20.5 { sqlite3_column_type $stmt 0 } {TEXT} do_test 20.6 { sqlite3_column_blob_v2 $stmt 0 } {abcdefghij} do_test 20.7 { sqlite3_column_type $stmt 0 } {TEXT} do_test 20.8 { sqlite3_finalize $stmt } SQLITE_OK # Tests of the interface when no VFS is registered. # if {![info exists tester_do_binarylog]} { db close vfs_unregister_all |
︙ | ︙ |