Merge latest trunk changes.

FossilOrigin-Name: 1a72777b1279f74f212fb2f675a4594a238e5d28f048879d7f5ad5287673c3c4
This commit is contained in:
dan 2022-12-05 18:26:37 +00:00
commit 77e171e8fa
28 changed files with 502 additions and 209 deletions

View File

@ -489,7 +489,7 @@ emcc.jsflags += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY))
emcc.jsflags += $(emcc.environment)
emcc.jsflags += -sSTACK_SIZE=1MB
# ^^^ ACHTUNG: emsdk 3.1.27 reduced the default stack size from 4MB to
# ^^^ ACHTUNG: emsdk 3.1.27 reduced the default stack size from 5MB to
# a mere 64KB, which leads to silent memory corruption via the kvvfs
# VFS, which requires twice that for its xRead() and xWrite() methods.
########################################################################
@ -811,12 +811,6 @@ endif
# /wasmfs
########################################################################
########################################################################
# Create main client downloadable zip file:
ifneq (,$(filter dist snapshot,$(MAKECMDGOALS)))
include dist.make
endif
########################################################################
# Push files to public wasm-testing.sqlite.org server
wasm-testing.include = *.js *.mjs *.html \
@ -839,27 +833,35 @@ push-testing:
########################################################################
# If we find a copy of the sqlite.org/wasm docs checked out, copy
# certain files over to it, noting that some need automatable edits...
WDOCS.home ?= ../../../wdoc
wasm.docs.home ?= ../../../wasm
wasm.docs.found = $(if $(wildcard $(wasm.docs.home)/api-index.md),\
$(wildcard $(wasm.docs.home)),)
.PHONY: update-docs
ifneq (,$(wildcard $(WDOCS.home)/api-index.md))
WDOCS.jswasm := $(WDOCS.home)/jswasm
update-docs: $(bin.stripccomments) $(sqlite3.js) $(sqlite3.wasm)
@echo "Copying files to the /wasm docs. Be sure to use an -Oz build for this!"
cp $(sqlite3.wasm) $(WDOCS.jswasm)/.
$(bin.stripccomments) -k -k < $(sqlite3.js) \
| sed -e '/^[ \t]*$$/d' > $(WDOCS.jswasm)/sqlite3.js
cp demo-123.js demo-123.html demo-123-worker.html $(WDOCS.home)
sed -n -e '/EXTRACT_BEGIN/,/EXTRACT_END/p' \
module-symbols.html > $(WDOCS.home)/module-symbols.html
else
ifeq (,$(wasm.docs.found))
update-docs:
@echo "Cannot find wasm docs checkout."; \
echo "Pass WDOCS.home=/path/to/wasm/docs/checkout or edit this makefile to suit."; \
echo "Pass wasm.docs.home=/path/to/wasm/docs/checkout or edit this makefile to suit."; \
exit 127
else
wasm.docs.jswasm := $(wasm.docs.home)/jswasm
update-docs: $(bin.stripccomments) $(sqlite3.js) $(sqlite3.wasm)
@echo "Copying files to the /wasm docs. Be sure to use an -Oz build for this!"
cp $(sqlite3.wasm) $(wasm.docs.jswasm)/.
$(bin.stripccomments) -k -k < $(sqlite3.js) \
| sed -e '/^[ \t]*$$/d' > $(wasm.docs.jswasm)/sqlite3.js
cp demo-123.js demo-123.html demo-123-worker.html $(wasm.docs.home)
sed -n -e '/EXTRACT_BEGIN/,/EXTRACT_END/p' \
module-symbols.html > $(wasm.docs.home)/module-symbols.html
endif
# end /wasm docs
########################################################################
########################################################################
# Create main client downloadable zip file:
ifneq (,$(filter dist snapshot,$(MAKECMDGOALS)))
include dist.make
endif
# Run local web server for the test/demo pages.
httpd:
althttpd -max-age 1 -enable-sab -page index.html

View File

@ -66,6 +66,8 @@ _sqlite3_result_int
_sqlite3_result_int64
_sqlite3_result_null
_sqlite3_result_text
_sqlite3_result_zeroblob
_sqlite3_result_zeroblob64
_sqlite3_serialize
_sqlite3_shutdown
_sqlite3_sourceid
@ -93,3 +95,4 @@ _sqlite3_vfs_register
_sqlite3_vfs_unregister
_malloc
_free
_realloc

View File

@ -605,6 +605,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
//console.debug('wasm.ctype length =',wasm.cstrlen(cJson));
for(const t of ['access', 'blobFinalizers', 'dataTypes',
'encodings', 'fcntl', 'flock', 'ioCap',
'limits',
'openFlags', 'prepareFlags', 'resultCodes',
'serialize', 'syncFlags', 'trace', 'udfFlags',
'version'

View File

@ -78,8 +78,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}.bind({counter: 0}));
/**
A map of sqlite3_vfs pointers to SQL code to run when the DB
constructor opens a database with the given VFS.
A map of sqlite3_vfs pointers to SQL code or a callback function
to run when the DB constructor opens a database with the given
VFS. In the latter case, the call signature is (theDbObject,sqlite3Namespace)
and the callback is expected to throw on error.
*/
const __vfsPostOpenSql = Object.create(null);
@ -160,15 +162,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
capi.sqlite3_trace_v2(pDb, capi.SQLITE_TRACE_STMT,
__dbTraceToConsole, 0);
}
// Check for per-VFS post-open SQL...
const pVfs = capi.sqlite3_js_db_vfs(pDb);
//console.warn("Opened db",fn,"with vfs",vfsName,pVfs);
if(!pVfs) toss3("Internal error: cannot get VFS for new db handle.");
const postInitSql = __vfsPostOpenSql[pVfs];
if(postInitSql){
rc = capi.sqlite3_exec(pDb, postInitSql, 0, 0, 0);
checkSqlite3Rc(pDb, rc);
}
}catch( e ){
if( pDb ) capi.sqlite3_close_v2(pDb);
throw e;
@ -178,12 +171,34 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
this.filename = fnJs;
__ptrMap.set(this, pDb);
__stmtMap.set(this, Object.create(null));
try{
// Check for per-VFS post-open SQL/callback...
const pVfs = capi.sqlite3_js_db_vfs(pDb);
if(!pVfs) toss3("Internal error: cannot get VFS for new db handle.");
const postInitSql = __vfsPostOpenSql[pVfs];
if(postInitSql instanceof Function){
postInitSql(this, sqlite3);
}else if(postInitSql){
checkSqlite3Rc(
pDb, capi.sqlite3_exec(pDb, postInitSql, 0, 0, 0)
);
}
}catch(e){
this.close();
throw e;
}
};
/**
Sets SQL which should be exec()'d on a DB instance after it is
opened with the given VFS pointer. This is intended only for use
by DB subclasses or sqlite3_vfs implementations.
opened with the given VFS pointer. The SQL may be any type
supported by the "flexible-string" function argument
conversion. Alternately, the 2nd argument may be a function, in
which case it is called with (theOo1DbObject,sqlite3Namespace) at
the end of the DB() constructor. The function must throw on
error, in which case the db is closed and the exception is
propagated. This function is intended only for use by DB
subclasses or sqlite3_vfs implementations.
*/
dbCtorHelper.setVfsPostOpenSql = function(pVfs, sql){
__vfsPostOpenSql[pVfs] = sql;

View File

@ -75,6 +75,10 @@
the `free(3)`-compatible routine for the WASM
environment. Defaults to `"sqlite3_free"`.
- `reallocExportName`: the name of the function, in `exports`, of
the `realloc(3)`-compatible routine for the WASM
environment. Defaults to `"sqlite3_realloc"`.
- `wasmfsOpfsDir`[^1]: if the environment supports persistent
storage using OPFS-over-WASMFS , this directory names the "mount
point" for that directory. It must be prefixed by `/` and may
@ -108,11 +112,23 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
}
return !!self.BigInt64Array;
})(),
allocExportName: 'sqlite3_malloc',
deallocExportName: 'sqlite3_free',
wasmfsOpfsDir: '/opfs'
wasmfsOpfsDir: '/opfs',
/**
useStdAlloc is just for testing an allocator discrepancy. The
docs guarantee that this is false in the canonical builds. For
99% of purposes it doesn't matter which allocators we use, but
it becomes significant with, e.g., sqlite3_deserialize()
and certain wasm.xWrap.resultAdapter()s.
*/
useStdAlloc: false
}, apiConfig || {});
Object.assign(config, {
allocExportName: config.useStdAlloc ? 'malloc' : 'sqlite3_malloc',
deallocExportName: config.useStdAlloc ? 'free' : 'sqlite3_free',
reallocExportName: config.useStdAlloc ? 'realloc' : 'sqlite3_realloc'
}, config);
[
// If any of these config options are functions, replace them with
// the result of calling that function...
@ -284,12 +300,14 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
};
/**
Returns true if v appears to be one of our bind()-able
TypedArray types: Uint8Array or Int8Array. Support for
TypedArrays with element sizes >1 is TODO.
Returns true if v appears to be one of our bind()-able TypedArray
types: Uint8Array or Int8Array. Support for TypedArrays with
element sizes >1 is a potential TODO just waiting on a use case
to justify them.
*/
const isBindableTypedArray = (v)=>{
return v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
return v && (v instanceof Uint8Array || v instanceof Int8Array);
//v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
};
/**
@ -302,7 +320,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
isSQLableTypedArray() list.
*/
const isSQLableTypedArray = (v)=>{
return v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
return v && (v instanceof Uint8Array || v instanceof Int8Array);
//v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
};
/** Returns true if isBindableTypedArray(v) does, else throws with a message
@ -664,12 +683,12 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
"or config.memory (imported)."),
/**
The API's one single point of access to the WASM-side memory
allocator. Works like malloc(3) (and is likely bound to
malloc()) but throws an WasmAllocError if allocation fails. It is
important that any code which might pass through the sqlite3 C
API NOT throw and must instead return SQLITE_NOMEM (or
equivalent, depending on the context).
The API's primary point of access to the WASM-side memory
allocator. Works like sqlite3_malloc() but throws a
WasmAllocError if allocation fails. It is important that any
code which might pass through the sqlite3 C API NOT throw and
must instead return SQLITE_NOMEM (or equivalent, depending on
the context).
Very few cases in the sqlite3 JS APIs can result in
client-defined functions propagating exceptions via the C-style
@ -681,7 +700,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
catch exceptions and convert them to appropriate error codes.
For cases where non-throwing allocation is required, use
sqlite3.wasm.alloc.impl(), which is direct binding of the
this.alloc.impl(), which is direct binding of the
underlying C-level allocator.
Design note: this function is not named "malloc" primarily
@ -692,9 +711,27 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
alloc: undefined/*installed later*/,
/**
The API's one single point of access to the WASM-side memory
deallocator. Works like free(3) (and is likely bound to
free()).
Rarely necessary in JS code, this routine works like
sqlite3_realloc(M,N), where M is either NULL or a pointer
obtained from this function or this.alloc() and N is the number
of bytes to reallocate the block to. Returns a pointer to the
reallocated block or 0 if allocation fails.
If M is NULL and N is positive, this behaves like
this.alloc(N). If N is 0, it behaves like this.dealloc().
Results are undefined if N is negative (sqlite3_realloc()
treats that as 0, but if this code is built with a different
allocator it may misbehave with negative values).
Like this.alloc.impl(), this.realloc.impl() is a direct binding
to the underlying realloc() implementation which does not throw
exceptions, instead returning 0 on allocation error.
*/
realloc: undefined/*installed later*/,
/**
The API's primary point of access to the WASM-side memory
deallocator. Works like sqlite3_free().
Design note: this function is not named "free" for the same
reason that this.alloc() is not called this.malloc().
@ -711,18 +748,20 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
returned pointer must eventually be passed to
wasm.dealloc() to clean it up.
The argument may be a Uint8Array, Int8Array, or ArrayBuffer,
and it throws if passed any other type.
As a special case, to avoid further special cases where
this is used, if srcTypedArray.byteLength is 0, it
allocates a single byte and sets it to the value
0. Even in such cases, calls must behave as if the
allocated memory has exactly srcTypedArray.byteLength
bytes.
ACHTUNG: this currently only works for Uint8Array and
Int8Array types and will throw if srcTypedArray is of
any other type.
*/
wasm.allocFromTypedArray = function(srcTypedArray){
if(srcTypedArray instanceof ArrayBuffer){
srcTypedArray = new Uint8Array(srcTypedArray);
}
affirmBindableTypedArray(srcTypedArray);
const pRet = wasm.alloc(srcTypedArray.byteLength || 1);
wasm.heapForSize(srcTypedArray.constructor).set(
@ -731,20 +770,27 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
return pRet;
};
const keyAlloc = config.allocExportName,
keyDealloc = config.deallocExportName;
for(const key of [keyAlloc, keyDealloc]){
const f = wasm.exports[key];
if(!(f instanceof Function)) toss3("Missing required exports[",key,"] function.");
}
{
// Set up allocators...
const keyAlloc = config.allocExportName,
keyDealloc = config.deallocExportName,
keyRealloc = config.reallocExportName;
for(const key of [keyAlloc, keyDealloc, keyRealloc]){
const f = wasm.exports[key];
if(!(f instanceof Function)) toss3("Missing required exports[",key,"] function.");
}
wasm.alloc = function f(n){
const m = f.impl(n);
if(!m) throw new WasmAllocError("Failed to allocate",n," bytes.");
return m;
};
wasm.alloc.impl = wasm.exports[keyAlloc];
wasm.dealloc = wasm.exports[keyDealloc];
wasm.alloc = function f(n){
return f.impl(n) || WasmAllocError.toss("Failed to allocate",n," bytes.");
};
wasm.alloc.impl = wasm.exports[keyAlloc];
wasm.realloc = function f(m,n){
const m2 = f.impl(m,n);
return n ? (m2 || WasmAllocError.toss("Failed to reallocate",n," bytes.")) : 0;
};
wasm.realloc.impl = wasm.exports[keyRealloc];
wasm.dealloc = wasm.exports[keyDealloc];
}
/**
Reports info about compile-time options using
@ -899,15 +945,16 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
the range of supported argument types. */
["sqlite3_realloc", "*","*","int"],
["sqlite3_reset", "int", "sqlite3_stmt*"],
["sqlite3_result_blob",undefined, "*", "*", "int", "*"],
["sqlite3_result_double",undefined, "*", "f64"],
["sqlite3_result_error",undefined, "*", "string", "int"],
["sqlite3_result_error_code", undefined, "*", "int"],
["sqlite3_result_error_nomem", undefined, "*"],
["sqlite3_result_error_toobig", undefined, "*"],
["sqlite3_result_int",undefined, "*", "int"],
["sqlite3_result_null",undefined, "*"],
["sqlite3_result_text",undefined, "*", "string", "int", "*"],
["sqlite3_result_blob",undefined, "sqlite3_context*", "*", "int", "*"],
["sqlite3_result_double",undefined, "sqlite3_context*", "f64"],
["sqlite3_result_error",undefined, "sqlite3_context*", "string", "int"],
["sqlite3_result_error_code", undefined, "sqlite3_context*", "int"],
["sqlite3_result_error_nomem", undefined, "sqlite3_context*"],
["sqlite3_result_error_toobig", undefined, "sqlite3_context*"],
["sqlite3_result_int",undefined, "sqlite3_context*", "int"],
["sqlite3_result_null",undefined, "sqlite3_context*"],
["sqlite3_result_text",undefined, "sqlite3_context*", "string", "int", "*"],
["sqlite3_result_zeroblob", undefined, "sqlite3_context*", "int"],
["sqlite3_serialize","*", "sqlite3*", "string", "*", "int"],
["sqlite3_shutdown", undefined],
["sqlite3_sourceid", "string"],
@ -955,6 +1002,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
["sqlite3_msize", "i64", "*"],
["sqlite3_realloc64", "*","*", "i64"],
["sqlite3_result_int64",undefined, "*", "i64"],
["sqlite3_result_zeroblob64", "int", "*", "i64"],
["sqlite3_total_changes64", "i64", ["sqlite3*"]],
["sqlite3_uri_int64", "i64", ["sqlite3_filename", "string", "i64"]],
["sqlite3_value_int64","i64", "sqlite3_value*"],

View File

@ -1163,24 +1163,27 @@ const installOpfsVfs = function callee(options){
OpfsDb.prototype = Object.create(sqlite3.oo1.DB.prototype);
sqlite3.oo1.DB.dbCtorHelper.setVfsPostOpenSql(
opfsVfs.pointer,
[
/* Truncate journal mode is faster than delete for
this vfs, per speedtest1. That gap seems to have closed with
Chrome version 108 or 109, but "persist" is very roughly 5-6%
faster than truncate in initial tests. */
"pragma journal_mode=persist;",
/* Set a default busy-timeout handler to help OPFS dbs
deal with multi-tab/multi-worker contention. */
"pragma busy_timeout=5000;",
/*
This vfs benefits hugely from cache on moderate/large
speedtest1 --size 50 and --size 100 workloads. We currently
rely on setting a non-default cache size when building
sqlite3.wasm. If that policy changes, the cache can
be set here.
*/
//"pragma cache_size=-16384;"
].join("")
function(oo1Db, sqlite3){
/* Set a relatively high default busy-timeout handler to
help OPFS dbs deal with multi-tab/multi-worker
contention. */
sqlite3.capi.sqlite3_busy_timeout(oo1Db, 10000);
sqlite3.capi.sqlite3_exec(oo1Db, [
/* Truncate journal mode is faster than delete for
this vfs, per speedtest1. That gap seems to have closed with
Chrome version 108 or 109, but "persist" is very roughly 5-6%
faster than truncate in initial tests. */
"pragma journal_mode=persist;",
/*
This vfs benefits hugely from cache on moderate/large
speedtest1 --size 50 and --size 100 workloads. We
currently rely on setting a non-default cache size when
building sqlite3.wasm. If that policy changes, the cache
can be set here.
*/
"pragma cache_size=-16384;"
], 0, 0, 0);
}
);
}

View File

@ -112,6 +112,12 @@
# define SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
#endif
/**********************************************************************/
/* SQLITE_M... */
#ifndef SQLITE_MAX_ALLOCATION_SIZE
# define SQLITE_MAX_ALLOCATION_SIZE 0x1fffffff
#endif
/**********************************************************************/
/* SQLITE_O... */
#ifndef SQLITE_OMIT_DEPRECATED
@ -497,6 +503,10 @@ const char * sqlite3_wasm_enum_json(void){
DefInt(SQLITE_IOCAP_BATCH_ATOMIC);
} _DefGroup;
DefGroup(limits) {
DefInt(SQLITE_MAX_ALLOCATION_SIZE);
} _DefGroup;
DefGroup(openFlags) {
/* Noting that not all of these will have any effect in
** WASM-space. */
@ -1194,7 +1204,7 @@ void sqlite3_wasm_test_stack_overflow(int recurse){
/* For testing the 'string-free' whwasmutil.xWrap() conversion. */
SQLITE_WASM_KEEP
char * sqlite3_wasm_test_str_hello(int fail){
char * s = fail ? 0 : (char *)malloc(6);
char * s = fail ? 0 : (char *)sqlite3_malloc(6);
if(s){
memcpy(s, "hello", 5);
s[5] = 0;

View File

@ -1267,7 +1267,7 @@ self.WhWasmUtilInstaller = function(target){
- If v is a string, scopeAlloc() a new C-string from it and return
that temp string's pointer.
- Else return the value from the arg adaptor defined for ptrIR.
- Else return the value from the arg adapter defined for ptrIR.
TODO? Permit an Int8Array/Uint8Array and convert it to a string?
Would that be too much magic concentrated in one place, ready to
@ -1279,12 +1279,12 @@ self.WhWasmUtilInstaller = function(target){
return v ? xcv.arg[ptrIR](v) : null;
};
xcv.result.string = xcv.result.utf8 = (i)=>target.cstringToJs(i);
xcv.result['string:free'] = xcv.result['utf8:free'] = (i)=>{
xcv.result['string:dealloc'] = xcv.result['utf8:dealloc'] = (i)=>{
try { return i ? target.cstringToJs(i) : null }
finally{ target.dealloc(i) }
};
xcv.result.json = (i)=>JSON.parse(target.cstringToJs(i));
xcv.result['json:free'] = (i)=>{
xcv.result['json:dealloc'] = (i)=>{
try{ return i ? JSON.parse(target.cstringToJs(i)) : null }
finally{ target.dealloc(i) }
}
@ -1383,7 +1383,7 @@ self.WhWasmUtilInstaller = function(target){
true.
- `f32` (`float`), `f64` (`double`) (args and results): pass
their argument to Number(). i.e. the adaptor does not currently
their argument to Number(). i.e. the adapter does not currently
distinguish between the two types of floating-point numbers.
- `number` (results): converts the result to a JS Number using
@ -1411,7 +1411,7 @@ self.WhWasmUtilInstaller = function(target){
const C-string, encoded as UTF-8, copies it to a JS string,
and returns that JS string.
- `string:free` or `utf8:free) (results): treats the result value
- `string:dealloc` or `utf8:dealloc) (results): treats the result value
as a non-const UTF-8 C-string, ownership of which has just been
transfered to the caller. It copies the C-string to a JS
string, frees the C-string, and returns the JS string. If such
@ -1422,7 +1422,7 @@ self.WhWasmUtilInstaller = function(target){
required. For example:
```js
target.xWrap.resultAdaptor('string:my_free',(i)=>{
target.xWrap.resultAdapter('string:my_free',(i)=>{
try { return i ? target.cstringToJs(i) : null }
finally{ target.exports.my_free(i) }
};
@ -1432,9 +1432,9 @@ self.WhWasmUtilInstaller = function(target){
returns the result of passing the converted-to-JS string to
JSON.parse(). Returns `null` if the C-string is a NULL pointer.
- `json:free` (results): works exactly like `string:free` but
- `json:dealloc` (results): works exactly like `string:dealloc` but
returns the same thing as the `json` adapter. Note the
warning in `string:free` regarding maching allocators and
warning in `string:dealloc` regarding maching allocators and
deallocators.
The type names for results and arguments are validated when
@ -1545,7 +1545,7 @@ self.WhWasmUtilInstaller = function(target){
*/
target.xWrap.resultAdapter = function f(typeName, adapter){
return __xAdapter(f, arguments.length, typeName, adapter,
'resultAdaptor()', xcv.result);
'resultAdapter()', xcv.result);
};
/**

View File

@ -97,9 +97,17 @@ dist: \
ls -la $$arczip; \
set +e; \
unzip -lv $$arczip || echo "Missing unzip app? Not fatal."
ifeq (,$(wasm.docs.found))
snapshot: dist
@echo "Upload snapshot with:"; \
echo "rsync -ve ssh $(dist-name-prefix)*.zip $(wasm-testing.dest)/snapshots/."
@echo "To upload the snapshot build to the wasm docs server:"; \
echo "1) move $(dist-name-prefix)*.zip to the top of a wasm docs checkout."; \
echo "2) run 'make uv-sync'"
else
snapshot: dist
@echo "Moving snapshot to [$(wasm.docs.found)]..."; \
mv $(dist-name-prefix)*.zip $(wasm.docs.found)/.
@echo "Run 'make uv-sync' from $(wasm.docs.found) to upload it."
endif
# We need a separate `clean` rule to account for weirdness in
# a sub-make, where we get a copy of the $(dist-name) dir
# copied into the new $(dist-name) dir.

View File

@ -88,9 +88,9 @@
<li><a href='speedtest1.html'>speedtest1</a>: a main-thread WASM build of speedtest1.</li>
<!--li><a href='speedtest1-wasmfs.html?flags=--size,25'>speedtest1-wasmfs</a>: a variant of speedtest1 built solely for the wasmfs/opfs feature.
</li-->
<li><a href='speedtest1.html?vfs=kvvfs'>speedtest1-kvvfs</a>: speedtest1 with the kvvfs.</li>
<li><a href='speedtest1.html?vfs=kvvfs'>speedtest1?vfs=kvvfs</a>: speedtest1 with the kvvfs.</li>
<li><a href='speedtest1-worker.html?size=25'>speedtest1-worker</a>: an interactive Worker-thread variant of speedtest1.</li>
<li><a href='speedtest1-worker.html?vfs=opfs&size=25'>speedtest1-worker-opfs</a>: speedtest1-worker with the
<li><a href='speedtest1-worker.html?vfs=opfs&size=25'>speedtest1-worker?vfs=opfs</a>: speedtest1-worker with the
OPFS VFS preselected and configured for a moderate workload.</li>
</ul>
</li>

View File

@ -92,9 +92,8 @@
<li>This page runs in the main UI thread so cannot see features
which are only available in a Worker thread. If this page were
to function via a Worker, it would not be able to see
functionality only available in the main thread. Starting a
Worker here to fetch those symbols requires loading a second
copy of the sqlite3 WASM module and JS code.
functionality only available in the main thread. Either way, it
would be missing certain APIs.
</li>
</ul>

View File

@ -45,7 +45,7 @@
if(urlParams.has('esm')){
logHtml('warning',"Attempting to run an ES6 Worker Module, "+
"which is not supported by all browsers! "+
"e.g. Firefox (as of 2022-11) cannot do this.");
"e.g. Firefox (as of 2022-12) cannot do this.");
workerArgs.push("tester1.mjs",{type:"module"});
document.querySelectorAll('title,#color-target').forEach((e)=>{
e.innerText = "sqlite3 tester #1: ES6 Worker Module";

View File

@ -344,9 +344,22 @@ self.sqlite3InitModule = sqlite3InitModule;
////////////////////////////////////////////////////////////////////
T.g('Basic sanity checks')
.t("JS wasm-side allocator === sqlite3_malloc()", function(sqlite3){
T.assert(wasm.alloc.impl === wasm.exports.sqlite3_malloc)
.assert(wasm.dealloc === wasm.exports.sqlite3_free);
.t({
name: "JS wasm-side allocator",
test: function(sqlite3){
if(sqlite3.config.useStdAlloc){
warn("Using system allocator. This violates the docs and",
"may cause grief with certain APIs",
"(e.g. sqlite3_deserialize()).");
T.assert(wasm.alloc.impl === wasm.exports.malloc)
.assert(wasm.dealloc === wasm.exports.free)
.assert(wasm.realloc.impl === wasm.exports.realloc);
}else{
T.assert(wasm.alloc.impl === wasm.exports.sqlite3_malloc)
.assert(wasm.dealloc === wasm.exports.sqlite3_free)
.assert(wasm.realloc.impl === wasm.exports.sqlite3_realloc);
}
}
})
.t('Namespace object checks', function(sqlite3){
const wasmCtypes = wasm.ctype;
@ -424,6 +437,46 @@ self.sqlite3InitModule = sqlite3InitModule;
}
}
// alloc(), realloc(), allocFromTypedArray()
{
let m = w.alloc(14);
let m2 = w.realloc(m, 16);
T.assert(m === m2/* because of alignment */);
T.assert(0 === w.realloc(m, 0));
m = m2 = 0;
// Check allocation limits and allocator's responses...
T.assert('number' === typeof sqlite3.capi.SQLITE_MAX_ALLOCATION_SIZE);
if(!sqlite3.config.useStdAlloc){
const tooMuch = sqlite3.capi.SQLITE_MAX_ALLOCATION_SIZE + 1,
isAllocErr = (e)=>e instanceof sqlite3.WasmAllocError;
T.mustThrowMatching(()=>w.alloc(tooMuch), isAllocErr)
.assert(0 === w.alloc.impl(tooMuch))
.mustThrowMatching(()=>w.realloc(0, tooMuch), isAllocErr)
.assert(0 === w.realloc.impl(0, tooMuch));
}
// Check allocFromTypedArray()...
const byteList = [11,22,33]
const u = new Uint8Array(byteList);
m = w.allocFromTypedArray(u);
for(let i = 0; i < u.length; ++i){
T.assert(u[i] === byteList[i])
.assert(u[i] === w.getMemValue(m + i, 'i8'));
}
w.dealloc(m);
m = w.allocFromTypedArray(u.buffer);
for(let i = 0; i < u.length; ++i){
T.assert(u[i] === byteList[i])
.assert(u[i] === w.getMemValue(m + i, 'i8'));
}
w.dealloc(m);
T.mustThrowMatching(
()=>w.allocFromTypedArray(1),
'Value is not of a supported TypedArray type.'
);
}
// isPtr32()
{
const ip = w.isPtr32;
@ -521,11 +574,12 @@ self.sqlite3InitModule = sqlite3InitModule;
//log("allocCString()...");
{
const cstr = w.allocCString("hällo, world");
const n = w.cstrlen(cstr);
T.assert(13 === n)
const jstr = "hällo, world!";
const [cstr, n] = w.allocCString(jstr, true);
T.assert(14 === n)
.assert(0===w.getMemValue(cstr+n))
.assert(chr('d')===w.getMemValue(cstr+n-1));
.assert(chr('!')===w.getMemValue(cstr+n-1));
w.dealloc(cstr);
}
//log("scopedAlloc() and friends...");
@ -607,11 +661,13 @@ self.sqlite3InitModule = sqlite3InitModule;
rc = w.xCallWrapped('sqlite3_wasm_enum_json','utf8');
T.assert('string'===typeof rc).assert(rc.length>300);
if(haveWasmCTests()){
fw = w.xWrap('sqlite3_wasm_test_str_hello', 'utf8:free',['i32']);
rc = fw(0);
T.assert('hello'===rc);
rc = fw(1);
T.assert(null===rc);
if(!sqlite3.config.useStdAlloc){
fw = w.xWrap('sqlite3_wasm_test_str_hello', 'utf8:dealloc',['i32']);
rc = fw(0);
T.assert('hello'===rc);
rc = fw(1);
T.assert(null===rc);
}
if(w.bigIntEnabled){
w.xWrap.resultAdapter('thrice', (v)=>3n*BigInt(v));
@ -1415,7 +1471,7 @@ self.sqlite3InitModule = sqlite3InitModule;
const n = db.selectValue(sql);
T.assert(n>0 && db2.selectValue(sql) === n);
}finally{
if(db2) db2.close();
db2.close();
wasm.sqlite3_wasm_vfs_unlink(pVfs, filename);
}
}
@ -1454,8 +1510,7 @@ self.sqlite3InitModule = sqlite3InitModule;
assert(T.eqApprox(3.1,db.selectValue("select 3.0 + 0.1"))).
assert(T.eqApprox(1.3,db.selectValue("select asis(1 + 0.3)")));
let blobArg = new Uint8Array(2);
blobArg.set([0x68, 0x69], 0);
let blobArg = new Uint8Array([0x68, 0x69]);
let blobRc = db.selectValue("select asis(?1)", blobArg);
T.assert(blobRc instanceof Uint8Array).
assert(2 === blobRc.length).
@ -1465,8 +1520,7 @@ self.sqlite3InitModule = sqlite3InitModule;
assert(2 === blobRc.length).
assert(0x68==blobRc[0] && 0x69==blobRc[1]);
blobArg = new Int8Array(2);
blobArg.set([0x68, 0x69]);
blobArg = new Int8Array([0x68, 0x69]);
//debug("blobArg=",blobArg);
blobRc = db.selectValue("select asis(?1)", blobArg);
T.assert(blobRc instanceof Uint8Array).

View File

@ -61,7 +61,7 @@
urlArgsHtml.has('verbose') ? +urlArgsHtml.get('verbose') : 1
) || 1;
options.interval = (
urlArgsHtml.has('interval') ? +urlArgsHtml.get('interval') : 750
urlArgsHtml.has('interval') ? +urlArgsHtml.get('interval') : 1000
) || 1000;
options.iterations = (
urlArgsHtml.has('iterations') ? +urlArgsHtml.get('iterations') : 10

View File

@ -1,5 +1,5 @@
C Add\sloops\sand\srows\scounters\sto\s"USE\sTEMP\sB-TREE\sFOR\sORDER\sBY"\srecords.\sAlso\sfix\sthe\ssqliteHwtime()\sfunction\sso\sthat\sit\sreturns\sa\s64-bit\svalue.
D 2022-12-05T18:19:56.530
C Merge\slatest\strunk\schanges.
D 2022-12-05T18:26:37.073
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -491,10 +491,10 @@ 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 54ab8da16a01e78bf5767c0e7bd57af07bfeb3a71fbecd63a39b3dbeec967c4e
F ext/wasm/GNUmakefile bfa47f169468ca9db031105b0e336db29a88e93c3abd217d0bbb2b8731fa5413
F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20
F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b4d68c97d14944b48d55e06aa44f544a6f56a7fa2bcb6f9e030936a5b2a9479a
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 89af0612bad5c651f69e629c7e9689be6d3c8a92a9010da5dd90a87c1d86817a
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md 20a256f4aaae80035d2bb1c9e3e0a125570313a8d137d427471d7be10edde87a
F ext/wasm/api/extern-post-js.c-pp.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d
@ -503,16 +503,16 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f
F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4
F ext/wasm/api/sqlite3-api-glue.js b528207ba43f7740d1ade623f3f6b08a49f44ce7e9126915b78e1818c2466d8e
F ext/wasm/api/sqlite3-api-oo1.js c8b6c9ccb64cf93ca990ac689e98963735110aec21f98e04b55018f8e67b8147
F ext/wasm/api/sqlite3-api-prologue.js 42d6b316b542cf8e086f2f272460deb72dff184f1438a3377383cab99b08070b
F ext/wasm/api/sqlite3-api-glue.js 6fe39964605fda3b699f69365eed565b5172d29cab2c49bc057a43f9a93f9f36
F ext/wasm/api/sqlite3-api-oo1.js 91a7d7b9203fb0f031e6ba380a644a7f871e1798b388de399c01ed4087bac9e0
F ext/wasm/api/sqlite3-api-prologue.js 697a5989ad52a9ba7bc60b5436589bd05885ee2201d84c38c5e9af3876af3ba4
F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
F ext/wasm/api/sqlite3-opfs-async-proxy.js f79dd8d98ef3e0b55c10bb2bee7a3840fa967318e1f577c156aafc34664271d1
F ext/wasm/api/sqlite3-vfs-helper.js 4ad4faf02e1524bf0296be8452c00b5708dce6faf649468d0377e26a0b299263
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js b8889f182ba7b5c1be8bcf6f47b538519e3fff0e98d7cf8b9d1fa4a9afdfb8ce
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 29d6487a26b2fb6a471cde52c37ffee7c27ed6a91914b308c247e0706f454ffb
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
F ext/wasm/api/sqlite3-wasm.c 733bc939f93caef0df0b3ebfea14cbd528da580fdef1a35b1f69c2b3e044c7b7
F ext/wasm/api/sqlite3-wasm.c b0babf8435f31d21f28454fb81433aa538c68b23d0a4a251f0666fdec4e71f59
F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07
F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
F ext/wasm/common/testing.css 35889709547d89a6109ff83b25c11bbc91d8dd43aab8722e428655ca98880a06
F ext/wasm/common/whwasmutil.js dbe625a22bf0962cde1f958f2be604d27d2f97ee1b4e6ee0f19c6480aa36aeed
F ext/wasm/common/whwasmutil.js c1bc5715cd96728929cc31d788b16152ccbd6b2e111d2e88fbc9725247e67b4f
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
@ -531,17 +531,17 @@ F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98
F ext/wasm/demo-worker1-promiser.js b85a2bb1b918db4f09dfa24419241cb3edad7791389425c2505092e9b715017d
F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d
F ext/wasm/demo-worker1.js a619adffc98b75b66c633b00f747b856449a134a9a0357909287d80a182d70fa
F ext/wasm/dist.make 994cc61822694b123d4357731072937a54153fbe5d9b12c6cb95d5562d2766dc
F ext/wasm/dist.make 701694188a78c9a24bf44cdf529063f4b3a0e892adc1d20ed1619252738943f1
F ext/wasm/fiddle.make 2812c44c9bafb5be9c8767963d1b9f374d77af7795fcaa06483c03e7059dea74
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
F ext/wasm/fiddle/fiddle-worker.js b4a0c8ab6c0983218543ca771c45f6075449f63a1dcf290ae5a681b2cba8800d
F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715
F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2
F ext/wasm/index-dist.html c806b6005145b71d64240606e9c6e0bf56878ee8829c66fe7486cebf34b0e6b1
F ext/wasm/index.html 618ad5cbc07b55556a4e09931773761698a38323387d392046bda907f1ce4c52
F ext/wasm/index.html f151b7c7b5cfdc066567d556acd168e769efd4e982286dc5f849a5ee69ecd0ff
F ext/wasm/jaccwabyt/jaccwabyt.js 95f573de1826474c9605dda620ee622fcb1673ae74f191eb324c0853aa4dcb66
F ext/wasm/jaccwabyt/jaccwabyt.md 9aa6951b529a8b29f578ec8f0355713c39584c92cf1708f63ba0cf917cb5b68e
F ext/wasm/module-symbols.html b8eebafef8e536624bbe5f7a3da40c07a9062b843dfd3161a0bb72cbb6763dc5
F ext/wasm/module-symbols.html 980680c8acfa3c8ae6a5aa223512d1b8e78040ced20f8ba2c382129bc73ec028
F ext/wasm/scratchpad-wasmfs-main.html 20cf6f1a8f368e70d01e8c17200e3eaa90f1c8e1029186d836d14b83845fbe06
F ext/wasm/scratchpad-wasmfs-main.js 4c140457f4d6da9d646a49addd91edb6e9ad1643c6c48e3258b5bce24725dc18
F ext/wasm/speedtest1-wasmfs.html bc28eb29b69a73864b8d7aae428448f8b7e1de81d8bfb9bba99541322054dbd0
@ -553,11 +553,11 @@ F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d826
F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555e685bce3da8c3f
F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac
F ext/wasm/tester1-worker.html ead6bdcc6cca221deb0dc9855a56f376351dbf2294fd7978cd1609b3a56b245b
F ext/wasm/tester1-worker.html 29b1d87f7d51f70d61645719fee657f3787fe939bb695f27034c75404e8f1e6f
F ext/wasm/tester1.c-pp.html 74aa9b31c75f12490653f814b53c3dd39f40cd3f70d6a53a716f4e8587107399
F ext/wasm/tester1.c-pp.js e73a91eba4b59aaadd98f383c00a5101dbbbc52d937fff3162fc4761986f4a88
F ext/wasm/tester1.c-pp.js d096a8fadfd27caa680a4311b1d529551f8fe885a63dd27457c87b6008c64632
F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70
F ext/wasm/tests/opfs/concurrency/test.js 9315339ed27849e65890eda924a516562936525a4f3f162fa71aeb489b9dc707
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
F ext/wasm/wasmfs.make 7ab655788bf0b52dce4538acbd5b11cdbe77edd36a14af5dec6dfe1ec4ab25fc
@ -609,13 +609,13 @@ F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 25663175950c5c4404b9377840b7b4c6fe5c53b415caf43634c62f442c02a9a7
F src/main.c 954490392b74fb215378af3c75a9e1f4f559f19cb1567e5d77f3fbbb63909b4d
F src/malloc.c 3d4ec162214024ee071d85711b93bec25cd3371280aee3702b63bcf312ca8238
F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75
F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6
F src/mem5.c 5a3dbd8ac8a6501152a4fc1fcae9b0900c2d7eb0589c4ec7456fdde15725a26c
F src/memdb.c a42248bc04dc1f80da3511618a78956ed77b65058b73e251bde39061204e9f97
F src/memdb.c fa280078fb48c4bb7ef47e361cd958938a1a3c46a9a45f6622da6efcb57cc055
F src/memjournal.c c283c6c95d940eb9dc70f1863eef3ee40382dbd35e5a1108026e7817c206e8a0
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
@ -627,7 +627,7 @@ F src/notify.c 89a97dc854c3aa62ad5f384ef50c5a4a11d70fcc69f86de3e991573421130ed6
F src/os.c 81c9c1c52eab711e27e33fd51fe5788488d3a02bc1a71439857abbee5d0d2c97
F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
F src/os_kv.c 0e59600d25b72034c7666b8b7dcc527f039b5d9c16f24a7eca4c08c66f63c364
F src/os_kv.c 73f89ab97ecdb3216857d2acc8395103f89164eaadac87cce4e9e16445c89541
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
F src/os_unix.c 08191111a7040b8d5a6fff946f9fc9a11a0f83bac727c0415dfc5d030e1bc41f
F src/os_win.c 295fe45f18bd86f2477f4cd79f3377c6f883ceb941b1f46808665c73747f2345
@ -646,8 +646,8 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 321f29e431fbb71e594cc7026391a827a0270237597d2e2401244e7602dea8bd
F src/shell.c.in 8cfe0c7dbd3ac8f9eca40fdad85d90f22362a89ab9ad8d64826fd0ad5e408d13
F src/sqlite.h.in 3ba99a3c2b414b9ad36d06e2f273ab6077f5f74e4d79630aee047394b92f7c7f
F src/shell.c.in e7fc8db64df14d1893a86dce488770efdbb1007e44ec8cd5549769533bb419f2
F src/sqlite.h.in e72678d6b1b2e9b006db786d5d9ac534ccf58fff6612557290b6276d0d3a5a84
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h c4b9fa7a7e2bcdf850cfeb4b8a91d5ec47b7a00033bc996fd2ee96cbf2741f5f
F src/sqliteInt.h 0c9934acd88e0fa14f0d4743233b4cd7bd7bbc84099ba3cad50d8e69676ce2b9
@ -732,7 +732,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
F src/where.c bf470b5d1ba03af8d558a0c98cc1fa97b330e03a198a7af61895e5a2e8d93f20
F src/where.c 20f4f51d2d5fb19b984e6ea381b26cf627cc93e64dd9b2ce6a94531aec2f5916
F src/whereInt.h e25203e5bfee149f5f1225ae0166cfb4f1e65490c998a024249e98bb0647377c
F src/wherecode.c d3146e215f3a716c0e153ded68bfcc747aad550e114a79729bda887cf4ea6f00
F src/whereexpr.c 05295b44b54eea76d1ba766f0908928d0e20e990c249344c9521454d3d09c7ae
@ -1317,6 +1317,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
F test/memdb1.test 2c4e9cc10d21c6bf4e217d72b7f6b8ba9b2605971bb2c5e6df76018e189f98f5
F test/memdb2.test d1dc6058ee59f78c7f46f85e069bb974a981920f8c499f0167690d16c0b079f6
F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c
F test/memjournal2.test 6b9083cfaab9a3281ec545c3da2487999e8025fb7501bbae10f713f80c56454c
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
@ -1368,7 +1369,7 @@ F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/optfuzz-db01.c 9f2fa80b8f84ebbf1f2e8b13421a4e0477fe300f6686fbd76cac1d2db66e0fdc
F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041
F test/optfuzz.c 690430a0bf0ad047d5a168bf52b05b2ee97aedaad8c14337e9eb5050faa64994
F test/orderby1.test a4bba04b9c60a21e53486fbc173a596b29641a3b3a57a0f26a1cbef1360358e9
F test/orderby1.test 02cfd870127a7342170b829175c5c53e9e7405744451ac1aeb2f7e2b0c18ca76
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
@ -1501,7 +1502,7 @@ F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8e
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test e4b4de56f454708e0747b52915135baa2cbfec4965406d6eaf02a4a5c22a9880
F test/shell2.test c536c2aab4852608f8a606262330797abc4d964a4c2c782a7760f54ea1f17a6a
F test/shell2.test 1190b951373fdfe719bc6ac16962bc743dfa4355db8ae546c0bb9bf559a28d4a
F test/shell3.test 91febeac0412812bf6370abb8ed72700e32bf8f9878849414518f662dfd55e8a
F test/shell4.test 9abd0c12a7e20a4c49e84d5be208d2124fa6c09e728f56f1f4bee0f02853935f
F test/shell5.test c8b6c54f26ec537f8558273d7ed293ca3725ef42e6b12b8f151718628bd1473b
@ -1526,7 +1527,7 @@ F test/snapshot_fault.test f6c5ef7cb93bf92fbb4e864ecc5c87df7d3a250064838822db5b4
F test/snapshot_up.test a0a29c4cf33475fcef07c3f8e64af795e24ab91b4cc68295863402a393cdd41c
F test/soak.test 18944cf21b94a7fe0df02016a6ee1e9632bc4e8d095a0cb49d95e15d5cca2d5c
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b
F test/sort.test f86751134159abb5e5fd4381a0d7038c91013638cd1e3fa1d7850901f6df6196
F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0
F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5
F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c
@ -1885,7 +1886,7 @@ F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2a
F test/walvfs.test e1a6ad0f3c78e98b55c3d5f0889cf366cc0d0a1cb2bccb44ac9ec67384adc4a1
F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec
F test/wapptest.tcl 1bea58a6a8e68a73f542ee4fca28b771b84ed803bd0c9e385087070b3d747b3c x
F test/where.test d13cd7c24e80009d2b54e2f7a8893c457afa49c64f99359c9eb3fe668ba1d9d4
F test/where.test 98208c95b574269980132c347b4bdb8992c6d5fc30c1954938593336d12e7447
F test/where2.test 03c21a11e7b90e2845fc3c8b4002fc44cc2797fa74c86ee47d70bd7ea4f29ed6
F test/where3.test 5b4ffc0ac2ea0fe92f02b1244b7531522fe4d7bccf6fa8741d54e82c10e67753
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
@ -2041,7 +2042,7 @@ F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F tool/vdbe-compress.tcl 1dcb7632e57cf57105248029e6e162fddaf6c0fccb3bb9e6215603752c5a2d4a
F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh d58dc38367cc776550f90327e205d7946802d4004fb9f291fd8b81256bc1eedd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
@ -2066,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 622d8eb3724bee617b55d6fb71f1a2d683db6858065adced6bf3ce9525bcd6b5
R 26a74ba4d9b4917db1af945f6ebd0886
P 41a0e05e8c0fca3b803fe4bd017a157c172b2ca518356a2a4d4ed4f12d01a1e3 dc7dd2d3e50e7cc474b22f1b5b219da32bcd7aa1ba56864d1dbcf0d3a6fa06f2
R 656aefb1ecbcda39e45961b382db5e0d
U dan
Z 549ef47ca8c045470c46bb8ad599992d
Z eafa1697653e28cd3e4cfd55976da0a1
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
41a0e05e8c0fca3b803fe4bd017a157c172b2ca518356a2a4d4ed4f12d01a1e3
1a72777b1279f74f212fb2f675a4594a238e5d28f048879d7f5ad5287673c3c4

View File

@ -279,7 +279,7 @@ static void mallocWithAlarm(int n, void **pp){
** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391
** This provides a 256-byte safety margin for defense against 32-bit
** signed integer overflow bugs when computing memory allocation sizes.
** Parnoid applications might want to reduce the maximum allocation size
** Paranoid applications might want to reduce the maximum allocation size
** further for an even larger safety margin. 0x3fffffff or 0x0fffffff
** or even smaller would be reasonable upper bounds on the size of a memory
** allocations for most applications.

View File

@ -371,9 +371,22 @@ static int memdbLock(sqlite3_file *pFile, int eLock){
if( eLock==pThis->eLock ) return SQLITE_OK;
memdbEnter(p);
if( eLock>SQLITE_LOCK_SHARED ){
assert( pThis->eLock>=SQLITE_LOCK_SHARED );
if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){
rc = SQLITE_READONLY;
}else if( eLock==SQLITE_LOCK_EXCLUSIVE ){
/* Taking an EXCLUSIVE lock. Fail if we only have SHARED and any
** other client has any kind of write-lock. Also fail if any other
** client is holding read-lock. */
if( pThis->eLock<=SQLITE_LOCK_SHARED && p->nWrLock ){
rc = SQLITE_BUSY;
}else if( p->nRdLock>1 ){
rc = SQLITE_BUSY;
}
p->nWrLock = 1;
}else if( pThis->eLock<=SQLITE_LOCK_SHARED ){
/* Upgrading to RESERVED or PENDING from SHARED. Fail if any other
** client has a write-lock of any kind. */
if( p->nWrLock ){
rc = SQLITE_BUSY;
}else{

View File

@ -52,7 +52,9 @@ struct KVVfsFile {
char *aJrnl; /* Journal content */
int szPage; /* Last known page size */
sqlite3_int64 szDb; /* Database file size. -1 means unknown */
char *aData; /* Buffer to hold page data */
};
#define SQLITE_KVOS_SZ 133073
/*
** Methods for KVVfsFile
@ -493,6 +495,7 @@ static int kvvfsClose(sqlite3_file *pProtoFile){
SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass,
pFile->isJournal ? "journal" : "db"));
sqlite3_free(pFile->aJrnl);
sqlite3_free(pFile->aData);
return SQLITE_OK;
}
@ -541,7 +544,7 @@ static int kvvfsReadDb(
unsigned int pgno;
int got, n;
char zKey[30];
char aData[133073];
char *aData = pFile->aData;
assert( iOfst>=0 );
assert( iAmt>=0 );
SQLITE_KV_LOG(("xRead('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
@ -558,7 +561,8 @@ static int kvvfsReadDb(
pgno = 1;
}
sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno);
got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey, aData, sizeof(aData)-1);
got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey,
aData, SQLITE_KVOS_SZ-1);
if( got<0 ){
n = 0;
}else{
@ -566,7 +570,7 @@ static int kvvfsReadDb(
if( iOfst+iAmt<512 ){
int k = iOfst+iAmt;
aData[k*2] = 0;
n = kvvfsDecode(aData, &aData[2000], sizeof(aData)-2000);
n = kvvfsDecode(aData, &aData[2000], SQLITE_KVOS_SZ-2000);
if( n>=iOfst+iAmt ){
memcpy(zBuf, &aData[2000+iOfst], iAmt);
n = iAmt;
@ -625,7 +629,7 @@ static int kvvfsWriteDb(
KVVfsFile *pFile = (KVVfsFile*)pProtoFile;
unsigned int pgno;
char zKey[30];
char aData[131073];
char *aData = pFile->aData;
SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
assert( iAmt>=512 && iAmt<=65536 );
assert( (iAmt & (iAmt-1))==0 );
@ -834,6 +838,10 @@ static int kvvfsOpen(
}else{
pFile->zClass = "local";
}
pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ);
if( pFile->aData==0 ){
return SQLITE_NOMEM;
}
pFile->aJrnl = 0;
pFile->nJrnl = 0;
pFile->szPage = -1;

View File

@ -1880,7 +1880,7 @@ static int safeModeAuth(
"zipfile",
"zipfile_cds",
};
UNUSED_PARAMETER(zA2);
UNUSED_PARAMETER(zA1);
UNUSED_PARAMETER(zA3);
UNUSED_PARAMETER(zA4);
switch( op ){
@ -1895,7 +1895,7 @@ static int safeModeAuth(
case SQLITE_FUNCTION: {
int i;
for(i=0; i<ArraySize(azProhibitedFunctions); i++){
if( sqlite3_stricmp(zA1, azProhibitedFunctions[i])==0 ){
if( sqlite3_stricmp(zA2, azProhibitedFunctions[i])==0 ){
failIfSafeMode(p, "cannot use the %s() function in safe mode",
azProhibitedFunctions[i]);
}

View File

@ -7014,15 +7014,6 @@ int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
*/
void sqlite3_reset_auto_extension(void);
/*
** The interface to the virtual-table mechanism is currently considered
** to be experimental. The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.
**
** When the virtual-table mechanism stabilizes, we will declare the
** interface fixed, support it indefinitely, and remove this comment.
*/
/*
** Structures used by the virtual table interface
*/
@ -7264,7 +7255,7 @@ struct sqlite3_index_info {
** the [sqlite3_vtab_collation()] interface. For most real-world virtual
** tables, the collating sequence of constraints does not matter (for example
** because the constraints are numeric) and so the sqlite3_vtab_collation()
** interface is no commonly needed.
** interface is not commonly needed.
*/
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
@ -7423,16 +7414,6 @@ int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
*/
int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** The interface to the virtual-table mechanism defined above (back up
** to a comment remarkably similar to this one) is currently considered
** to be experimental. The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.
**
** When the virtual-table mechanism stabilizes, we will declare the
** interface fixed, support it indefinitely, and remove this comment.
*/
/*
** CAPI3REF: A Handle To An Open BLOB
** KEYWORDS: {BLOB handle} {BLOB handles}
@ -9636,7 +9617,7 @@ int sqlite3_vtab_nochange(sqlite3_context*);
** <li><p> Otherwise, "BINARY" is returned.
** </ol>
*/
SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
/*
** CAPI3REF: Determine if a virtual table query is DISTINCT

View File

@ -3092,7 +3092,15 @@ static int whereLoopAddBtreeIndex(
** seek only. Then, if this is a non-covering index, add the cost of
** visiting the rows in the main table. */
assert( pSrc->pTab->szTabRow>0 );
rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
/* The pProbe->szIdxRow is low for an IPK table since the interior
** pages are small. Thuse szIdxRow gives a good estimate of seek cost.
** But the leaf pages are full-size, so pProbe->szIdxRow would badly
** under-estimate the scanning cost. */
rCostIdx = pNew->nOut + 16;
}else{
rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
}
pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
@ -3472,7 +3480,7 @@ static int whereLoopAddBtree(
sPk.aiRowLogEst = aiRowEstPk;
sPk.onError = OE_Replace;
sPk.pTable = pTab;
sPk.szIdxRow = pTab->szTabRow;
sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */
sPk.idxType = SQLITE_IDXTYPE_IPK;
aiRowEstPk[0] = pTab->nRowLogEst;
aiRowEstPk[1] = 0;
@ -4803,37 +4811,56 @@ static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
** order.
*/
static LogEst whereSortingCost(
WhereInfo *pWInfo,
LogEst nRow,
int nOrderBy,
int nSorted
WhereInfo *pWInfo, /* Query planning context */
LogEst nRow, /* Estimated number of rows to sort */
int nOrderBy, /* Number of ORDER BY clause terms */
int nSorted /* Number of initial ORDER BY terms naturally in order */
){
/* TUNING: Estimated cost of a full external sort, where N is
/* Estimated cost of a full external sort, where N is
** the number of rows to sort is:
**
** cost = (3.0 * N * log(N)).
** cost = (K * N * log(N)).
**
** Or, if the order-by clause has X terms but only the last Y
** terms are out of order, then block-sorting will reduce the
** sorting cost to:
**
** cost = (3.0 * N * log(N)) * (Y/X)
** cost = (K * N * log(N)) * (Y/X)
**
** The (Y/X) term is implemented using stack variable rScale
** below.
** The constant K is at least 2.0 but will be larger if there are a
** large number of columns to be sorted, as the sorting time is
** proportional to the amount of content to be sorted. The algorithm
** does not currently distinguish between fat columns (BLOBs and TEXTs)
** and skinny columns (INTs). It just uses the number of columns as
** an approximation for the row width.
**
** And extra factor of 2.0 or 3.0 is added to the sorting cost if the sort
** is built using OP_IdxInsert and OP_Sort rather than with OP_SorterInsert.
*/
LogEst rScale, rSortCost;
assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
rSortCost = nRow + rScale + 16;
LogEst rSortCost, nCol;
assert( pWInfo->pSelect!=0 );
assert( pWInfo->pSelect->pEList!=0 );
/* TUNING: sorting cost proportional to the number of output columns: */
nCol = sqlite3LogEst((pWInfo->pSelect->pEList->nExpr+59)/30);
rSortCost = nRow + nCol;
if( nSorted>0 ){
/* Scale the result by (Y/X) */
rSortCost += sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
}
/* Multiple by log(M) where M is the number of output rows.
** Use the LIMIT for M if it is smaller. Or if this sort is for
** a DISTINCT operator, M will be the number of distinct output
** rows, so fudge it downwards a bit.
*/
if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
nRow = pWInfo->iLimit;
if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){
rSortCost += 10; /* TUNING: Extra 2.0x if using LIMIT */
if( nSorted!=0 ){
rSortCost += 6; /* TUNING: Extra 1.5x if also using partial sort */
}
if( pWInfo->iLimit<nRow ){
nRow = pWInfo->iLimit;
}
}else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){
/* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT
** reduces the number of output rows by a factor of 2 */
@ -4985,11 +5012,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo, nRowEst, nOrderBy, isOrdered
);
}
/* TUNING: Add a small extra penalty (5) to sorting as an
/* TUNING: Add a small extra penalty (3) to sorting as an
** extra encouragment to the query planner to select a plan
** where the rows emerge in the correct order without any sorting
** required. */
rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5;
rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 3;
WHERETRACE(0x002,
("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",

66
test/memdb2.test Normal file
View File

@ -0,0 +1,66 @@
# 2022-12-05
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is the "memdb" VFS
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix memdb1
do_not_use_codec
ifcapable !deserialize {
finish_test
return
}
db close
#-------------------------------------------------------------------------
# Test that when using a memdb database, it is not possible to upgrade
# to an EXCLUSIVE lock if some other client is holding SHARED.
#
sqlite3 db file:/test.db?vfs=memdb -uri 1
sqlite3 db2 file:/test.db?vfs=memdb -uri 1
do_execsql_test 1.1 {
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(1, 2);
}
do_execsql_test -db db2 1.2 {
BEGIN;
SELECT * FROM t1;
} {1 2}
do_execsql_test 1.3 {
BEGIN;
INSERT INTO t1 VALUES(3, 4);
}
do_catchsql_test 1.4 {
COMMIT
} {1 {database is locked}}
do_execsql_test -db db2 1.5 {
SELECT * FROM t1;
END;
} {1 2}
do_execsql_test 1.6 {
COMMIT
} {}
do_execsql_test -db db2 1.7 {
SELECT * FROM t1
} {1 2 3 4}
finish_test

View File

@ -43,6 +43,7 @@ do_test 1.0 {
(NULL, 1, 3, 'one-c'),
(NULL, 2, 1, 'two-a'),
(NULL, 3, 1, 'three-a');
ANALYZE;
COMMIT;
}
} {}
@ -180,6 +181,7 @@ do_test 2.0 {
(1, 3, 'one-c'),
(20, 1, 'two-a'),
(3, 1, 'three-a');
ANALYZE;
COMMIT;
}
} {}
@ -327,6 +329,7 @@ do_test 3.0 {
(NULL, 1, 3, 'one-c'),
(NULL, 2, 1, 'two-a'),
(NULL, 3, 1, 'three-a');
ANALYZE;
COMMIT;
}
} {}

View File

@ -191,4 +191,16 @@ do_test shell2-1.4.7 {
SELECT 'unclosed;
^--- error here}}
# Verify that safe mode rejects certain UDFs
# Reported at https://sqlite.org/forum/forumpost/07beac8056151b2f
do_test shell2-1.4.8 {
catchcmd "-safe :memory:" {
SELECT edit('DoNotCare');}
} {1 {line 2: cannot use the edit() function in safe mode}}
do_test shell2-1.4.9 {
catchcmd "-safe :memory:" {
SELECT writefile('DoNotCare', x'');}
} {1 {line 2: cannot use the writefile() function in safe mode}}
finish_test

View File

@ -595,4 +595,36 @@ do_execsql_test 17.1 {
SELECT * FROM sqlite_master ORDER BY sql;
} {}
# 2022-12-03 Ticket e8b674241947eb3b
# Improve estimates for the cost of sorting relative
# to the cost of doing an index lookup, so as to get
# a better query plan. See the ticket for a deetailed
# example.
#
reset_db
do_execsql_test 18.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<50)
-- increase to 5000 for actual test data ----^^
INSERT INTO t1(a,b,c) SELECT x, random()%5000, random()%5000 FROM c;
CREATE TABLE t2(d,e,f);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<500)
-- increase to 50000 for actual test data -----^^^
INSERT INTO t2(d,e,f) SELECT
NULLIF(0, random()%2), random()%5000, random()%5000
FROM c;
ANALYZE;
UPDATE sqlite_stat1 SET stat='50000' WHERE tbl='t2';
UPDATE sqlite_stat1 SET stat='5000' WHERE tbl='t1';
ANALYZE sqlite_schema;
} {}
do_execsql_test 18.2 {
EXPLAIN QUERY PLAN
SELECT a FROM t1 JOIN t2
WHERE a IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
AND a=CASE WHEN d IS NOT NULL THEN e ELSE f END
ORDER BY a;
} {/.*SCAN t2.*SEARCH t1.*/}
# ^^^^^^^--^^^^^^^^^--- t2 should be the outer loop.
finish_test

View File

@ -545,6 +545,7 @@ do_test where-6.1 {
CREATE INDEX t3acb ON t3(a,c,b);
INSERT INTO t3 SELECT w, 101-w, y FROM t1;
SELECT count(*), sum(a), sum(b), sum(c) FROM t3;
ANALYZE;
}
} {100 5050 5050 348550}
do_test where-6.2 {

View File

@ -66,6 +66,8 @@ foreach stmt $allstmt {
puts "********************************************************************"
puts [string trim $sql($stmt)]
puts "Execution count: $cnt($stmt)"
set tcx 0
set ttx 0
for {set i 0} {[info exists stat($stmt,$i)]} {incr i} {
foreach {cx tx detail} $stat($stmt,$i) break
if {$cx==0} {
@ -74,7 +76,11 @@ foreach stmt $allstmt {
set ax [expr {$tx/$cx}]
}
puts [format {%8d %12d %12d %4d %s} $cx $tx $ax $i $detail]
incr tcx $cx
incr ttx $tx
}
set tax [expr {$tcx>0?$ttx/$tcx:0}]
puts [format {%8d %12d %12d TOTAL} $tcx $ttx $tax]
}
puts "********************************************************************"
puts "OPCODES:"