1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-27 20:41:58 +03:00

Experimentally add another output pointer to the text/blob_v2() family which gets the sqlite3_value_type() assigned to it if it's not NULL, based on feedback in the forum.

FossilOrigin-Name: 4aab781d2abc64a39c53acd0faf6d60bb38afcce42f25bc8c0fa52b73df05312
This commit is contained in:
stephan
2025-07-01 16:38:58 +00:00
parent 3daba35147
commit c5e9645e1b
8 changed files with 115 additions and 94 deletions

View File

@ -113,7 +113,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_clear_bindings","int", "sqlite3_stmt*"], ["sqlite3_clear_bindings","int", "sqlite3_stmt*"],
["sqlite3_collation_needed", "int", "sqlite3*", "*", "*"/*=>v(ppis)*/], ["sqlite3_collation_needed", "int", "sqlite3*", "*", "*"/*=>v(ppis)*/],
["sqlite3_column_blob","*", "sqlite3_stmt*", "int"], ["sqlite3_column_blob","*", "sqlite3_stmt*", "int"],
["sqlite3_column_blob_v2", "int", "sqlite3_stmt*", "int", "**", "*"], ["sqlite3_column_blob_v2", "int", "sqlite3_stmt*", "int", "**", "*", "*"],
["sqlite3_column_bytes","int", "sqlite3_stmt*", "int"], ["sqlite3_column_bytes","int", "sqlite3_stmt*", "int"],
["sqlite3_column_count", "int", "sqlite3_stmt*"], ["sqlite3_column_count", "int", "sqlite3_stmt*"],
["sqlite3_column_decltype", "string", "sqlite3_stmt*", "int"], ["sqlite3_column_decltype", "string", "sqlite3_stmt*", "int"],
@ -121,7 +121,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_column_int","int", "sqlite3_stmt*", "int"], ["sqlite3_column_int","int", "sqlite3_stmt*", "int"],
["sqlite3_column_name","string", "sqlite3_stmt*", "int"], ["sqlite3_column_name","string", "sqlite3_stmt*", "int"],
["sqlite3_column_text","string", "sqlite3_stmt*", "int"], ["sqlite3_column_text","string", "sqlite3_stmt*", "int"],
["sqlite3_column_text_v2", "int", "sqlite3_stmt*", "int", "**", "*"], ["sqlite3_column_text_v2", "int", "sqlite3_stmt*", "int", "**", "*", "*"],
["sqlite3_column_type","int", "sqlite3_stmt*", "int"], ["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"], ["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"],
["sqlite3_commit_hook", "void*", [ ["sqlite3_commit_hook", "void*", [
@ -307,7 +307,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_uri_parameter", "string", "sqlite3_filename", "string"], ["sqlite3_uri_parameter", "string", "sqlite3_filename", "string"],
["sqlite3_user_data","void*", "sqlite3_context*"], ["sqlite3_user_data","void*", "sqlite3_context*"],
["sqlite3_value_blob", "*", "sqlite3_value*"], ["sqlite3_value_blob", "*", "sqlite3_value*"],
["sqlite3_value_blob_v2", "int", "sqlite3_value*", "**", "*"], ["sqlite3_value_blob_v2", "int", "sqlite3_value*", "**", "*", "*"],
["sqlite3_value_bytes","int", "sqlite3_value*"], ["sqlite3_value_bytes","int", "sqlite3_value*"],
["sqlite3_value_double","f64", "sqlite3_value*"], ["sqlite3_value_double","f64", "sqlite3_value*"],
["sqlite3_value_dup", "sqlite3_value*", "sqlite3_value*"], ["sqlite3_value_dup", "sqlite3_value*", "sqlite3_value*"],
@ -319,7 +319,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"], ["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"],
["sqlite3_value_subtype", "int", "sqlite3_value*"], ["sqlite3_value_subtype", "int", "sqlite3_value*"],
["sqlite3_value_text", "string", "sqlite3_value*"], ["sqlite3_value_text", "string", "sqlite3_value*"],
["sqlite3_value_text_v2", "int", "sqlite3_value*", "**", "*"], ["sqlite3_value_text_v2", "int", "sqlite3_value*", "**", "*", "*"],
["sqlite3_value_type", "int", "sqlite3_value*"], ["sqlite3_value_type", "int", "sqlite3_value*"],
["sqlite3_vfs_find", "*", "string"], ["sqlite3_vfs_find", "*", "string"],
["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"], ["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],

View File

@ -3352,18 +3352,22 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
try { try {
let sv, rc; let sv, rc;
q = db.prepare("select a, b from t order by a"); q = db.prepare("select a, b from t order by a");
let [ppOut,pnOut] = P.allocPtr(2); let [ppOut, pnOut, pType] = P.allocPtr(3);
const clearPtrs = ()=>{
wasm.pokePtr(ppOut, 0);
wasm.poke32(pnOut, 0);
wasm.poke32(pType, 0);
};
const next = ()=>{ const next = ()=>{
T.assert( q.step() ); T.assert( q.step() );
sv = capi.sqlite3_column_value(q, 1); sv = capi.sqlite3_column_value(q, 1);
T.assert( sv ); T.assert( sv );
wasm.pokePtr(ppOut, 0); clearPtrs();
wasm.poke32(pnOut, 0); rc = capi.sqlite3_value_text_v2(sv, ppOut, pnOut, pType);
rc = capi.sqlite3_value_text_v2(sv, ppOut, pnOut);
T.assert( 0===rc ); T.assert( 0===rc );
return sv; return sv;
}; };
const cmp = function(expect){ const cmp = function(type,expect){
const blob = wasm.peekPtr(ppOut); const blob = wasm.peekPtr(ppOut);
const len = wasm.peek32(pnOut); const len = wasm.peek32(pnOut);
//log("blob=",wasm.cstrToJs(blob)); //log("blob=",wasm.cstrToJs(blob));
@ -3379,22 +3383,20 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
.assert( str===expect, "String mismatch: got [" .assert( str===expect, "String mismatch: got ["
+str+"] expected ["+expect+"]"); +str+"] expected ["+expect+"]");
}; };
const cmp2 = (expect)=>{ const cmp2 = (type,expect)=>{
next(); next();
cmp(expect); cmp(type,expect);
wasm.pokePtr(ppOut, 0); clearPtrs();
wasm.poke32(pnOut, 0); const rc = capi.sqlite3_column_text_v2(q, 1, ppOut, pnOut, pType);
const rc = capi.sqlite3_column_text_v2(q, 1, ppOut, pnOut);
T.assert( 0==rc, "expecting column_text_v2() rc 0 but got "+rc ); T.assert( 0==rc, "expecting column_text_v2() rc 0 but got "+rc );
cmp(expect); cmp(type,expect);
}; };
cmp2('123'); cmp2(capi.SQLITE_INTEGER,'123');
cmp2(null); cmp2(capi.SQLITE_NULL,null);
cmp2('hi world'); cmp2(capi.SQLITE_TEXT,'hi world');
cmp2( '#*' ); cmp2(capi.SQLITE_BLOB, '#*');
cmp2( '' ); // empty strings are not null cmp2(capi.SQLITE_TEXT, ''); // empty strings are not null
const checkRc = (name, descr, rc)=>{ const checkRc = (name, descr, rc)=>{
T.assert( capi[name] === rc, T.assert( capi[name] === rc,
@ -3408,22 +3410,24 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
// This does not set a persistent error flag on q: // This does not set a persistent error flag on q:
checkRc('SQLITE_RANGE', "column_text_v2() bad index", checkRc('SQLITE_RANGE', "column_text_v2() bad index",
capi.sqlite3_column_text_v2(q, 11, ppOut, pnOut) ); capi.sqlite3_column_text_v2(q, 11, ppOut, pnOut, 0) );
checkRc('SQLITE_OK', "column_text_v2() valid index", checkRc('SQLITE_OK', "column_text_v2() valid index",
capi.sqlite3_column_text_v2(q, 1, ppOut, 0)); capi.sqlite3_column_text_v2(q, 1, ppOut, 0, 0));
checkRc('SQLITE_OK', "column null pnOut", checkRc('SQLITE_OK', "column null pnOut",
capi.sqlite3_column_text_v2(q, 1, ppOut, 0)); capi.sqlite3_column_text_v2(q, 1, ppOut, 0, 0));
/* Some of the following only applies because we build with
SQLITE_ENABLE_API_ARMOR. */
checkRc('SQLITE_MISUSE', "value null ppOut", checkRc('SQLITE_MISUSE', "value null ppOut",
capi.sqlite3_value_text_v2(sv, 0, pnOut)); capi.sqlite3_value_text_v2(sv, 0, pnOut, 0));
checkRc('SQLITE_MISUSE', "value null arg0", checkRc('SQLITE_MISUSE', "value null arg0",
capi.sqlite3_value_text_v2(0, ppOut, pnOut)); capi.sqlite3_value_text_v2(0, ppOut, pnOut, 0));
checkRc('SQLITE_MISUSE', "column null ppOut", checkRc('SQLITE_MISUSE', "column null ppOut",
capi.sqlite3_column_text_v2(q, 1, 0, pnOut)); capi.sqlite3_column_text_v2(q, 1, 0, pnOut, 0));
/* But a 0 pnOut is always okay. */ /* But a 0 pnOut is always okay. */
checkRc('SQLITE_OK', "value null pnOut", checkRc('SQLITE_OK', "value null pnOut",
capi.sqlite3_value_text_v2(sv, ppOut, 0)); capi.sqlite3_value_text_v2(sv, ppOut, 0, 0));
}finally{ }finally{
if( q ) q.finalize(); if( q ) q.finalize();
@ -3443,18 +3447,23 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
try { try {
let sv, rc; let sv, rc;
q = db.prepare("select a, b from t order by a"); q = db.prepare("select a, b from t order by a");
let [ppOut,pnOut] = P.allocPtr(2); let [ppOut, pnOut, pType] = P.allocPtr(3);
const clearPtrs = ()=>{
wasm.pokePtr(ppOut, 0);
wasm.poke32(pnOut, 0);
wasm.poke32(pType, 0);
};
const next = ()=>{ const next = ()=>{
T.assert( q.step() ); T.assert( q.step() );
sv = capi.sqlite3_column_value(q, 1); sv = capi.sqlite3_column_value(q, 1);
T.assert( sv ); T.assert( sv );
wasm.pokePtr(ppOut, 0); clearPtrs();
wasm.poke32(pnOut, 0); rc = capi.sqlite3_value_blob_v2(sv, ppOut, pnOut, pType);
rc = capi.sqlite3_value_blob_v2(sv, ppOut, pnOut);
T.assert( 0==rc, "expecting value_blob_v2() rc 0 but got "+rc ); T.assert( 0==rc, "expecting value_blob_v2() rc 0 but got "+rc );
return sv; return sv;
}; };
const cmp = (byteList)=>{ const cmp = (type,byteList)=>{
const blob = wasm.peekPtr(ppOut); const blob = wasm.peekPtr(ppOut);
const len = wasm.peek32(pnOut); const len = wasm.peek32(pnOut);
//log("blob=",wasm.cstrToJs(blob)); //log("blob=",wasm.cstrToJs(blob));
@ -3462,27 +3471,31 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
T.assert( len ? !!blob : !blob, T.assert( len ? !!blob : !blob,
"Expecting len=non-0/blob=non-null or len=0/blob=null. "+ "Expecting len=non-0/blob=non-null or len=0/blob=null. "+
"Got len="+len+" blob=@"+blob ); "Got len="+len+" blob=@"+blob );
T.assert( type === wasm.peek32(pType),
"Expecting value_blob_v2 type "+type+" but got "
+wasm.peek32(pType)+". Value="+wasm.cstrToJs(blob));
for( let i = 0; i < len; ++i ){ for( let i = 0; i < len; ++i ){
T.assert( byteList[i] === wasm.peek8(blob+i), T.assert( byteList[i] === wasm.peek8(blob+i),
"mismatch at offset "+i+": "+byteList[i] "mismatch at offset "+i+": "+byteList[i]
+"!=="+wasm.peek8(blob+i) ); +"!=="+wasm.peek8(blob+i) );
} }
}; };
const cmp2 = (byteList)=>{ const cmp2 = (type,byteList)=>{
next(); next();
cmp(byteList); cmp(type,byteList);
wasm.pokePtr(ppOut, 0); clearPtrs();
wasm.poke32(pnOut, 0); const rc = capi.sqlite3_column_blob_v2(q, 1, ppOut, pnOut, pType);
const rc = capi.sqlite3_column_blob_v2(q, 1, ppOut, pnOut); T.assert( 0==rc, "expecting column_blob_v2() rc 0 but got "+rc);
T.assert( 0==rc, "expecting column_blob_v2() rc 0 but got "+rc ); cmp(type,byteList);
cmp(byteList);
}; };
cmp2([49,50,51]); // 123 cmp2(capi.SQLITE_INTEGER, [49,50,51]); // 123
cmp2([]); // null cmp2(capi.SQLITE_NULL, []); // null
cmp2([104,105]); // "hi" cmp2(capi.SQLITE_TEXT, [104,105]); // "hi"
cmp2([0x23, 0, 0x2a]); // X'23002A' cmp2(capi.SQLITE_BLOB, [0x23, 0, 0x2a]); // X'23002A'
cmp2([]); // empty blobs are null cmp2(capi.SQLITE_TEXT, []) /* length-0 non-NULL blobs are NULL
but this one has type TEXT */;
/** Tests which cover the same code paths for both text_v2 and /** Tests which cover the same code paths for both text_v2 and
blob_v2 are in the previous test group. */ blob_v2 are in the previous test group. */

View File

@ -1,5 +1,5 @@
C Simplify\sthe\scolumn_text/blob_v2()\sJS\stests\sa\sbit\sand\scorrect\sthe\stext_v2()\stests\sto\scall\sinto\sboth\sthe\scolumn\sand\svalue\svariants. C Experimentally\sadd\sanother\soutput\spointer\sto\sthe\stext/blob_v2()\sfamily\swhich\sgets\sthe\ssqlite3_value_type()\sassigned\sto\sit\sif\sit's\snot\sNULL,\sbased\son\sfeedback\sin\sthe\sforum.
D 2025-07-01T14:44:12.721 D 2025-07-01T16:38:58.203
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@ -640,7 +640,7 @@ F ext/wasm/api/post-js-footer.js 365405929f41ca0e6d389ed8a8da3f3c93e11d3ef43a90a
F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea5f0699ff2acb0a701 F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea5f0699ff2acb0a701
F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb F ext/wasm/api/pre-js.c-pp.js a614a2c82b12c4d96d8e3ba77330329efc53c4d56a8a7e60ade900f341866cfb
F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359 F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359
F ext/wasm/api/sqlite3-api-glue.c-pp.js 0394eda4f8dc499d6fb77743a5d307d786991e599a552bdd5bc9e4b92e6f4ab1 F ext/wasm/api/sqlite3-api-glue.c-pp.js 2df4571b131726b1d9333d2ec8c8ce05d5b0872dad5ed08969791107d3b1616f
F ext/wasm/api/sqlite3-api-oo1.c-pp.js c68d6da0088c2527156fca9163a721abe08e7bd077b15404fd8d292f4612adc1 F ext/wasm/api/sqlite3-api-oo1.c-pp.js c68d6da0088c2527156fca9163a721abe08e7bd077b15404fd8d292f4612adc1
F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4 F ext/wasm/api/sqlite3-api-prologue.js 8708570165f5b4bce9a78ccd91bc9ddf8735970ac1c4d659e36c9a7d9a644bb4
F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644f23e64b126e7ae113570587c0ab
@ -698,7 +698,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
F ext/wasm/tester1.c-pp.js 24ae5f3220ea4cac492e5e9ca28984b85a40560d20e313cdd5a037f9d53e72c7 F ext/wasm/tester1.c-pp.js be5aa80c98aae290fa9bd0296358f978ef0b9ff25b0106d3f96cc4cc3c5128b9
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@ -787,10 +787,10 @@ F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482
F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6 F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6
F src/sqlite.h.in e09d0e3eed4815f1884c6fa93edcf0c64346fec0a3b06f1e6c3a5c5784ec1933 F src/sqlite.h.in b8acddc332b0ba20f7e46ada5e99156303ec7470ecafcda4dbc59285e4658bab
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e
F src/sqliteInt.h 461d39b85ee97d8f1496388f5d6884e8a240cabaea26b915ac7fd59e7a2ef727 F src/sqliteInt.h 21c089759415895c86220d35c22cd17fdc6ca27653e1ec0c744d1e6808d0545a
F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b
F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@ -855,10 +855,10 @@ F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789
F src/vdbe.c 7e29623ca387880b8893e69135a0ff240c3dcaf0710f7a46a5f95b062cf93883 F src/vdbe.c 7e29623ca387880b8893e69135a0ff240c3dcaf0710f7a46a5f95b062cf93883
F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958 F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958
F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e
F src/vdbeapi.c 428f811d1521ea155a8f2a3c0d5de7e6cace5aafc04845415976ee4a15e65ba7 F src/vdbeapi.c 4109e9afb11b468eadab6c5b78c3d1ae213f5fa2112ddff925c2972ee5a8f276
F src/vdbeaux.c fd2c6b19a8892c31a2adc719f156f313560f9cc490cdbd04ff08fdae5d7aedb7 F src/vdbeaux.c fd2c6b19a8892c31a2adc719f156f313560f9cc490cdbd04ff08fdae5d7aedb7
F src/vdbeblob.c b1b4032cac46b41e44b957c4d00aee9851f862dfd85ecb68116ba49884b03dfd F src/vdbeblob.c b1b4032cac46b41e44b957c4d00aee9851f862dfd85ecb68116ba49884b03dfd
F src/vdbemem.c 4c4878f6b691650a484f8046015d9b4653a904113d90b1da5f019a8819eee5de F src/vdbemem.c 08633d0ac68585c83176bc9f336424d9e97fcb50827f71b3bce9746ad6950a56
F src/vdbesort.c cb6f472e83ca12c46aa7de0ac0a9d11458b357986f2617a1c90dfb19a542ecbe F src/vdbesort.c cb6f472e83ca12c46aa7de0ac0a9d11458b357986f2617a1c90dfb19a542ecbe
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 1d065231aba8080ffd024497ad858eed22ece45fe82a749494a3efaa10f91389 P d5cb8080434bc13616d70aac516762ca8be622bf51a07f8c36d8657c410e03ce
R b36585780d88d89f92de02fb68417b16 R 76b92a6732359cdd07f9c1558852eff8
U stephan U stephan
Z a2d72b2958071e327f891d9e6a52fba4 Z 59582194fce1a262d6667c3ee644c001
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
d5cb8080434bc13616d70aac516762ca8be622bf51a07f8c36d8657c410e03ce 4aab781d2abc64a39c53acd0faf6d60bb38afcce42f25bc8c0fa52b73df05312

View File

@ -5465,12 +5465,12 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
** other SQLite interface is called on the same [database connection]. ** other SQLite interface is called on the same [database connection].
*/ */
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_blob_v2(sqlite3_stmt*, int iCol, const void **, int*); int sqlite3_column_blob_v2(sqlite3_stmt*, int iCol, const void **, int*, int*);
double sqlite3_column_double(sqlite3_stmt*, int iCol); double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol); int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(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*); int sqlite3_column_text_v2(sqlite3_stmt*, int iCol, const unsigned char **, int*, int*);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol); int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
@ -5980,13 +5980,13 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
** other SQLite interface is called on the same [database connection]. ** other SQLite interface is called on the same [database connection].
*/ */
const void *sqlite3_value_blob(sqlite3_value*); const void *sqlite3_value_blob(sqlite3_value*);
int sqlite3_value_blob_v2(sqlite3_value*, const void **, int*); int sqlite3_value_blob_v2(sqlite3_value*, const void **, int*, int*);
double sqlite3_value_double(sqlite3_value*); double sqlite3_value_double(sqlite3_value*);
int sqlite3_value_int(sqlite3_value*); int sqlite3_value_int(sqlite3_value*);
sqlite3_int64 sqlite3_value_int64(sqlite3_value*); sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
void *sqlite3_value_pointer(sqlite3_value*, const char*); void *sqlite3_value_pointer(sqlite3_value*, const char*);
const unsigned char *sqlite3_value_text(sqlite3_value*); const unsigned char *sqlite3_value_text(sqlite3_value*);
int sqlite3_value_text_v2(sqlite3_value*, const unsigned char **, int*); int sqlite3_value_text_v2(sqlite3_value*, const unsigned char **, int*, int*);
const void *sqlite3_value_text16(sqlite3_value*); const void *sqlite3_value_text16(sqlite3_value*);
const void *sqlite3_value_text16le(sqlite3_value*); const void *sqlite3_value_text16le(sqlite3_value*);
const void *sqlite3_value_text16be(sqlite3_value*); const void *sqlite3_value_text16be(sqlite3_value*);

View File

@ -5399,7 +5399,7 @@ void sqlite3FileSuffix3(const char*, char*);
u8 sqlite3GetBoolean(const char *z,u8); u8 sqlite3GetBoolean(const char *z,u8);
const void *sqlite3ValueText(sqlite3_value*, u8); const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueTextV2(sqlite3_value*, u8, const void **, int*); int sqlite3ValueTextV2(sqlite3_value*, u8, const void **, int*, int*);
int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*)); int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*));
int sqlite3ValueBytes(sqlite3_value*, u8); int sqlite3ValueBytes(sqlite3_value*, u8);

View File

@ -192,7 +192,7 @@ const void *sqlite3_value_blob(sqlite3_value *pVal){
} }
} }
int sqlite3_value_blob_v2(sqlite3_value *pVal, const void **pOut, int sqlite3_value_blob_v2(sqlite3_value *pVal, const void **pOut,
int *pnOut){ int *pnOut, int *pType){
Mem *p = (Mem*)pVal; Mem *p = (Mem*)pVal;
#ifdef SQLITE_ENABLE_API_ARMOR #ifdef SQLITE_ENABLE_API_ARMOR
if( pVal==0 || pOut==0 ){ if( pVal==0 || pOut==0 ){
@ -207,10 +207,11 @@ int sqlite3_value_blob_v2(sqlite3_value *pVal, const void **pOut,
p->flags |= MEM_Blob; p->flags |= MEM_Blob;
*pOut = p->n ? p->z : 0; *pOut = p->n ? p->z : 0;
if( pnOut ) *pnOut = p->n; if( pnOut ) *pnOut = p->n;
if( pType ) *pType = sqlite3_value_type(pVal);
return 0; return 0;
}else{ }else{
return sqlite3_value_text_v2(pVal, (const unsigned char **)pOut, return sqlite3_value_text_v2(pVal, (const unsigned char **)pOut,
pnOut); pnOut, pType);
} }
} }
int sqlite3_value_bytes(sqlite3_value *pVal){ int sqlite3_value_bytes(sqlite3_value *pVal){
@ -250,15 +251,12 @@ const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
} }
int sqlite3_value_text_v2(sqlite3_value *pVal, int sqlite3_value_text_v2(sqlite3_value *pVal,
const unsigned char **pOut, const unsigned char **pOut,
int *pnOut){ int *pnOut, int *pType){
int n = 0; int n = 0;
#ifdef SQLITE_ENABLE_API_ARMOR return (pVal && pOut)
if( pOut==0 ){ ? sqlite3ValueTextV2(pVal, SQLITE_UTF8, (const void **)pOut,
return SQLITE_MISUSE_BKPT; pnOut ? pnOut : &n, pType)
} : SQLITE_MISUSE_BKPT;
#endif
return sqlite3ValueTextV2(pVal, SQLITE_UTF8, (const void **)pOut,
pnOut ? pnOut : &n);
} }
#ifndef SQLITE_OMIT_UTF16 #ifndef SQLITE_OMIT_UTF16
const void *sqlite3_value_text16(sqlite3_value* pVal){ const void *sqlite3_value_text16(sqlite3_value* pVal){
@ -1384,7 +1382,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
** not call columnMallocFailure() to avoid calling sqlite3ApiExit(). ** not call columnMallocFailure() to avoid calling sqlite3ApiExit().
*/ */
static int columnMemV2(sqlite3_stmt *pStmt, int iCol, int bBlob, static int columnMemV2(sqlite3_stmt *pStmt, int iCol, int bBlob,
const void **pOut, int * pnOut){ const void **pOut, int * pnOut, int *pType){
int rc = 0; int rc = 0;
Vdbe * const pVm = (Vdbe*)pStmt; Vdbe * const pVm = (Vdbe*)pStmt;
@ -1394,9 +1392,9 @@ static int columnMemV2(sqlite3_stmt *pStmt, int iCol, int bBlob,
if( pVm->pResultRow!=0 && iCol<pVm->nResColumn && iCol>=0 ){ if( pVm->pResultRow!=0 && iCol<pVm->nResColumn && iCol>=0 ){
Mem * const pMem = &pVm->pResultRow[iCol]; Mem * const pMem = &pVm->pResultRow[iCol];
rc = bBlob rc = bBlob
? sqlite3_value_blob_v2(pMem, pOut, pnOut) ? sqlite3_value_blob_v2(pMem, pOut, pnOut, pType)
: sqlite3_value_text_v2(pMem, (const unsigned char **)pOut, : sqlite3_value_text_v2(pMem, (const unsigned char **)pOut,
pnOut); pnOut, pType);
}else{ }else{
rc = pVm->pResultRow==0 ? SQLITE_MISUSE_BKPT : SQLITE_RANGE; rc = pVm->pResultRow==0 ? SQLITE_MISUSE_BKPT : SQLITE_RANGE;
} }
@ -1453,8 +1451,8 @@ const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
return val; return val;
} }
int sqlite3_column_blob_v2(sqlite3_stmt *pStmt, int iCol, int sqlite3_column_blob_v2(sqlite3_stmt *pStmt, int iCol,
const void **pOut, int *pnOut){ const void **pOut, int *pnOut, int *pType){
return columnMemV2(pStmt, iCol, 1, pOut, pnOut); return columnMemV2(pStmt, iCol, 1, pOut, pnOut, pType);
} }
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_bytes( columnMem(pStmt,i) ); int val = sqlite3_value_bytes( columnMem(pStmt,i) );
@ -1487,9 +1485,9 @@ const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
return val; return val;
} }
int sqlite3_column_text_v2(sqlite3_stmt *pStmt, int iCol, int sqlite3_column_text_v2(sqlite3_stmt *pStmt, int iCol,
const unsigned char **pOut, const unsigned char **pOut, int *pnOut,
int *pnOut){ int *pType){
return columnMemV2(pStmt, iCol, 0, (const void **)pOut, pnOut); return columnMemV2(pStmt, iCol, 0, (const void **)pOut, pnOut, pType);
} }
sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
Mem *pOut = columnMem(pStmt, i); Mem *pOut = columnMem(pStmt, i);

View File

@ -1360,12 +1360,19 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
** This works like valueToText() but returns its result using ** This works like valueToText() but returns its result using
** different semantics. On success, return 0, set *pOut to a ** different semantics. On success, return 0, set *pOut to a
** zero-terminated version of that string, and set *pnOut (which must ** zero-terminated version of that string, and set *pnOut (which must
** not be NULL, to avoid an extra branch in this function) to the ** not be NULL to the string-length of that memory. If pType is not
** string-length of that memory. On error, return non-0 and do not ** NULL, it will be set to the sqlite3_value_type() of pVal.
** modify pOut or pnOut. **
** On error, return non-0 and do not modify pOut, pnOut, or pType.
**
** 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, static SQLITE_NOINLINE int valueToTextV2(sqlite3_value* pVal, u8 enc,
const void **pOut, int *pnOut){ const void **pOut, int *pnOut,
int *pType){
assert( pVal!=0 ); assert( pVal!=0 );
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
@ -1405,6 +1412,7 @@ static SQLITE_NOINLINE int valueToTextV2(sqlite3_value* pVal, u8 enc,
assert( sqlite3VdbeMemValidStrRep(pVal) ); assert( sqlite3VdbeMemValidStrRep(pVal) );
*pOut = pVal->z; *pOut = pVal->z;
*pnOut = pVal->n; *pnOut = pVal->n;
if( pType ) *pType = sqlite3_value_type(pVal);
return 0; return 0;
} }
return (pVal->db && pVal->db->mallocFailed) return (pVal->db && pVal->db->mallocFailed)
@ -1442,17 +1450,17 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
** **
** On success, returns 0, sets *pOut to the underlying value (or NULL ** 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 ** in the case of NULL), and sets *pnOut to the memory's usable
** length. On error, neither *pOut nor *pnOut are modified. ** length. If *pType is not NULL, it is set to the
** sqlite3_value_type() of pVal. On error, neither *pOut nor *pnOut
** nor *pType are modified.
** **
** Design note: pnOut must not be NULL to avoid an extra branch in ** Results are undefined if pVal, pOut, or pnOut are NULL. pType may
** this function. It is thought (but is untested) that such a branch ** be NULL.
** would be more expensive than ensuring that pnOut is not NULL
** will. Public APIs wrapping this may optionally accept a NULL pnOut,
** but must not pass that NULL on to here.
*/ */
int sqlite3ValueTextV2(sqlite3_value* pVal, u8 enc, int sqlite3ValueTextV2(sqlite3_value* pVal, u8 enc, const void **pOut,
const void **pOut, int *pnOut){ int *pnOut, int *pType){
if( !pVal ) return SQLITE_MISUSE_BKPT; /*if( !pVal ) return SQLITE_MISUSE_BKPT;*/
assert( pVal!=0 );
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
assert( !sqlite3VdbeMemIsRowSet(pVal) ); assert( !sqlite3VdbeMemIsRowSet(pVal) );
@ -1462,14 +1470,16 @@ int sqlite3ValueTextV2(sqlite3_value* pVal, u8 enc,
assert( sqlite3VdbeMemValidStrRep(pVal) ); assert( sqlite3VdbeMemValidStrRep(pVal) );
*pOut = pVal->z; *pOut = pVal->z;
*pnOut = pVal->n; *pnOut = pVal->n;
if( pType ) *pType = sqlite3_value_type( pVal );
return 0; return 0;
} }
if( pVal->flags&MEM_Null ){ if( pVal->flags&MEM_Null ){
*pOut = 0; *pOut = 0;
*pnOut = 0; *pnOut = 0;
if( pType ) *pType = sqlite3_value_type( pVal );
return 0; return 0;
} }
return valueToTextV2(pVal, enc, pOut, pnOut); return valueToTextV2(pVal, enc, pOut, pnOut, pType);
} }
/* Return true if sqlit3_value object pVal is a string or blob value /* Return true if sqlit3_value object pVal is a string or blob value