Merge trunk enhancements into the json-opt branch.
FossilOrigin-Name: 5739a16ad270a5aadcbb46b28c34fa6ba975422788dcbccb1a8e0d1e6ed75144
This commit is contained in:
commit
95daf355a7
@ -451,6 +451,13 @@ emcc.exportedRuntimeMethods := \
|
||||
emcc.jsflags += $(emcc.exportedRuntimeMethods)
|
||||
emcc.jsflags += -sUSE_CLOSURE_COMPILER=0
|
||||
emcc.jsflags += -sIMPORTED_MEMORY
|
||||
#emcc.jsflags += -sASYNCIFY=2
|
||||
# ^^^ ASYNCIFY=2 is for experimental JSPI support
|
||||
# (https://v8.dev/blog/jspi), but enabling it causes the lib-level
|
||||
# init code to throw inexplicable complaints about C-level function
|
||||
# signatures not matching what we expect them to be. JSPI requires, as of
|
||||
# this writing, requires an experimental Chrome flag:
|
||||
# chrome://flags/#enable-experimental-webassembly-stack-switching
|
||||
emcc.jsflags += -sSTRICT_JS=0
|
||||
# STRICT_JS disabled due to:
|
||||
# https://github.com/emscripten-core/emscripten/issues/18610
|
||||
@ -678,13 +685,13 @@ sqlite3-wasmfs.cfiles := $(sqlite3-wasm.cfiles)
|
||||
# Upstream RFE:
|
||||
# https://github.com/emscripten-core/emscripten/issues/18237
|
||||
#
|
||||
# Maintenance reminder: Mac sed -i works differently than GNU sed, so
|
||||
# don't use that flag here.
|
||||
# Maintenance reminder: Mac sed works differently than GNU sed, so
|
||||
# don't use sed for this.
|
||||
define SQLITE3.xJS.ESM-EXPORT-DEFAULT
|
||||
if [ x1 = x$(1) ]; then \
|
||||
echo "Fragile workaround for emscripten/issues/18237. See SQLITE3.xJS.RECIPE."; \
|
||||
{\
|
||||
sed -e '0,/^export default/{/^export default/d;}' $@ > $@.tmp && mv $@.tmp $@; \
|
||||
awk '/^export default/ && !f{f=1; next} 1' $@ > $@.tmp && mv $@.tmp $@; \
|
||||
} || exit $$?; \
|
||||
if [ x != x$(2) ]; then \
|
||||
if ! grep -q '^export default' $@; then \
|
||||
@ -863,7 +870,7 @@ clean-batch:
|
||||
# a regular basis with different -Ox flags and rebuilding the batch
|
||||
# pieces each time is an unnecessary time sink.
|
||||
batch: batch-runner.list
|
||||
all: batch
|
||||
#all: batch
|
||||
# end batch-runner.js
|
||||
########################################################################
|
||||
# Wasmified speedtest1 is our primary benchmarking tool.
|
||||
|
@ -22,7 +22,9 @@ if('undefined' !== typeof Module){ // presumably an Emscripten build
|
||||
*/
|
||||
const SABC = Object.assign(
|
||||
Object.create(null), {
|
||||
exports: Module['asm'],
|
||||
exports: ('undefined'===typeof wasmExports)
|
||||
? Module['asm']/* emscripten <=3.1.43 */
|
||||
: wasmExports /* emscripten >=3.1.44 */,
|
||||
memory: Module.wasmMemory /* gets set if built with -sIMPORTED_MEMORY */
|
||||
},
|
||||
globalThis.sqlite3ApiConfig || {}
|
||||
|
@ -728,6 +728,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
Populate api object with sqlite3_...() by binding the "raw" wasm
|
||||
exports into type-converting proxies using wasm.xWrap().
|
||||
*/
|
||||
if(0 === wasm.exports.sqlite3_step.length){
|
||||
/* This environment wraps exports in nullary functions, which means
|
||||
we must disable the arg-count validation we otherwise perform
|
||||
on the wrappers. */
|
||||
wasm.xWrap.doArgcCheck = false;
|
||||
sqlite3.config.warn(
|
||||
"Disabling sqlite3.wasm.xWrap.doArgcCheck due to environmental quirks."
|
||||
);
|
||||
}
|
||||
for(const e of wasm.bindingSignatures){
|
||||
capi[e[0]] = wasm.xWrap.apply(null, e);
|
||||
}
|
||||
|
@ -501,6 +501,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
/* Current number of in-use files from pool. */
|
||||
getFileCount(){return this.#mapFilenameToSAH.size}
|
||||
|
||||
/* Returns an array of the names of all
|
||||
currently-opened client-specified filenames. */
|
||||
getFileNames(){
|
||||
const rc = [];
|
||||
const iter = this.#mapFilenameToSAH.keys();
|
||||
for(const n of iter) rc.push(n);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// #createFileObject(sah,clientName,opaqueName){
|
||||
// const f = Object.assign(Object.create(null),{
|
||||
// clientName, opaqueName
|
||||
@ -901,6 +910,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
getCapacity(){ return this.#p.getCapacity(this.#p) }
|
||||
|
||||
getFileCount(){ return this.#p.getFileCount() }
|
||||
getFileNames(){ return this.#p.getFileNames() }
|
||||
|
||||
async reserveMinimumCapacity(min){
|
||||
const c = this.#p.getCapacity();
|
||||
@ -1059,6 +1069,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
Returns the number of files from the pool currently allocated to
|
||||
slots. This is not the same as the files being "opened".
|
||||
|
||||
- array getFileNames()
|
||||
|
||||
Returns an array of the names of the files currently allocated to
|
||||
slots. This list is the same length as getFileCount().
|
||||
|
||||
- void importDb(name, byteArray)
|
||||
|
||||
Imports the contents of an SQLite database, provided as a byte
|
||||
|
@ -111,7 +111,8 @@
|
||||
of `target.instance` (a WebAssembly.Module instance) and it must
|
||||
contain the symbols exported by the WASM module associated with
|
||||
this code. In an Enscripten environment it must be set to
|
||||
`Module['asm']`. The exports object must contain a minimum of the
|
||||
`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
|
||||
|
@ -107,7 +107,8 @@
|
||||
<li><a href='module-symbols.html'>module-symbols</a> gives
|
||||
a high-level overview of the symbols exposed by the JS
|
||||
module.</li>
|
||||
<li><a href='batch-runner.html'>batch-runner</a>: runs batches of SQL exported from speedtest1.</li>
|
||||
<!--li><a href='batch-runner.html'>batch-runner</a>: runs batches of
|
||||
SQL exported from speedtest1.</li-->
|
||||
<li><a href='test-opfs-vfs.html'>test-opfs-vfs</a>
|
||||
(<a href='test-opfs-vfs.html?opfs-sanity-check&opfs-verbose'>same
|
||||
with verbose output and sanity-checking tests</a>) is an
|
||||
|
@ -3072,10 +3072,23 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
db = new u2.OpfsSAHPoolDb(dbName);
|
||||
T.assert(1 === u1.getFileCount());
|
||||
db.close();
|
||||
T.assert(1 === u1.getFileCount())
|
||||
const fileNames = u1.getFileNames();
|
||||
T.assert(1 === fileNames.length)
|
||||
.assert(dbName === fileNames[0])
|
||||
.assert(1 === u1.getFileCount())
|
||||
.assert(true === u1.unlink(dbName))
|
||||
.assert(false === u1.unlink(dbName))
|
||||
.assert(0 === u1.getFileCount());
|
||||
.assert(0 === u1.getFileCount())
|
||||
.assert(0 === u1.getFileNames().length);
|
||||
|
||||
// Demonstrate that two SAH pools can coexist so long as
|
||||
// they have different names.
|
||||
const conf2 = JSON.parse(JSON.stringify(sahPoolConfig));
|
||||
conf2.name += '-test2';
|
||||
const POther = await inst(conf2);
|
||||
log("Installed second SAH instance as",conf2.name);
|
||||
T.assert(0 === POther.getFileCount())
|
||||
.assert(true === await POther.removeVfs());
|
||||
if(0){
|
||||
/* Enable this block to inspect vfs's contents via the dev
|
||||
console or OPFS Explorer browser extension. The
|
||||
@ -3087,7 +3100,6 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name));
|
||||
|
||||
let cErr, u3;
|
||||
const conf2 = JSON.parse(JSON.stringify(sahPoolConfig));
|
||||
conf2.$testThrowInInit = new Error("Testing throwing during init.");
|
||||
conf2.name = sahPoolConfig.name+'-err';
|
||||
const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e);
|
||||
|
30
manifest
30
manifest
@ -1,5 +1,5 @@
|
||||
C Change\sthe\sdebugging\s"json_parse(X)"\sfunction\sso\sthat\sit\sshows\sa\smore\ncomplete\sdescription\sof\sthe\sJsonParse\sobject\son\sstandard\soutput\sand\sreturns\nthe\smimified\sJSON.\s\sFormer\sbehavior\swas\sto\sreturn\sthe\stext\sof\sa\sdecode\nof\sthe\saNode\sarray.
|
||||
D 2023-07-26T13:17:43.116
|
||||
C Merge\strunk\senhancements\sinto\sthe\sjson-opt\sbranch.
|
||||
D 2023-07-27T18:19:46.300
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -482,7 +482,7 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||
F ext/wasm/GNUmakefile a3e316bf51d8915a49d4728e0d41f19ec4c3ead3409d1171989a4fe163ec2214
|
||||
F ext/wasm/GNUmakefile ddf1aede4275e404c7eda782462c33b6406fcd2dd327241f6b22c0f7b80938e4
|
||||
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
||||
F ext/wasm/README.md 0895244c0539ae68cf8c70d59c2de512532fd47cfba313268e2b672e6359112e
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab
|
||||
@ -494,15 +494,15 @@ F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e
|
||||
F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
|
||||
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
|
||||
F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js 23ceec5ef74a0e649b19694ca985fd89e335771e21f24f50df352a626a8c81bf
|
||||
F ext/wasm/api/sqlite3-api-glue.js f1b2dcb944de5138bb5bd9a1559d2e76a4f3ec25260963d709e8237476688803
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e
|
||||
F ext/wasm/api/sqlite3-api-glue.js cc6b0bb093bdb6279d4af259200b7b9e150e3796a8a3a4cd09a4928c43d25e56
|
||||
F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8
|
||||
F ext/wasm/api/sqlite3-api-prologue.js cbd7d6ba185f3a844a8b0020e954b49bbc2ca78b305d117bec2ceca21431795a
|
||||
F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
|
||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
|
||||
F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 7931b50b63246a3d6b46a4c703c28820aa10c5b1ae7c0718e1f58dae2cf6db85
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 44740935f6eeab3a0c6dc9f0ca93aebb6339f8d8365f03ea6d7808c134dbfe46
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js e7a690e0e78ff4d563f2eca468f91db69f001ff4b79c6d2304cbb6f62dca437d
|
||||
F ext/wasm/api/sqlite3-wasm.c 8867f1d41c112fb4a2cfe22ff224eccaf309fcdea266cee0ec554f85db72ef0f
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
|
||||
@ -513,7 +513,7 @@ F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25
|
||||
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
|
||||
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
|
||||
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
|
||||
F ext/wasm/common/whwasmutil.js ae263dec9d7384f4c530f324b99d00516a4d6f26424372daee65031e00eb49b3
|
||||
F ext/wasm/common/whwasmutil.js db6368ee57af90ee6691b6fb3ca97ee8064d12482e06a29113127c67b08f956e
|
||||
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
||||
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
||||
F ext/wasm/demo-123.js 38aa8faec4d0ace1c973bc8a7a1533584463ebeecd4c420daa7d9687beeb9cb5
|
||||
@ -531,7 +531,7 @@ F ext/wasm/fiddle/fiddle-worker.js 163d6139a93fab4bcb72064923df050d4e7c0ff0d8aa0
|
||||
F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715
|
||||
F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2
|
||||
F ext/wasm/index-dist.html 22379774f0ad4edcaaa8cf9c674c82e794cc557719a8addabed74eb8069d412e
|
||||
F ext/wasm/index.html b4e55de741be9fb7656445ea55085f703a784aebde620e1c4852fa21c1ac1c5b
|
||||
F ext/wasm/index.html 4e7847b909f4ae0da8c829b150b79454050e53b3658431f138636257729cd42b
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.md 37911f00db12cbcca73aa1ed72594430365f30aafae2fa9c886961de74e5e0eb
|
||||
F ext/wasm/module-symbols.html 841de62fc198988b8330e238c260e70ec93028b096e1a1234db31b187a899d10
|
||||
@ -549,7 +549,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
|
||||
F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
|
||||
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
|
||||
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
|
||||
F ext/wasm/tester1.c-pp.js f835c9f703b562142f23a3607fa4a34cb6aece5fb5d674ea5bd7d37b0e47e104
|
||||
F ext/wasm/tester1.c-pp.js b9a493a764f2113f6a8205d4e5573a25731d6f965338005460920389ac0693e0
|
||||
F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
|
||||
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
|
||||
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
||||
@ -598,7 +598,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
|
||||
F src/json.c 512bc389b42c68b34571ca532afb0f4bb235b1fc11ea5c9a4f6850c64fa12ab4
|
||||
F src/json.c c992d2a87a6888bf16a5c7270ef523eb838cf49e6643420c3cf917124f41f97f
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465
|
||||
F src/main.c 512b1d45bc556edf4471a845afb7ba79e64bd5b832ab222dc195c469534cd002
|
||||
@ -639,7 +639,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 37953a5f36c60bea413c3c04efcd433b6177009f508ef2ace0494728912fe2e9
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 3ab1186290a311a8ceed1286c0e286209f7fe97b2d02c7593258004ce295dd88
|
||||
F src/shell.c.in d320d8a13636de06d777cc1eab981caca304e175464e98183cf4ea68d93db818
|
||||
F src/shell.c.in 62b58d7be1e44ec3eb729411278b079c39949e683853445323fd3f250b674a29
|
||||
F src/sqlite.h.in f999ef3642f381d69679b2516b430dbcb6c5a2a951b7f5e43dc4751b474a5774
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
|
||||
@ -717,7 +717,7 @@ F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2c
|
||||
F src/vdbemem.c 33da4f30ddba2670bc1e617c3262b66aef2a8039043d4ff93e5c97974991089d
|
||||
F src/vdbesort.c 0d40dca073c94e158ead752ef4225f4fee22dee84145e8c00ca2309afb489015
|
||||
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
|
||||
F src/vdbevtab.c aae4bd769410eb7e1d02c42613eec961d514459b1c3c1c63cfc84e92a137daac
|
||||
F src/vdbevtab.c 57fa8f56478e5b5cb558cb425e7878515e0a105c54f96f1d1bbf4b9433529254
|
||||
F src/vtab.c 1ecf8c3745d29275688d583e12822fa984d421e0286b5ef50c137bc3bf6d7a64
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c dd843f619ac60d5dadab7109cf402432ba74dde0c301505fd1c202add07659e3
|
||||
@ -2044,8 +2044,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 cd5fda8c2e354da7458b7c1a82ff18c5946f8dab16095bb0293bec57f6804f17
|
||||
R ecfa3d900e8af899b83f6d4944c0b5ca
|
||||
P 1bf85d4e388714a88f8940dcdec353c3e0267456697eff6963d34637912aecc9 fd59226b34fffb1479fb2d7bd7c0aff982aa4a1a73e6c0d81de6eaf9c075998c
|
||||
R 26c73044c10199d992b00944e358a20b
|
||||
U drh
|
||||
Z 621bef24d346a4651dc554beab6ec135
|
||||
Z d6bca8891c39ac6c04dd8ce7fe687700
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
1bf85d4e388714a88f8940dcdec353c3e0267456697eff6963d34637912aecc9
|
||||
5739a16ad270a5aadcbb46b28c34fa6ba975422788dcbccb1a8e0d1e6ed75144
|
61
src/json.c
61
src/json.c
@ -144,8 +144,7 @@ struct JsonNode {
|
||||
/* A parsed and possibly edited JSON string. Lifecycle:
|
||||
**
|
||||
** 1. JSON comes in and is parsed into an array aNode[]. The original
|
||||
** JSON text is stored in zJson. This object may or may not be the
|
||||
** owner of the input JSON - the bOwnsJson variables determines which.
|
||||
** JSON text is stored in zJson.
|
||||
**
|
||||
** 2. Zero or more changes are made (via json_remove() or json_replace()
|
||||
** or similar) to the aNode[] array.
|
||||
@ -176,7 +175,6 @@ struct JsonParse {
|
||||
u8 nErr; /* Number of errors seen */
|
||||
u8 oom; /* Set to true if out of memory */
|
||||
u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
|
||||
u8 bOwnsJson; /* This object owns zJson and response for freeing it */
|
||||
u8 useMod; /* Actually use the edits contain inside aNode */
|
||||
u8 hasMod; /* aNode contains edits from the original zJson */
|
||||
u32 nJPRef; /* Number of references to this object */
|
||||
@ -565,12 +563,18 @@ static void jsonAppendValue(
|
||||
** The JSON string is reset.
|
||||
*/
|
||||
static void jsonResult(JsonString *p){
|
||||
if( p->bErr==0 && jsonForceRCStr(p) ){
|
||||
sqlite3RCStrRef(p->zBuf);
|
||||
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
|
||||
(void(*)(void*))sqlite3RCStrUnref,
|
||||
SQLITE_UTF8);
|
||||
}else if( p->bErr==1 ){
|
||||
if( p->bErr==0 ){
|
||||
if( p->bStatic ){
|
||||
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
|
||||
SQLITE_TRANSIENT, SQLITE_UTF8);
|
||||
}else if( jsonForceRCStr(p) ){
|
||||
sqlite3RCStrRef(p->zBuf);
|
||||
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
|
||||
(void(*)(void*))sqlite3RCStrUnref,
|
||||
SQLITE_UTF8);
|
||||
}
|
||||
}
|
||||
if( p->bErr==1 ){
|
||||
sqlite3_result_error_nomem(p->pCtx);
|
||||
}
|
||||
jsonReset(p);
|
||||
@ -619,11 +623,6 @@ static void jsonParseReset(JsonParse *pParse){
|
||||
sqlite3RCStrUnref(pParse->zAlt);
|
||||
pParse->zAlt = 0;
|
||||
}
|
||||
if( pParse->bOwnsJson ){
|
||||
pParse->bOwnsJson = 0;
|
||||
sqlite3RCStrUnref(pParse->zJson);
|
||||
pParse->zJson = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1759,14 +1758,12 @@ json_parse_restart:
|
||||
static int jsonParse(
|
||||
JsonParse *pParse, /* Initialize and fill this JsonParse object */
|
||||
sqlite3_context *pCtx, /* Report errors here */
|
||||
char *zJson, /* Input JSON text to be parsed */
|
||||
int bTakeJson /* Assume ownership of zJson if true */
|
||||
char *zJson /* Input JSON text to be parsed */
|
||||
){
|
||||
int i;
|
||||
memset(pParse, 0, sizeof(*pParse));
|
||||
if( zJson==0 ) return 1;
|
||||
pParse->zJson = zJson;
|
||||
pParse->bOwnsJson = bTakeJson;
|
||||
pParse->nJPRef = 1;
|
||||
i = jsonParseValue(pParse, 0);
|
||||
if( pParse->oom ) i = -1;
|
||||
@ -1933,21 +1930,16 @@ static JsonParse *jsonParseCached(
|
||||
/* The input JSON was not found anywhere in the cache. We will need
|
||||
** to parse it ourselves and generate a new JsonParse object.
|
||||
*/
|
||||
p = sqlite3_malloc64( sizeof(*p) );
|
||||
p = sqlite3_malloc64( sizeof(*p) + nJson + 1 );
|
||||
if( p==0 ){
|
||||
sqlite3_result_error_nomem(pCtx);
|
||||
return 0;
|
||||
}
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->zJson = sqlite3RCStrNew( nJson );
|
||||
if( p->zJson==0 ){
|
||||
sqlite3_free(p);
|
||||
sqlite3_result_error_nomem(pCtx);
|
||||
return 0;
|
||||
}
|
||||
p->zJson = (char*)&p[1];
|
||||
memcpy(p->zJson, zJson, nJson);
|
||||
p->zJson[nJson] = 0;
|
||||
if( jsonParse(p, pErrCtx, p->zJson, 1) ){
|
||||
if( jsonParse(p, pErrCtx, p->zJson) ){
|
||||
if( pErrCtx==0 ){
|
||||
p->nErr = 1;
|
||||
assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */
|
||||
@ -2365,7 +2357,6 @@ static void jsonParseFunc(
|
||||
printf("nErr = %u\n", p->nErr);
|
||||
printf("oom = %u\n", p->oom);
|
||||
printf("hasNonstd = %u\n", p->hasNonstd);
|
||||
printf("bOwnsJson = %u\n", p->bOwnsJson);
|
||||
printf("useMod = %u\n", p->useMod);
|
||||
printf("hasMod = %u\n", p->hasMod);
|
||||
printf("nJPRef = %u\n", p->nJPRef);
|
||||
@ -2677,8 +2668,8 @@ static void jsonPatchFunc(
|
||||
JsonNode *pResult; /* The result of the merge */
|
||||
|
||||
UNUSED_PARAMETER(argc);
|
||||
if( jsonParse(&x, ctx, (char*)sqlite3_value_text(argv[0]), 0) ) return;
|
||||
if( jsonParse(&y, ctx, (char*)sqlite3_value_text(argv[1]), 0) ){
|
||||
if( jsonParse(&x, ctx, (char*)sqlite3_value_text(argv[0])) ) return;
|
||||
if( jsonParse(&y, ctx, (char*)sqlite3_value_text(argv[1])) ){
|
||||
jsonParseReset(&x);
|
||||
return;
|
||||
}
|
||||
@ -2828,14 +2819,17 @@ static void jsonReplaceNode(
|
||||
break;
|
||||
}
|
||||
if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){
|
||||
int k = jsonParseAddNode(p, JSON_STRING, n, z);
|
||||
char *zCopy = sqlite3DbStrDup(0, z);
|
||||
if( k>0 ) p->aNode[k].jnFlags |= JNODE_RAW;
|
||||
int k;
|
||||
if( zCopy ){
|
||||
jsonParseAddCleanup(p, sqlite3_free, zCopy);
|
||||
}else{
|
||||
}else{
|
||||
p->oom = 1;
|
||||
sqlite3_result_error_nomem(pCtx);
|
||||
}
|
||||
k = jsonParseAddNode(p, JSON_STRING, n, zCopy);
|
||||
assert( k>0 || p->oom );
|
||||
if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW;
|
||||
}else{
|
||||
JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1);
|
||||
if( pPatch==0 ){
|
||||
@ -2852,7 +2846,8 @@ static void jsonReplaceNode(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SQLITE_BLOB: {
|
||||
default: {
|
||||
jsonParseAddNode(p, JSON_NULL, 0, 0);
|
||||
sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1);
|
||||
p->nErr++;
|
||||
break;
|
||||
@ -3641,7 +3636,7 @@ static int jsonEachFilter(
|
||||
p->zJson = sqlite3_malloc64( n+1 );
|
||||
if( p->zJson==0 ) return SQLITE_NOMEM;
|
||||
memcpy(p->zJson, z, (size_t)n+1);
|
||||
if( jsonParse(&p->sParse, 0, p->zJson, 0) ){
|
||||
if( jsonParse(&p->sParse, 0, p->zJson) ){
|
||||
int rc = SQLITE_NOMEM;
|
||||
if( p->sParse.oom==0 ){
|
||||
sqlite3_free(cur->pVtab->zErrMsg);
|
||||
|
167
src/shell.c.in
167
src/shell.c.in
@ -1607,6 +1607,7 @@ static ShellState shellState;
|
||||
#define MODE_Box 16 /* Unicode box-drawing characters */
|
||||
#define MODE_Count 17 /* Output only a count of the rows of output */
|
||||
#define MODE_Off 18 /* No query output shown */
|
||||
#define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */
|
||||
|
||||
static const char *modeDescr[] = {
|
||||
"line",
|
||||
@ -2520,38 +2521,58 @@ static int shell_callback(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MODE_ScanExp:
|
||||
case MODE_Explain: {
|
||||
static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
|
||||
if( nArg>ArraySize(aExplainWidth) ){
|
||||
nArg = ArraySize(aExplainWidth);
|
||||
static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
|
||||
static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
static const int aScanExpWidth[] = {4, 6, 6, 13, 4, 4, 4, 13, 2, 13};
|
||||
static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
||||
const int *aWidth = aExplainWidth;
|
||||
const int *aMap = aExplainMap;
|
||||
int nWidth = ArraySize(aExplainWidth);
|
||||
int iIndent = 1;
|
||||
|
||||
if( p->cMode==MODE_ScanExp ){
|
||||
aWidth = aScanExpWidth;
|
||||
aMap = aScanExpMap;
|
||||
nWidth = ArraySize(aScanExpWidth);
|
||||
iIndent = 3;
|
||||
}
|
||||
if( nArg>nWidth ) nArg = nWidth;
|
||||
|
||||
/* If this is the first row seen, print out the headers */
|
||||
if( p->cnt++==0 ){
|
||||
for(i=0; i<nArg; i++){
|
||||
int w = aExplainWidth[i];
|
||||
utf8_width_print(p->out, w, azCol[i]);
|
||||
utf8_width_print(p->out, aWidth[i], azCol[ aMap[i] ]);
|
||||
fputs(i==nArg-1 ? "\n" : " ", p->out);
|
||||
}
|
||||
for(i=0; i<nArg; i++){
|
||||
int w = aExplainWidth[i];
|
||||
print_dashes(p->out, w);
|
||||
print_dashes(p->out, aWidth[i]);
|
||||
fputs(i==nArg-1 ? "\n" : " ", p->out);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is no data, exit early. */
|
||||
if( azArg==0 ) break;
|
||||
|
||||
for(i=0; i<nArg; i++){
|
||||
int w = aExplainWidth[i];
|
||||
const char *zSep = " ";
|
||||
int w = aWidth[i];
|
||||
const char *zVal = azArg[ aMap[i] ];
|
||||
if( i==nArg-1 ) w = 0;
|
||||
if( azArg[i] && strlenChar(azArg[i])>w ){
|
||||
w = strlenChar(azArg[i]);
|
||||
if( zVal && strlenChar(zVal)>w ){
|
||||
w = strlenChar(zVal);
|
||||
zSep = " ";
|
||||
}
|
||||
if( i==1 && p->aiIndent && p->pStmt ){
|
||||
if( i==iIndent && p->aiIndent && p->pStmt ){
|
||||
if( p->iIndent<p->nIndent ){
|
||||
utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
|
||||
}
|
||||
p->iIndent++;
|
||||
}
|
||||
utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
|
||||
fputs(i==nArg-1 ? "\n" : " ", p->out);
|
||||
utf8_width_print(p->out, w, zVal ? zVal : p->nullValue);
|
||||
fputs(i==nArg-1 ? "\n" : zSep, p->out);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3332,17 +3353,11 @@ static int scanStatsHeight(sqlite3_stmt *p, int iEntry){
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Display scan stats.
|
||||
*/
|
||||
static void display_scanstats(
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
static void display_explain_scanstats(
|
||||
sqlite3 *db, /* Database to query */
|
||||
ShellState *pArg /* Pointer to ShellState */
|
||||
){
|
||||
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
UNUSED_PARAMETER(db);
|
||||
UNUSED_PARAMETER(pArg);
|
||||
#else
|
||||
static const int f = SQLITE_SCANSTAT_COMPLEX;
|
||||
sqlite3_stmt *p = pArg->pStmt;
|
||||
int ii = 0;
|
||||
@ -3414,8 +3429,9 @@ static void display_scanstats(
|
||||
}
|
||||
|
||||
eqp_render(pArg, nTotal);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Parameter azArray points to a zero-terminated array of strings. zStr
|
||||
@ -3453,8 +3469,6 @@ static int str_in_array(const char *zStr, const char **azArray){
|
||||
** and "Goto" by 2 spaces.
|
||||
*/
|
||||
static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
|
||||
const char *zSql; /* The text of the SQL statement */
|
||||
const char *z; /* Used to check if this is an EXPLAIN */
|
||||
int *abYield = 0; /* True if op is an OP_Yield */
|
||||
int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
|
||||
int iOp; /* Index of operation in p->aiIndent[] */
|
||||
@ -3465,65 +3479,45 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
|
||||
"Rewind", 0 };
|
||||
const char *azGoto[] = { "Goto", 0 };
|
||||
|
||||
/* Try to figure out if this is really an EXPLAIN statement. If this
|
||||
** cannot be verified, return early. */
|
||||
if( sqlite3_column_count(pSql)!=8 ){
|
||||
p->cMode = p->mode;
|
||||
return;
|
||||
}
|
||||
zSql = sqlite3_sql(pSql);
|
||||
if( zSql==0 ) return;
|
||||
for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
|
||||
if( sqlite3_strnicmp(z, "explain", 7) ){
|
||||
p->cMode = p->mode;
|
||||
return;
|
||||
}
|
||||
/* The caller guarantees that the leftmost 4 columns of the statement
|
||||
** passed to this function are equivalent to the leftmost 4 columns
|
||||
** of EXPLAIN statement output. In practice the statement may be
|
||||
** an EXPLAIN, or it may be a query on the bytecode() virtual table. */
|
||||
assert( sqlite3_column_count(pSql)>=4 );
|
||||
assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 0), "addr" ) );
|
||||
assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 1), "opcode" ) );
|
||||
assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 2), "p1" ) );
|
||||
assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 3), "p2" ) );
|
||||
|
||||
for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
|
||||
int i;
|
||||
int iAddr = sqlite3_column_int(pSql, 0);
|
||||
const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
|
||||
|
||||
/* Set p2 to the P2 field of the current opcode. Then, assuming that
|
||||
** p2 is an instruction address, set variable p2op to the index of that
|
||||
** instruction in the aiIndent[] array. p2 and p2op may be different if
|
||||
** the current instruction is part of a sub-program generated by an
|
||||
** SQL trigger or foreign key. */
|
||||
int p1 = sqlite3_column_int(pSql, 2);
|
||||
int p2 = sqlite3_column_int(pSql, 3);
|
||||
|
||||
/* Assuming that p2 is an instruction address, set variable p2op to the
|
||||
** index of that instruction in the aiIndent[] array. p2 and p2op may be
|
||||
** different if the current instruction is part of a sub-program generated
|
||||
** by an SQL trigger or foreign key. */
|
||||
int p2op = (p2 + (iOp-iAddr));
|
||||
|
||||
/* Grow the p->aiIndent array as required */
|
||||
if( iOp>=nAlloc ){
|
||||
if( iOp==0 ){
|
||||
/* Do further verification that this is explain output. Abort if
|
||||
** it is not */
|
||||
static const char *explainCols[] = {
|
||||
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
|
||||
int jj;
|
||||
for(jj=0; jj<ArraySize(explainCols); jj++){
|
||||
if( cli_strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
|
||||
p->cMode = p->mode;
|
||||
sqlite3_reset(pSql);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
nAlloc += 100;
|
||||
p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
|
||||
shell_check_oom(p->aiIndent);
|
||||
abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
|
||||
shell_check_oom(abYield);
|
||||
}
|
||||
|
||||
abYield[iOp] = str_in_array(zOp, azYield);
|
||||
p->aiIndent[iOp] = 0;
|
||||
p->nIndent = iOp+1;
|
||||
|
||||
if( str_in_array(zOp, azNext) && p2op>0 ){
|
||||
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
|
||||
}
|
||||
if( str_in_array(zOp, azGoto) && p2op<p->nIndent
|
||||
&& (abYield[p2op] || sqlite3_column_int(pSql, 2))
|
||||
){
|
||||
if( str_in_array(zOp, azGoto) && p2op<iOp && (abYield[p2op] || p1) ){
|
||||
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
|
||||
}
|
||||
}
|
||||
@ -3543,6 +3537,48 @@ static void explain_data_delete(ShellState *p){
|
||||
p->iIndent = 0;
|
||||
}
|
||||
|
||||
static void exec_prepared_stmt(ShellState*, sqlite3_stmt*);
|
||||
|
||||
/*
|
||||
** Display scan stats.
|
||||
*/
|
||||
static void display_scanstats(
|
||||
sqlite3 *db, /* Database to query */
|
||||
ShellState *pArg /* Pointer to ShellState */
|
||||
){
|
||||
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
UNUSED_PARAMETER(db);
|
||||
UNUSED_PARAMETER(pArg);
|
||||
#else
|
||||
if( pArg->scanstatsOn==3 ){
|
||||
const char *zSql =
|
||||
" SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec,"
|
||||
" round(ncycle*100.0 / (sum(ncycle) OVER ()), 2)||'%' AS cycles"
|
||||
" FROM bytecode(?)";
|
||||
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_stmt *pSave = pArg->pStmt;
|
||||
pArg->pStmt = pStmt;
|
||||
sqlite3_bind_pointer(pStmt, 1, pSave, "stmt-pointer", 0);
|
||||
|
||||
pArg->cnt = 0;
|
||||
pArg->cMode = MODE_ScanExp;
|
||||
explain_data_prepare(pArg, pStmt);
|
||||
exec_prepared_stmt(pArg, pStmt);
|
||||
explain_data_delete(pArg);
|
||||
|
||||
sqlite3_finalize(pStmt);
|
||||
pArg->pStmt = pSave;
|
||||
}
|
||||
}else{
|
||||
display_explain_scanstats(db, pArg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
|
||||
*/
|
||||
@ -4362,6 +4398,7 @@ static int shell_exec(
|
||||
rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
pArg->cMode = MODE_Explain;
|
||||
assert( sqlite3_stmt_isexplain(pExplain)==1 );
|
||||
explain_data_prepare(pArg, pExplain);
|
||||
exec_prepared_stmt(pArg, pExplain);
|
||||
explain_data_delete(pArg);
|
||||
@ -4380,9 +4417,10 @@ static int shell_exec(
|
||||
}
|
||||
|
||||
if( pArg ){
|
||||
int bIsExplain = (sqlite3_stmt_isexplain(pStmt)==1);
|
||||
pArg->cMode = pArg->mode;
|
||||
if( pArg->autoExplain ){
|
||||
if( sqlite3_stmt_isexplain(pStmt)==1 ){
|
||||
if( bIsExplain ){
|
||||
pArg->cMode = MODE_Explain;
|
||||
}
|
||||
if( sqlite3_stmt_isexplain(pStmt)==2 ){
|
||||
@ -4392,7 +4430,7 @@ static int shell_exec(
|
||||
|
||||
/* If the shell is currently in ".explain" mode, gather the extra
|
||||
** data required to add indents to the output.*/
|
||||
if( pArg->cMode==MODE_Explain ){
|
||||
if( pArg->cMode==MODE_Explain && bIsExplain ){
|
||||
explain_data_prepare(pArg, pStmt);
|
||||
}
|
||||
}
|
||||
@ -9933,6 +9971,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){
|
||||
if( nArg==2 ){
|
||||
if( cli_strcmp(azArg[1], "vm")==0 ){
|
||||
p->scanstatsOn = 3;
|
||||
}else
|
||||
if( cli_strcmp(azArg[1], "est")==0 ){
|
||||
p->scanstatsOn = 2;
|
||||
}else{
|
||||
|
@ -69,6 +69,8 @@ static int bytecodevtabConnect(
|
||||
"p5 INT,"
|
||||
"comment TEXT,"
|
||||
"subprog TEXT,"
|
||||
"nexec INT,"
|
||||
"ncycle INT,"
|
||||
"stmt HIDDEN"
|
||||
");",
|
||||
|
||||
@ -231,7 +233,7 @@ static int bytecodevtabColumn(
|
||||
}
|
||||
}
|
||||
}
|
||||
i += 10;
|
||||
i += 20;
|
||||
}
|
||||
}
|
||||
switch( i ){
|
||||
@ -281,16 +283,31 @@ static int bytecodevtabColumn(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 10: /* tables_used.type */
|
||||
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
case 9: /* nexec */
|
||||
sqlite3_result_int(ctx, pOp->nExec);
|
||||
break;
|
||||
case 10: /* ncycle */
|
||||
sqlite3_result_int(ctx, pOp->nCycle);
|
||||
break;
|
||||
#else
|
||||
case 9: /* nexec */
|
||||
case 10: /* ncycle */
|
||||
sqlite3_result_int(ctx, 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 20: /* tables_used.type */
|
||||
sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
|
||||
break;
|
||||
case 11: /* tables_used.schema */
|
||||
case 21: /* tables_used.schema */
|
||||
sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
|
||||
break;
|
||||
case 12: /* tables_used.name */
|
||||
case 22: /* tables_used.name */
|
||||
sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
|
||||
break;
|
||||
case 13: /* tables_used.wr */
|
||||
case 23: /* tables_used.wr */
|
||||
sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
|
||||
break;
|
||||
}
|
||||
@ -364,7 +381,7 @@ static int bytecodevtabBestIndex(
|
||||
int rc = SQLITE_CONSTRAINT;
|
||||
struct sqlite3_index_constraint *p;
|
||||
bytecodevtab *pVTab = (bytecodevtab*)tab;
|
||||
int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
|
||||
int iBaseCol = pVTab->bTablesUsed ? 4 : 10;
|
||||
pIdxInfo->estimatedCost = (double)100;
|
||||
pIdxInfo->estimatedRows = 100;
|
||||
pIdxInfo->idxNum = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user