From: stephan Date: Thu, 8 Dec 2022 10:06:07 +0000 (+0000) Subject: More work on the JS vtable tests. X-Git-Tag: version-3.41.0~291^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fwasm-vtab;p=thirdparty%2Fsqlite.git More work on the JS vtable tests. FossilOrigin-Name: 51e3c3b569dce2097063d39dc484f44b2f98cad0a902ef66765ca4cdc3e06f47 --- diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index 96234bca3a..0262375ace 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -1021,7 +1021,11 @@ sqlite3_vfs * sqlite3_wasm_db_vfs(sqlite3 *pDb, const char *zDbName){ ** ** This function resets the given db pointer's database as described at ** -** https://www.sqlite.org/c3ref/c_dbconfig_defensive.html#sqlitedbconfigresetdatabase +** https://sqlite.org/c3ref/c_dbconfig_defensive.html#sqlitedbconfigresetdatabase +** +** But beware: virtual tables destroyed that way do not have their +** xDestroy() called, so will leak if they require that function for +** proper cleanup. ** ** Returns 0 on success, an SQLITE_xxx code on error. Returns ** SQLITE_MISUSE if pDb is NULL. @@ -1030,6 +1034,7 @@ SQLITE_WASM_KEEP int sqlite3_wasm_db_reset(sqlite3 *pDb){ int rc = SQLITE_MISUSE; if( pDb ){ + sqlite3_table_column_metadata(pDb, "main", 0, 0, 0, 0, 0, 0, 0); rc = sqlite3_db_config(pDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); if( 0==rc ){ rc = sqlite3_exec(pDb, "VACUUM", 0, 0, 0); diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 65ef5f6098..61531cf87f 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -998,14 +998,27 @@ self.sqlite3InitModule = sqlite3InitModule; wasm.sqlite3_wasm_vfs_unlink(0, dbFile); const db = this.db = new sqlite3.oo1.DB(dbFile, 0 ? 'ct' : 'c'); db.onclose = { - disposeThese: [], - before: (db)=>{ + disposeAfter: [], + disposeBefore: [], + before: function(db){ + while(this.disposeBefore.length){ + const v = this.disposeBefore.shift(); + console.debug("db.onclose.before cleaning up:",v); + if(wasm.isPtr(v)) wasm.dealloc(v); + else if(v instanceof sqlite3.StructBinder.StructType){ + v.dispose(); + }else if(v instanceof Function){ + try{ v(db) } catch(e){ + console.warn("beforeDispose() callback threw:",e); + } + } + } console.debug("db.onclose.before dropping modules"); - sqlite3.capi.sqlite3_drop_modules(db, 0); + sqlite3.capi.sqlite3_drop_modules(db.pointer, 0); }, after: function(){ - while(this.disposeThese.length){ - const v = this.disposeThese.shift(); + while(this.disposeAfter.length){ + const v = this.disposeAfter.shift(); console.debug("db.onclose.after cleaning up:",v); if(wasm.isPtr(v)) wasm.dealloc(v); else if(v instanceof sqlite3.StructBinder.StructType){ @@ -1847,7 +1860,7 @@ self.sqlite3InitModule = sqlite3InitModule; const tmplMod = new sqlite3.capi.sqlite3_module(); tmplMod.$iVersion = 0; - this.db.onclose.disposeThese.push(tmplMod); + this.db.onclose.disposeAfter.push(tmplMod); vth.installMethods(tmplMod, tmplMethods, true); if(tmplMethods.xCreate){ T.assert(tmplMod.$xCreate) @@ -1867,7 +1880,7 @@ self.sqlite3InitModule = sqlite3InitModule; ); T.assert(10===list.length) .assert(1000===list[0][0]) - .assert(2009===list[list.length-1][1]) + .assert(2009===list[list.length-1][1]); } })/*custom vtab #1*/ @@ -1890,20 +1903,16 @@ self.sqlite3InitModule = sqlite3InitModule; always translates errors from a vtable to a generic SQLITE_ERROR unless it's from xConnect()/xCreate() and that callback sets an error string. */; + const vtabTrace = 1 + ? ()=>{} + : (methodName,...args)=>console.debug('sqlite3_module::'+methodName+'():',...args); const modConfig = { /* catchExceptions changes how the methods are wrapped */ catchExceptions: true, name: "vtab2test", methods:{ - xConnect: function(pDb, pAux, argc, argv, ppVtab, pzErr){ - console.debug("xConnect(",...arguments,")"); - const t = vth.xVtab(); - wasm.setPtrValue(ppVtab, t.pointer); - T.assert(t === vth.xVtab(wasm.getPtrValue(ppVtab))); - console.debug("xConnect(",...arguments,") ppVtab =",t.pointer); - }, xCreate: function(pDb, pAux, argc, argv, ppVtab, pzErr){ - console.debug("xCreate(",...arguments,")"); + vtabTrace("xCreate",...arguments); if(throwOnCreate){ sqlite3.SQLite3Error.toss( throwOnCreate, @@ -1911,7 +1920,7 @@ self.sqlite3InitModule = sqlite3InitModule; ); } const args = wasm.cArgvToJs(argc, argv); - console.debug("xCreate/xConnect args:",args); + vtabTrace("xCreate","argv:",args); T.assert(args.length>=3); const rc = capi.sqlite3_declare_vtab( pDb, "CREATE TABLE ignored(a,b)" @@ -1920,40 +1929,51 @@ self.sqlite3InitModule = sqlite3InitModule; const t = vth.xVtab(); wasm.setPtrValue(ppVtab, t.pointer); T.assert(t === vth.xVtab(wasm.getPtrValue(ppVtab))); - console.debug("xCreate(",...arguments,") ppVtab =",t.pointer); + vtabTrace("xCreate",...arguments," ppVtab =",t.pointer); } return rc; }, - xDisconnect: function(pVtab){ - console.debug("sqlite3_module::xDisconnect(",pVtab,")"); + xDestroy: function(pVtab){ + vtabTrace("sqlite3_xDestroy",pVtab); const t = vth.xVtab(pVtab, true); T.assert(t); t.dispose(); }, - xDestroy: function(pVtab){ - console.debug("sqlite3_module::xDestroy(",pVtab,")"); + /*xConnect: function(pDb, pAux, argc, argv, ppVtab, pzErr){ + vtabTrace("xConnect",...arguments); + const t = vth.xVtab(); + wasm.setPtrValue(ppVtab, t.pointer); + T.assert(t === vth.xVtab(wasm.getPtrValue(ppVtab))); + vtabTrace("xConnect",...arguments,"ppVtab =",t.pointer); + }, + xDisconnect: function(pVtab){ + vtabTrace("xDisconnect",pVtab); const t = vth.xVtab(pVtab, true); T.assert(t); t.dispose(); - }, + },*/ xOpen: function(pVtab, ppCursor){ const t = vth.xVtab(pVtab), c = vth.xCursor(); T.assert(t instanceof capi.sqlite3_vtab) .assert(c instanceof capi.sqlite3_vtab_cursor); wasm.setPtrValue(ppCursor, c.pointer); + vtabTrace("xOpen",...arguments," cursor =",c.pointer); c._rowId = 0; }, xClose: function(pCursor){ + vtabTrace("xClose",...arguments); const c = vth.xCursor(pCursor,true); T.assert(c instanceof capi.sqlite3_vtab_cursor) .assert(!vth.xCursor(pCursor)); c.dispose(); }, xNext: function(pCursor){ + vtabTrace("xNext",...arguments); const c = vth.xCursor(pCursor); ++c._rowId; }, xColumn: function(pCursor, pCtx, iCol){ + vtabTrace("xColumn",...arguments); const c = vth.xCursor(pCursor); switch(iCol){ case tmplCols.A: @@ -1966,22 +1986,24 @@ self.sqlite3InitModule = sqlite3InitModule; } }, xRowid: function(pCursor, ppRowid64){ + vtabTrace("xRowid",...arguments); const c = vth.xCursor(pCursor); vth.xRowid(ppRowid64, c._rowId); }, xEof: function(pCursor){ - const c = vth.xCursor(pCursor), - rc = c._rowId>=10; - return rc; + vtabTrace("xEof",...arguments); + return vth.xCursor(pCursor)._rowId>=10; }, xFilter: function(pCursor, idxNum, idxCStr, argc, argv/* [sqlite3_value* ...] */){ + vtabTrace("xFilter",...arguments); const c = vth.xCursor(pCursor); c._rowId = 0; const list = vth.sqlite3ValuesToJs(argc, argv); T.assert(argc === list.length); }, xBestIndex: function(pVtab, pIdxInfo){ + vtabTrace("xBestIndex",...arguments); //const t = vth.xVtab(pVtab); const pii = vth.xIndexInfo(pIdxInfo); pii.$estimatedRows = 10; @@ -1993,32 +2015,50 @@ self.sqlite3InitModule = sqlite3InitModule; const tmplMod = vth.setupModule(modConfig); T.assert(tmplMod instanceof capi.sqlite3_module) .assert(1===tmplMod.$iVersion); - this.db.onclose.disposeThese.push(tmplMod); + this.db.onclose.disposeAfter.push(tmplMod); this.db.checkRc(capi.sqlite3_create_module( this.db.pointer, modConfig.name, tmplMod.pointer, 0 )); this.db.exec([ "create virtual table testvtab2 using ", modConfig.name, - "(arg1, arg2)" + "(arg1 blah, arg2 bloop)" ]); - const list = this.db.selectArrays( - ["SELECT a,b FROM", - " testvtab2", - " where a<9999 and b>1 order by a, b" - ]/* Query is shaped so that it will ensure that some - constraints end up in xBestIndex(). */ + this.db.onclose.disposeBefore.push(function(db){ + console.debug("testvtab2 disposeBefore handler..."); + db.exec( + /** + DROP TABLE is the only way to get xDestroy() to be called. + If we DROP TABLE at the end of the containing + test function, xDestroy() is called. If we instead + delay it until db.onclose.before(), we're getting + "no such table"? + */ + "DROP TABLE testvtab2" + ); + }); + let list = this.db.selectArrays( + "SELECT a,b FROM testvtab2 where a<9999 and b>1 order by a, b" + /* Query is shaped so that it will ensure that some + constraints end up in xBestIndex(). */ ); T.assert(10===list.length) .assert(1000===list[0][0]) - .assert(2009===list[list.length-1][1]) + .assert(2009===list[list.length-1][1]); + + list = this.db.selectArrays( + "SELECT a,b FROM testvtab2 where a<9999 and b>1 order by b, a limit 5" + ); + T.assert(5===list.length) + .assert(1000===list[0][0]) + .assert(2004===list[list.length-1][1]); } })/*custom vtab #2*/ //////////////////////////////////////////////////////////////////////// .t('Close db', function(){ T.assert(this.db).assert(wasm.isPtr(this.db.pointer)); - wasm.sqlite3_wasm_db_reset(this.db); + //wasm.sqlite3_wasm_db_reset(this.db); // will leak virtual tables! this.db.close(); T.assert(!this.db.pointer); }) diff --git a/manifest b/manifest index 5a4e5ff7ad..05d0489812 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Got\sJS\snon-eponymous\svtable\sworking\sthanks\sto\sa\shint\sfrom\sDan. -D 2022-12-08T09:06:20.756 +C More\swork\son\sthe\sJS\svtable\stests. +D 2022-12-08T10:06:07.508 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -512,7 +512,7 @@ F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c F ext/wasm/api/sqlite3-v-helper.js ec03a222ad3551764626f14f38de1b1081bda509e098849502b498c041993a0f F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 8ec510fee735c646fb18a3b99f0ca5ca461f9e066c43cdc404d7144f12ae6ed6 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 723522a6c2a2463884a83fa1cc7ae5770deaaf0856a1058cc1023b2bfa1c898b +F ext/wasm/api/sqlite3-wasm.c 97034ab4f40ec1fac71ccfaf3afffdca6b1ea2dcd95b7871527bad0f34e152b0 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406 -F ext/wasm/tester1.c-pp.js 7e3cd6cbad34f44800b2ee3e03d12aa064c598156ee779cf5d5c562156ed83f5 +F ext/wasm/tester1.c-pp.js ecd0ecd6c9f0c5bce7f39a3ccb28151c7ae7b1042379a0c855e930661579f2e8 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0ee495452c014680697aa9035c245024df127a52d1820ab0e02580a015d96ecb -R 09bfd5e1d5efadd7221593e29be578f6 +P 750719b4981df62fa2ff3665e6f559ec760609ad2493495628295ad9ae6024fc +R a667c38f5946f2c41a0c069302850ad8 U stephan -Z 6e67580aa5c332587f0481ad10406d76 +Z d2bb94e965d8f50e0296d40f52f07644 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 49f8a85350..e9d0fed4dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -750719b4981df62fa2ff3665e6f559ec760609ad2493495628295ad9ae6024fc \ No newline at end of file +51e3c3b569dce2097063d39dc484f44b2f98cad0a902ef66765ca4cdc3e06f47 \ No newline at end of file