1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Merge trunk changes into this branch.

FossilOrigin-Name: 9945206e6e26a48a49b9747650d299eb983cc21a3a61c621cd81f0bbc85a74d7
This commit is contained in:
dan
2024-09-24 15:43:52 +00:00
27 changed files with 309 additions and 124 deletions

View File

@ -1653,7 +1653,7 @@ tidy:
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE)
rm -f *.dll *.lib *.exp *.def *.pc *.vsix *.so *.dylib pkgIndex.tcl
rm -f sqlite3_analyzer$(TEXE)
rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE)
rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE)
rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE)
rm -f threadtest5$(TEXE)

View File

@ -1907,6 +1907,10 @@ fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
fuzzcheck-asan.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) /fsanitize=address $(FUZZCHECK_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
run-fuzzcheck: fuzzcheck.exe fuzzcheck-asan.exe
fuzzcheck --spinner $(FUZZDB)
fuzzcheck-asan --spinner $(FUZZDB)
ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@ -2775,7 +2779,7 @@ clean:
del /Q sqlite3.c sqlite3-*.c sqlite3.h 2>NUL
del /Q sqlite3rc.h 2>NUL
del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c sqlite3-rsync.exe 2>NUL
del /Q sqlite-*-output.vsix 2>NUL
del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL
del /Q sqltclsh.* 2>NUL

View File

@ -428,6 +428,8 @@ do_execsql_test 5.0 {
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
INSERT INTO t2 SELECT (i-1)/20, (i-1)/5 FROM s;
CREATE INDEX i1 ON t1( lower(a) );
}
do_candidates_test 5.1 {
SELECT * FROM t1,t2 WHERE (b=? OR a=?) AND (c=? OR d=?)
@ -457,6 +459,7 @@ do_execsql_test 5.3 {
ANALYZE;
SELECT * FROM sqlite_stat1 ORDER BY 1, 2;
} {
t1 i1 {100 50}
t1 t1_idx_00000061 {100 50}
t1 t1_idx_00000062 {100 20}
t1 t1_idx_000123a7 {100 50 17}
@ -491,4 +494,17 @@ USE TEMP B-TREE FOR ORDER BY
}}
}
do_execsql_test 6.0 {
CREATE TABLE x1(a, b, c, d);
CREATE INDEX x1ab ON x1(a, lower(b));
CREATE INDEX x1dcba ON x1(d, b+c, a);
}
do_candidates_test 6.1 {
SELECT * FROM x1 WHERE b=? ORDER BY a;
} {
CREATE INDEX x1_idx_0001267f ON x1(b, a);
CREATE INDEX x1_idx_00000062 ON x1(b);
}
finish_test

View File

@ -1623,6 +1623,12 @@ static int idxPopulateOneStat1(
const char *zComma = zCols==0 ? "" : ", ";
const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
if( zName==0 ){
/* This index contains an expression. Ignore it. */
sqlite3_free(zCols);
sqlite3_free(zOrder);
return sqlite3_reset(pIndexXInfo);
}
zCols = idxAppendText(&rc, zCols,
"%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s",
zComma, zName, nCol, zName, zColl

View File

@ -40,7 +40,7 @@
** modification-time of the target file is set to this value before
** returning.
**
** If three or more arguments are passed to this function and an
** If five or more arguments are passed to this function and an
** error is encountered, an exception is raised.
**
** READFILE(FILE):

View File

@ -416,7 +416,7 @@ static const char *lockName(int eLock){
const char *azLockNames[] = {
"NONE", "SHARED", "RESERVED", "PENDING", "EXCLUSIVE"
};
if( eLock<0 || eLock>=sizeof(azLockNames)/sizeof(azLockNames[0]) ){
if( eLock<0 || eLock>=(int)(sizeof(azLockNames)/sizeof(azLockNames[0])) ){
return "???";
}else{
return azLockNames[eLock];

View File

@ -202,6 +202,7 @@ foreach {tn sql1 at sql2} {
sqlite3changegroup grp
grp schema db main
breakpoint
grp add $C1
grp add $C2
set T1 [grp output]

View File

@ -56,4 +56,28 @@ do_faultsim_test 1 -faults oom* -prep {
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
ALTER TABLE t1 ADD COLUMN c DEFAULT 'abcdefghijklmnopqrstuvwxyz';
}
faultsim_save_and_close
do_faultsim_test 2 -faults oom-t* -prep {
faultsim_restore_and_reopen
db eval {SELECT * FROM sqlite_schema}
} -body {
sqlite3session S db main
S attach *
execsql {
DELETE FROM t1 WHERE a = 1;
}
} -test {
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
catch { S delete }
}
finish_test

View File

@ -82,6 +82,7 @@ do_execsql_test 1.5 {
UPDATE p1 SET c=12345 WHERE a = 45;
}
breakpoint
sqlite3changeset_apply_v2 -noaction db $C conflict
do_execsql_test 1.6 {
SELECT * FROM c1

View File

@ -74,6 +74,10 @@ struct SessionBuffer {
** input data. Input data may be supplied either as a single large buffer
** (e.g. sqlite3changeset_start()) or using a stream function (e.g.
** sqlite3changeset_start_strm()).
**
** bNoDiscard:
** If true, then the only time data is discarded is as a result of explicit
** sessionDiscardData() calls. Not within every sessionInputBuffer() call.
*/
struct SessionInput {
int bNoDiscard; /* If true, do not discard in InputBuffer() */
@ -1757,16 +1761,19 @@ static void sessionPreupdateOneChange(
for(i=0; i<(pTab->nCol-pTab->bRowid); i++){
sqlite3_value *p = 0;
if( op!=SQLITE_INSERT ){
TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p);
assert( trc==SQLITE_OK );
/* This may fail if the column has a non-NULL default and was added
** using ALTER TABLE ADD COLUMN after this record was created. */
rc = pSession->hook.xOld(pSession->hook.pCtx, i, &p);
}else if( pTab->abPK[i] ){
TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p);
assert( trc==SQLITE_OK );
}
if( rc==SQLITE_OK ){
/* This may fail if SQLite value p contains a utf-16 string that must
** be converted to utf-8 and an OOM error occurs while doing so. */
rc = sessionSerializeValue(0, p, &nByte);
}
if( rc!=SQLITE_OK ) goto error_out;
}
if( pTab->bRowid ){
@ -5124,15 +5131,21 @@ static int sessionChangesetApply(
int nTab = 0; /* Result of sqlite3Strlen30(zTab) */
SessionApplyCtx sApply; /* changeset_apply() context object */
int bPatchset;
u64 savedFlag = db->flags & SQLITE_FkNoAction;
assert( xConflict!=0 );
sqlite3_mutex_enter(sqlite3_db_mutex(db));
if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){
db->flags |= ((u64)SQLITE_FkNoAction);
db->aDb[0].pSchema->schema_cookie -= 32;
}
pIter->in.bNoDiscard = 1;
memset(&sApply, 0, sizeof(sApply));
sApply.bRebase = (ppRebase && pnRebase);
sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP);
sqlite3_mutex_enter(sqlite3_db_mutex(db));
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
}
@ -5294,6 +5307,12 @@ static int sessionChangesetApply(
sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
sqlite3_free((char*)sApply.constraints.aBuf);
sqlite3_free((char*)sApply.rebase.aBuf);
if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){
assert( db->flags & SQLITE_FkNoAction );
db->flags &= ~((u64)SQLITE_FkNoAction);
db->aDb[0].pSchema->schema_cookie -= 32;
}
sqlite3_mutex_leave(sqlite3_db_mutex(db));
return rc;
}
@ -5322,12 +5341,6 @@ int sqlite3changeset_apply_v2(
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1);
u64 savedFlag = db->flags & SQLITE_FkNoAction;
if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){
db->flags |= ((u64)SQLITE_FkNoAction);
db->aDb[0].pSchema->schema_cookie -= 32;
}
if( rc==SQLITE_OK ){
rc = sessionChangesetApply(
@ -5335,11 +5348,6 @@ int sqlite3changeset_apply_v2(
);
}
if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){
assert( db->flags & SQLITE_FkNoAction );
db->flags &= ~((u64)SQLITE_FkNoAction);
db->aDb[0].pSchema->schema_cookie -= 32;
}
return rc;
}
@ -5660,6 +5668,9 @@ static int sessionChangesetExtendRecord(
sessionAppendBlob(pOut, aRec, nRec, &rc);
if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){
rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt);
if( rc==SQLITE_OK && SQLITE_ROW!=sqlite3_step(pTab->pDfltStmt) ){
rc = sqlite3_errcode(pGrp->db);
}
}
for(ii=nCol; rc==SQLITE_OK && ii<pTab->nCol; ii++){
int eType = sqlite3_column_type(pTab->pDfltStmt, ii);
@ -5676,6 +5687,7 @@ static int sessionChangesetExtendRecord(
}
if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){
sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal);
pOut->nBuf += 8;
}
break;
}
@ -5815,6 +5827,8 @@ static int sessionOneChangeToHash(
u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2];
int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2;
assert( nRec>0 );
/* Ensure that only changesets, or only patchsets, but not a mixture
** of both, are being combined. It is an error to try to combine a
** changeset and a patchset. */
@ -5892,6 +5906,7 @@ static int sessionChangesetToHash(
int nRec;
int rc = SQLITE_OK;
pIter->in.bNoDiscard = 1;
while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){
rc = sessionOneChangeToHash(pGrp, pIter, bRebase);
if( rc!=SQLITE_OK ) break;

View File

@ -1159,7 +1159,7 @@ clean:
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE)
rm -f *.dll *.lib *.exp *.def *.pc *.vsix
rm -f sqlite3_analyzer$(TEXE)
rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE)
rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE)
rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE)
rm -f threadtest5$(TEXE)

View File

@ -1,11 +1,11 @@
C Fix\sthe\sfts5\sxInstToken()\sAPI\sfor\sprefix\squeries\sthat\sdo\snot\suse\sprefix-indexes.\sThis\sis\sexperimental.
D 2024-09-14T20:30:14.441
C Merge\strunk\schanges\sinto\sthis\sbranch.
D 2024-09-24T15:43:52.339
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 31368ad3e1800bb5f311adede543ee456ca7d2595403c7f131797ae65a7d415c
F Makefile.in fa448c4c0567623fd140efebecb570ab58d955d766a5ea0fd8a94e9b5697007c
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
F Makefile.msc 62ace0005c53b52f189c20c1d6d8fa4dbd2a37c90d9c1362b60f4fb4c841fa15
F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6
F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159
F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@ -57,8 +57,8 @@ F ext/consio/console_io.c d2b74afae8d301de2e8447b1045fcd33eb59df13bf581d906d99c7
F ext/consio/console_io.h b5ebe34aa15b357621ebbea3d3f2e2b24750d4280b5802516409e23947fd9ee5
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
F ext/expert/expert1.test 661f873fd451127edf822ef0d520088faa319135f6a15bd10be6801ac284ac9b
F ext/expert/sqlite3expert.c 8b09aeb2b95a9fca8b6628b522bf4d69aa746ff64c38eb1e99a9b5fad8cf03b9
F ext/expert/expert1.test b10f9e20f64102a015c0fcf54cb7b7680266b397e91d93cdad45f57857cdfba6
F ext/expert/sqlite3expert.c df417a6d91873a74d35daa9259171647c23c6601415e938e8a71702703f3d677
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
F ext/expert/test_expert.c b767b2039a0df707eb3147e86bcf68b252d8455d9a41774b1a836cd052ceca70
F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee
@ -400,7 +400,7 @@ F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f82
F ext/misc/decimal.c 172cf81a8634e6a0f0bedaf71a8372fee63348cf5a3c4e1b78bb233c35889fdc
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b
F ext/misc/fileio.c 916638042f318701460485032e33981056747d0f92e6757aa9499f2363ea7047
F ext/misc/fileio.c 001179b29735639c607586c9e9398c92505c0833de06eefc27e13acf60dd1577
F ext/misc/fossildelta.c 8c026e086e406e2b69947f1856fa3b848fff5379962276430d10085b8756b05a
F ext/misc/fuzzer.c 8b28acf1a7e95d50e332bdd47e792ff27054ad99d3f9bc2e91273814d4b31a5a
F ext/misc/ieee754.c 62a90978204d2c956d5036eb89e548e736ca5fac0e965912867ddd7bb833256d
@ -436,7 +436,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20
F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d
F ext/misc/vfstrace.c 03f90dd465968e01f5d1d3e79c36cbc53a5bfe1bd55d239435ce94df19d5b0ac
F ext/misc/vfstrace.c ac76a4ac4d907774fd423cc2b61410c756f9d0782e27cf6032e058594accaaca
F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668
@ -576,7 +576,7 @@ F ext/session/sessionG.test 3efe388282d641b65485b5462e67851002cd91a282dc95b685d0
F ext/session/sessionH.test 71bbff6b1abb2c4ac62b84dee53273c37e0b21e5fde3aed80929403e091ef859
F ext/session/session_common.tcl e5598096425486b363718e2cda48ee85d660c96b4f8ea9d9d7a4c3ef514769da
F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3
F ext/session/sessionalter.test 460bdac2832a550519f6bc32e5db2c0cee94f335870aaf25a3a403a81ab20e17
F ext/session/sessionalter.test e852acb3d2357aac7d0b920a2109da758c4331bfdf85b41d39aa3a8c18914f65
F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b85419035bc04b45ee
F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf
F ext/session/sessionchange.test 77c4702050f24270b58070e2cf01c95c3d232a3ef164b70f31974b386ce69903
@ -584,10 +584,10 @@ F ext/session/sessionconflict.test 8b8cbd98548e2e636ddc17d0986276f60e833fb865617
F ext/session/sessiondiff.test e89f7aedcdd89e5ebac3a455224eb553a171e9586fc3e1e6a7b3388d2648ba8d
F ext/session/sessionfault.test c2b43d01213b389a3f518e90775fca2120812ba51e50444c4066962263e45c11
F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576dc79ed344c46fbf41c
F ext/session/sessionfault3.test 7c7547202775de268f3fe6f074c4d0d165151829710b4e64f90d4a01645ba9e7
F ext/session/sessionfault3.test ce0b5d182133935c224d72507dbf1c5be1a1febf7e85d0b0fbd6d2f724b32b96
F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25
F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09
F ext/session/sessionnoact.test 506526a5fe29421ecc50d371774ef1bb04cbd9d906a8a468f0556cdbde184c22
F ext/session/sessionnoact.test 2563dff62a2a80dc7c88002241b2fd1578c3e5438735e180fb7e941ebbc66214
F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7
F ext/session/sessionnoop2.test de4672dce88464396ec9f30ed08c6c01643a69c53ae540fadbbf6d30642d64e8
F ext/session/sessionrebase.test 702378bdcb5062f1106e74457beca8797d09c113a81768734a58b197b5b334e2
@ -595,7 +595,7 @@ F ext/session/sessionrowid.test 85187c2f1b38861a5844868126f69f9ec62223a03449a98a
F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795
F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544a806421b85dc2dec
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
F ext/session/sqlite3session.c c7473aafbd88f796391a8c25aa90975a8f3729ab7f4f8cf74ab9d3b014e10abe
F ext/session/sqlite3session.c 3d0a7f0f7a1c946e01818c716a55a40ae30542a29a9045cb05daf7fb658cdafa
F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b
F ext/session/test_session.c aa29abdcc9011ac02f4fa38e8ede226106eaeee7c3ea7d8b2b999a124e0c368c
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
@ -688,7 +688,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
F main.mk 8b9c0252aef57b5b2a10f34b8b46e89f9ed06bdccef1df98673a12f34e9b3e79
F main.mk 67e622f31d10fee8f0f62655b4f9b47cd97fe70a125674ca6754b3549d69cc0e
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@ -717,7 +717,7 @@ F src/ctime.c b224d3db0f28c4a5f1407c50107a0a8133bd244ff3c7f6f8cedeb896a8cf1b64
F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
F src/dbpage.c 12e49515d67d4a59625d71f9aa42499556cfdc2e4f1ea49086e674a7f47f46e5
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
F src/delete.c 444c4d1eaac40103461e3b6f0881846dd3aafc1cec1dd169d3482fa331667da7
F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
F src/expr.c 6d5f2c38fe3ec06a7eac599dac822788b36064124e20112a844e9cd5156cb239
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
@ -731,7 +731,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c e7b53893f9fb3ad76baa8513f85c167b34d5c8e25ce64608db440f5637d0fe9e
F src/main.c 4db6e3bde55ba0b24ccc83600c2b6ea11429f61ce7b3a2e7e3b42e1b45366c3e
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@ -763,17 +763,17 @@ F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
F src/pragma.c 52bfbf6dfd668b69b5eb9bd1186e3a67367c8453807150d6e75239229924f684
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce
F src/prepare.c 3ba0ad907b7773ed642f66cea8a2c9c8edc18841aa1050b6218dbb3479e86225
F src/printf.c 6a87534ebfb9e5346011191b1f3a7ebc457f5938c7e4feeea478ecf53f6a41b2
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 2c127880c0634962837f16f2f48a295e514357af959330cc038de73015d5b5e8
F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
F src/shell.c.in 375f8a183126be96ec73db4e42c57917ff10a0900846b1b722dd4f8cef537812
F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 889cd632f4386bbd8619b166abb7d25f1c8ce6514e90cb7f22f63bd530fc6107
F src/sqliteInt.h 5978cbb11becc3ce6471015d770d95f694ece06336c496f691df1b02460e9cd5
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@ -835,25 +835,25 @@ F src/treeview.c 88aa39b754f5ef7214385c1bbbdd2f3dc20efafeed0cf590e8d1199b9c6e44a
F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461
F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508
F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
F src/utf.c 7bc550af6f3ddd5f5dc82d092c41f728acb760c92e0b47f391963b01ae52569b
F src/util.c 5d1a0134cf4240648d1c6bb5cc8efaca0ea2b5d5c840985aec7e947271f04375
F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
F src/vdbe.c be5f58bc29f60252e041a618eae59e8d57d460ba136c5403cf0abf955560c457
F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df
F src/vdbeaux.c 25d685cafe119ff890c94345e884ea558a6b5d823bfa52ba708eb8ff3c70aa71
F src/vdbeInt.h af7d7e8291edd0b19f2cd698e60e4d4031078f9a2f2328ac8f0b7efb134f8a1d
F src/vdbeapi.c 53c7e26a2c0821a892b20eee2cde4656e31998212f3d515576c780dfaa45fd17
F src/vdbeaux.c 676dbee99b4febdd94bc9658667a2e3bc413c4c0e356242d90f98a1155d513e5
F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797
F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89
F src/vdbemem.c df568ef0187e4be2788c35174f6d9b8566ab9475f9aff2d73907ed05aa5684b2
F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
F src/vtab.c 5fb499d20494b7eecaadb7584634af9afcb374cb0524912b475fcb1712458a1b
F src/vtab.c 316cd48e9320660db3047cd306cd056e4361180cebb4d0f10a39244e10c11422
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c ef68130ba330ee18c1cb22da36a881c82e3a3b109badbdc6a9b9acaf788a6688
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
F src/where.c 7fb55836eb7fd07f0a0d8400c50619fc02cda1f46a617cfb003c2990f040193d
F src/where.c 461d41017d900d4248a268df96d2d30506c4dcc2257f4167c4f46072003ce2cf
F src/whereInt.h a5d079c346a658b7a6e9e47bb943d021e02fa1e6aed3b964ca112112a4892192
F src/wherecode.c 5172d647798134e7c92536ddffe7e530c393d79b5dedd648b88faf2646c65baf
F src/whereexpr.c 44f41ae554c7572e1de1485b3169b233ee04d464b2ee5881687ede3bf07cacfa
@ -1287,7 +1287,7 @@ F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9
F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
F test/hook.test 18cae9140fa7f9a6f346e892a3fe3e31b2ca0be1494cd01b918adb74281016a6
F test/hook.test 3481a68009fe143e3363fca922f6fc7a1e1f3776c51e42777f1a01b26ad2a9c8
F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
F test/icu.test 8da7d52cd9722c82f33b0466ed915460cb03c23a38f18a9a2d3ff97da9a4a8c0
F test/ieee754.test b0945d12be7d255f3dfa18e2511b17ca37e0edd2b803231c52d05b86c04ab26e
@ -2175,7 +2175,7 @@ F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x
F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60
F tool/sqldiff.c 847fc8fcfddf5ce4797b7394cad6372f2f5dc17d8186e2ef8fb44d50fae4f44a
F tool/sqlite3-rsync.c 00c9b4483851ca0337dff4b544ee39dffa8cdbe9dc55cd51d391590fd1f03763
F tool/sqlite3-rsync.c 187b262035c1159b047dbfa1959c168b87b5a153b63465e8c8bd1b54fabf4460
F tool/sqlite3_analyzer.c.in 8da2b08f56eeac331a715036cf707cc20f879f231362be0c22efd682e2b89b4f
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
@ -2214,11 +2214,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 50762ba0783a04e0dcd9456a1ae17d875b0a9272f2f09854a23d9d5253761e9f
R 7d932f341b9d462f57fdca7d1de99fb1
T *branch * fts5-tokendata-prefix
T *sym-fts5-tokendata-prefix *
T -sym-trunk *
P 97c2824f471e7e622c4a166947a6e8162cae891345101539829a6fcec83373fe 42bb941584a1ac922ee6b0b6ecadce71c9259555563cf49913a6f820f3f9b887
R cb71c4478793484afa282b1a3cf11afa
U dan
Z 82ecce364e38343eb4f3cc0cc45881c8
Z efd6491e97a3bc8cd929e608bea6d1a9
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
97c2824f471e7e622c4a166947a6e8162cae891345101539829a6fcec83373fe
9945206e6e26a48a49b9747650d299eb983cc21a3a61c621cd81f0bbc85a74d7

View File

@ -75,6 +75,7 @@ void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){
** is for a top-level SQL statement.
*/
static int vtabIsReadOnly(Parse *pParse, Table *pTab){
assert( IsVirtual(pTab) );
if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){
return 1;
}

View File

@ -3482,6 +3482,7 @@ static int openDatabase(
if( ((1<<(flags&7)) & 0x46)==0 ){
rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */
}else{
if( zFilename==0 ) zFilename = ":memory:";
rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
}
if( rc!=SQLITE_OK ){

View File

@ -1007,12 +1007,24 @@ static int sqlite3Prepare16(
if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
return SQLITE_MISUSE_BKPT;
}
/* Make sure nBytes is non-negative and correct. It should be the
** number of bytes until the end of the input buffer or until the first
** U+0000 character. If the input nBytes is odd, convert it into
** an even number. If the input nBytes is negative, then the input
** must be terminated by at least one U+0000 character */
if( nBytes>=0 ){
int sz;
const char *z = (const char*)zSql;
for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){}
nBytes = sz;
}else{
int sz;
const char *z = (const char*)zSql;
for(sz=0; z[sz]!=0 || z[sz+1]!=0; sz += 2){}
nBytes = sz;
}
sqlite3_mutex_enter(db->mutex);
zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
if( zSql8 ){
@ -1026,7 +1038,7 @@ static int sqlite3Prepare16(
** the same number of characters into the UTF-16 string.
*/
int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8));
*pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
*pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, nBytes, chars_parsed);
}
sqlite3DbFree(db, zSql8);
rc = sqlite3ApiExit(db, rc);

View File

@ -486,7 +486,7 @@ static int lookupName(
*/
if( cntTab==0
|| (cntTab==1
&& ALWAYS(pMatch!=0)
&& pMatch!=0
&& ALWAYS(pMatch->pSTab!=0)
&& (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0
&& (pTab->tabFlags & TF_Ephemeral)==0)
@ -1119,8 +1119,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
/* Resolve function names
*/
case TK_FUNCTION: {
ExprList *pList = pExpr->x.pList; /* The argument list */
int n = pList ? pList->nExpr : 0; /* Number of arguments */
ExprList *pList; /* The argument list */
int n; /* Number of arguments */
int no_such_func = 0; /* True if no such function exists */
int wrong_num_args = 0; /* True if wrong number of arguments */
int is_agg = 0; /* True if is an aggregate function */
@ -1133,6 +1133,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#endif
assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER );
pList = pExpr->x.pList;
n = pList ? pList->nExpr : 0;
zId = pExpr->u.zToken;
pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
if( pDef==0 ){

View File

@ -5267,7 +5267,7 @@ int sqlite3GetInt32(const char *, int*);
int sqlite3GetUInt32(const char*, u32*);
int sqlite3Atoi(const char*);
#ifndef SQLITE_OMIT_UTF16
int sqlite3Utf16ByteLen(const void *pData, int nChar);
int sqlite3Utf16ByteLen(const void *pData, int nByte, int nChar);
#endif
int sqlite3Utf8CharLen(const char *pData, int nByte);
u32 sqlite3Utf8Read(const u8**);

View File

@ -514,20 +514,22 @@ char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 enc){
}
/*
** zIn is a UTF-16 encoded unicode string at least nChar characters long.
** zIn is a UTF-16 encoded unicode string at least nByte bytes long.
** Return the number of bytes in the first nChar unicode characters
** in pZ. nChar must be non-negative.
** in pZ. nChar must be non-negative. Surrogate pairs count as a single
** character.
*/
int sqlite3Utf16ByteLen(const void *zIn, int nChar){
int sqlite3Utf16ByteLen(const void *zIn, int nByte, int nChar){
int c;
unsigned char const *z = zIn;
unsigned char const *zEnd = &z[nByte-1];
int n = 0;
if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++;
while( n<nChar ){
while( n<nChar && ALWAYS(z<=zEnd) ){
c = z[0];
z += 2;
if( c>=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2;
if( c>=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2;
n++;
}
return (int)(z-(unsigned char const *)zIn)

View File

@ -543,6 +543,7 @@ struct PreUpdate {
Mem *aNew; /* Array of new.* values */
Table *pTab; /* Schema object being updated */
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
sqlite3_value **apDflt; /* Array of default values, if required */
};
/*

View File

@ -1621,6 +1621,17 @@ const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
**
** The error code stored in database p->db is overwritten with the return
** value in any case.
**
** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK,
** that means all of the the following will be true:
**
** p!=0
** p->pVar!=0
** i>0
** i<=p->nVar
**
** An assert() is normally added after vdbeUnbind() to help static analyzers
** realize this.
*/
static int vdbeUnbind(Vdbe *p, unsigned int i){
Mem *pVar;
@ -1678,6 +1689,7 @@ static int bindText(
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
if( zData!=0 ){
pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
@ -1727,6 +1739,7 @@ int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
sqlite3_mutex_leave(p->db->mutex);
}
@ -1740,6 +1753,7 @@ int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
sqlite3_mutex_leave(p->db->mutex);
}
@ -1750,6 +1764,7 @@ int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
sqlite3_mutex_leave(p->db->mutex);
}
return rc;
@ -1765,6 +1780,7 @@ int sqlite3_bind_pointer(
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
sqlite3_mutex_leave(p->db->mutex);
}else if( xDestructor ){
@ -1846,6 +1862,7 @@ int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
#ifndef SQLITE_OMIT_INCRBLOB
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
#else
@ -2205,7 +2222,30 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
if( iIdx==p->pTab->iPKey ){
sqlite3VdbeMemSetInt64(pMem, p->iKey1);
}else if( iIdx>=p->pUnpacked->nField ){
/* This occurs when the table has been extended using ALTER TABLE
** ADD COLUMN. The value to return is the default value of the column. */
Column *pCol = &p->pTab->aCol[iIdx];
if( pCol->iDflt>0 ){
if( p->apDflt==0 ){
int nByte = sizeof(sqlite3_value*)*p->pTab->nCol;
p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte);
if( p->apDflt==0 ) goto preupdate_old_out;
}
if( p->apDflt[iIdx]==0 ){
sqlite3_value *pVal = 0;
Expr *pDflt;
assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) );
pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr;
rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal);
if( rc==SQLITE_OK && pVal==0 ){
rc = SQLITE_CORRUPT_BKPT;
}
p->apDflt[iIdx] = pVal;
}
*ppValue = p->apDflt[iIdx];
}else{
*ppValue = (sqlite3_value *)columnNullValue();
}
}else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
if( pMem->flags & (MEM_Int|MEM_IntReal) ){
testcase( pMem->flags & MEM_Int );

View File

@ -5543,5 +5543,12 @@ void sqlite3VdbePreUpdateHook(
}
sqlite3DbNNFreeNN(db, preupdate.aNew);
}
if( preupdate.apDflt ){
int i;
for(i=0; i<pTab->nCol; i++){
sqlite3ValueFree(preupdate.apDflt[i]);
}
sqlite3DbFree(db, preupdate.apDflt);
}
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */

View File

@ -1534,7 +1534,8 @@ static int valueFromFunction(
goto value_from_function_out;
}
for(i=0; i<nVal; i++){
rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]);
rc = sqlite3Stat4ValueFromExpr(pCtx->pParse, pList->a[i].pExpr, aff,
&apVal[i]);
if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out;
}
}

View File

@ -867,6 +867,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
Table *pNew = sParse.pNewTable;
Index *pIdx;
pTab->aCol = pNew->aCol;
assert( IsOrdinaryTable(pNew) );
sqlite3ExprListDelete(db, pNew->u.tab.pDfltList);
pTab->nNVCol = pTab->nCol = pNew->nCol;
pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);

View File

@ -1636,9 +1636,11 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){
** that this is required.
*/
static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
int rc;
sqlite3_vtab *pVtab;
assert( IsVirtual(pTab) );
pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
whereTraceIndexInfoInputs(p, pTab);
pParse->db->nSchemaLock++;
rc = pVtab->pModule->xBestIndex(pVtab, p);

View File

@ -706,11 +706,13 @@ ifcapable altertable {
}
}
if 0 {
if 1 {
# At time of writing, these two are broken. They demonstrate that the
# sqlite3_preupdate_old() method does not handle the case where ALTER TABLE
# has been used to add a column with a default value other than NULL.
#
# 2024-09-18: These are now fixed.
#
do_preupdate_test 7.5.2.1 {
DELETE FROM t8 WHERE a = 'one'
} {
@ -1022,4 +1024,37 @@ do_catchsql_test 12.6 {
INSERT INTO t4 VALUES('def', 3);
} {1 {UNIQUE constraint failed: t4.a}}
#-------------------------------------------------------------------------
# Test adding non-NULL default values using ALTER TABLE.
#
reset_db
db preupdate hook preupdate_hook
do_execsql_test 13.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY);
INSERT INTO t1 VALUES(100), (200), (300), (400);
}
do_execsql_test 13.1 {
ALTER TABLE t1 ADD COLUMN b DEFAULT 1234;
ALTER TABLE t1 ADD COLUMN c DEFAULT 'abcdef';
ALTER TABLE t1 ADD COLUMN d DEFAULT NULL;
}
do_preupdate_test 13.2 {
DELETE FROM t1 WHERE a=300
} {DELETE main t1 300 300 0 300 1234 abcdef {}}
do_preupdate_test 13.3 {
UPDATE t1 SET d='hello world' WHERE a=200
} {
UPDATE main t1 200 200 0 200 1234 abcdef {}
200 1234 abcdef {hello world}
}
do_preupdate_test 13.4 {
INSERT INTO t1 DEFAULT VALUES;
} {
INSERT main t1 401 401 0 401 1234 abcdef {}
}
finish_test

View File

@ -50,6 +50,7 @@ struct SQLiteRsync {
FILE *pLog; /* Duplicate output here if not NULL */
sqlite3 *db; /* Database connection */
int nErr; /* Number of errors encountered */
int nWrErr; /* Number of failed attempts to write on the pipe */
u8 eVerbose; /* Bigger for more output. 0 means none. */
u8 bCommCheck; /* True to debug the communication protocol */
u8 isRemote; /* On the remote side of a connection */
@ -844,7 +845,7 @@ static int readUint32(SQLiteRsync *p, unsigned int *pU){
p->nIn += 4;
return 0;
}else{
p->nErr++;
logError(p, "failed to read a 32-bit integer\n");
return 1;
}
}
@ -863,7 +864,8 @@ static int writeUint32(SQLiteRsync *p, unsigned int x){
buf[0] = x;
if( p->pLog ) fwrite(buf, sizeof(buf), 1, p->pLog);
if( fwrite(buf, sizeof(buf), 1, p->pOut)!=1 ){
logError(p, "failed to write 32-bit integer 0x%x", x);
logError(p, "failed to write 32-bit integer 0x%x\n", x);
p->nWrErr++;
return 1;
}
p->nOut += 4;
@ -890,7 +892,7 @@ void writeByte(SQLiteRsync *p, int c){
*/
int readPow2(SQLiteRsync *p){
int x = readByte(p);
if( x>=32 ){
if( x<0 || x>=32 ){
logError(p, "read invalid page size %d\n", x);
return 0;
}
@ -914,7 +916,7 @@ void readBytes(SQLiteRsync *p, int nByte, void *pData){
if( fread(pData, 1, nByte, p->pIn)==nByte ){
p->nIn += nByte;
}else{
logError(p, "failed to read %d bytes", nByte);
logError(p, "failed to read %d bytes\n", nByte);
}
}
@ -925,7 +927,8 @@ void writeBytes(SQLiteRsync *p, int nByte, const void *pData){
if( fwrite(pData, 1, nByte, p->pOut)==nByte ){
p->nOut += nByte;
}else{
logError(p, "failed to write %d bytes", nByte);
logError(p, "failed to write %d bytes\n", nByte);
p->nWrErr++;
}
}
@ -1236,7 +1239,7 @@ static void originSide(SQLiteRsync *p){
}
/* Respond to message from the replica */
while( p->nErr==0 && (c = readByte(p))!=EOF && c!=REPLICA_END ){
while( p->nErr<=p->nWrErr && (c = readByte(p))!=EOF && c!=REPLICA_END ){
switch( c ){
case REPLICA_BEGIN: {
/* This message is only sent if the replica received an origin-protocol
@ -1279,7 +1282,6 @@ static void originSide(SQLiteRsync *p){
}
case REPLICA_READY: {
sqlite3_stmt *pStmt;
int needPageOne = 0;
sqlite3_finalize(pCkHash);
pCkHash = 0;
if( iPage+1<p->nPage ){
@ -1292,39 +1294,20 @@ static void originSide(SQLiteRsync *p){
"SELECT pgno, data"
" FROM badHash JOIN sqlite_dbpage('main') USING(pgno)");
if( pStmt==0 ) break;
while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 ){
while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 && p->nWrErr==0 ){
unsigned int pgno = (unsigned int)sqlite3_column_int64(pStmt,0);
const void *pContent = sqlite3_column_blob(pStmt, 1);
if( pgno==1 ){
needPageOne = 1;
}else{
writeByte(p, ORIGIN_PAGE);
writeUint32(p, (unsigned int)sqlite3_column_int64(pStmt, 0));
writeBytes(p, szPg, pContent);
p->nPageSent++;
}
}
sqlite3_finalize(pStmt);
if( needPageOne ){
pStmt = prepareStmt(p,
"SELECT data"
" FROM sqlite_dbpage('main')"
" WHERE pgno=1"
);
if( pStmt==0 ) break;
while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 ){
const void *pContent = sqlite3_column_blob(pStmt, 0);
writeByte(p, ORIGIN_PAGE);
writeUint32(p, 1);
writeUint32(p, pgno);
writeBytes(p, szPg, pContent);
p->nPageSent++;
}
sqlite3_finalize(pStmt);
}
writeByte(p, ORIGIN_TXN);
writeUint32(p, nPage);
writeByte(p, ORIGIN_END);
goto origin_end;
fflush(p->pOut);
break;
}
default: {
reportError(p, "Unknown message 0x%02x %lld bytes into conversation",
@ -1334,7 +1317,6 @@ static void originSide(SQLiteRsync *p){
}
}
origin_end:
if( pCkHash ) sqlite3_finalize(pCkHash);
closeDb(p);
}
@ -1385,7 +1367,7 @@ static void replicaSide(SQLiteRsync *p){
/* Respond to message from the origin. The origin will initiate the
** the conversation with an ORIGIN_BEGIN message.
*/
while( p->nErr==0 && (c = readByte(p))!=EOF && c!=ORIGIN_END ){
while( p->nErr<=p->nWrErr && (c = readByte(p))!=EOF && c!=ORIGIN_END ){
switch( c ){
case ORIGIN_MSG:
case ORIGIN_ERROR: {
@ -1414,30 +1396,35 @@ static void replicaSide(SQLiteRsync *p){
}
p->nPage = nOPage;
p->szPage = szOPage;
rc = sqlite3_open(p->zReplica, &p->db);
rc = sqlite3_open(":memory:", &p->db);
if( rc ){
reportError(p, "cannot open replica \"%s\": %s",
p->zReplica, sqlite3_errmsg(p->db));
reportError(p, "cannot open in-memory database: %s",
sqlite3_errmsg(p->db));
closeDb(p);
break;
}
runSql(p, "ATTACH %Q AS 'replica'", p->zReplica);
if( p->nErr ){
closeDb(p);
break;
}
hashRegister(p->db);
if( runSqlReturnUInt(p, &nRPage, "PRAGMA page_count") ){
if( runSqlReturnUInt(p, &nRPage, "PRAGMA replica.page_count") ){
break;
}
if( nRPage==0 ){
runSql(p, "PRAGMA page_size=%u", szOPage);
runSql(p, "PRAGMA journal_mode=WAL");
runSql(p, "SELECT * FROM sqlite_schema");
runSql(p, "PRAGMA replica.page_size=%u", szOPage);
runSql(p, "PRAGMA replica.journal_mode=WAL");
runSql(p, "SELECT * FROM replica.sqlite_schema");
}
runSql(p, "BEGIN IMMEDIATE");
runSqlReturnText(p, buf, "PRAGMA journal_mode");
runSqlReturnText(p, buf, "PRAGMA replica.journal_mode");
if( strcmp(buf, "wal")!=0 ){
reportError(p, "replica is not in WAL mode");
break;
}
runSqlReturnUInt(p, &nRPage, "PRAGMA page_count");
runSqlReturnUInt(p, &szRPage, "PRAGMA page_size");
runSqlReturnUInt(p, &nRPage, "PRAGMA replica.page_count");
runSqlReturnUInt(p, &szRPage, "PRAGMA replica.page_size");
if( szRPage!=szOPage ){
reportError(p, "page size mismatch; origin is %d bytes and "
"replica is %d bytes", szOPage, szRPage);
@ -1445,10 +1432,10 @@ static void replicaSide(SQLiteRsync *p){
}
pStmt = prepareStmt(p,
"SELECT hash(data) FROM sqlite_dbpage"
"SELECT hash(data) FROM sqlite_dbpage('replica')"
" WHERE pgno<=min(%d,%d)"
" ORDER BY pgno", nRPage, nOPage);
while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 ){
while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 && p->nWrErr==0 ){
const unsigned char *a = sqlite3_column_blob(pStmt, 0);
writeByte(p, REPLICA_HASH);
writeBytes(p, 20, a);
@ -1474,8 +1461,8 @@ static void replicaSide(SQLiteRsync *p){
sqlite3_bind_null(pIns, 2);
rc = sqlite3_step(pIns);
if( rc!=SQLITE_DONE ){
reportError(p, "SQL statement [%s] failed: %s",
sqlite3_sql(pIns), sqlite3_errmsg(p->db));
reportError(p, "SQL statement [%s] failed (pgno=%u, data=NULL): %s",
sqlite3_sql(pIns), nOPage, sqlite3_errmsg(p->db));
}
sqlite3_reset(pIns);
p->nPage = nOPage;
@ -1490,7 +1477,7 @@ static void replicaSide(SQLiteRsync *p){
if( p->nErr ) break;
if( pIns==0 ){
pIns = prepareStmt(p,
"INSERT INTO sqlite_dbpage(pgno,data) VALUES(?1,?2)"
"INSERT INTO sqlite_dbpage(pgno,data,schema)VALUES(?1,?2,'replica')"
);
if( pIns==0 ) break;
}
@ -1559,6 +1546,34 @@ sqlite3_int64 currentTime(void){
return now;
}
/*
** Input string zIn might be in any of these formats:
**
** (1) PATH
** (2) HOST:PATH
** (3) USER@HOST:PATH
**
** For format 1, return NULL. For formats 2 and 3, return
** a pointer to the ':' character that separates the hostname
** from the path.
*/
static char *hostSeparator(const char *zIn){
char *zPath = strchr(zIn, ':');
if( zPath==0 ) return 0;
#ifdef _WIN32
if( isalpha(zIn[0]) && zIn[1]==':' && (zIn[2]=='/' || zIn[2]=='\\') ){
return 0;
}
#endif
while( zIn<zPath ){
if( zIn[0]=='/' ) return 0;
if( zIn[0]=='\\' ) return 0;
zIn++;
}
return zPath;
}
/*
** Parse command-line arguments. Dispatch subroutines to do the
** requested work.
@ -1724,9 +1739,9 @@ int main(int argc, char const * const *argv){
return 1;
}
tmStart = currentTime();
zDiv = strchr(ctx.zOrigin,':');
zDiv = hostSeparator(ctx.zOrigin);
if( zDiv ){
if( strchr(ctx.zReplica,':')!=0 ){
if( hostSeparator(ctx.zReplica)!=0 ){
fprintf(stderr,
"At least one of ORIGIN and REPLICA must be a local database\n"
"You provided two remote databases.\n");
@ -1757,7 +1772,7 @@ int main(int argc, char const * const *argv){
return 1;
}
replicaSide(&ctx);
}else if( (zDiv = strchr(ctx.zReplica,':'))!=0 ){
}else if( (zDiv = hostSeparator(ctx.zReplica))!=0 ){
/* Local ORIGIN and remote REPLICA */
sqlite3_str *pStr = sqlite3_str_new(0);
append_escaped_arg(pStr, zSsh, 1);
@ -1805,11 +1820,12 @@ int main(int argc, char const * const *argv){
}
originSide(&ctx);
}
pclose2(ctx.pIn, ctx.pOut, childPid);
if( ctx.pLog ) fclose(ctx.pLog);
tmEnd = currentTime();
tmElapse = tmEnd - tmStart; /* Elapse time in milliseconds */
if( ctx.nErr ){
printf("Databases where not synced due to errors\n");
printf("Databases were not synced due to errors\n");
}
if( ctx.eVerbose>=1 ){
char *zMsg;