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:
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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];
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
2
main.mk
2
main.mk
@ -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)
|
||||
|
63
manifest
63
manifest
@ -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.
|
||||
|
@ -1 +1 @@
|
||||
97c2824f471e7e622c4a166947a6e8162cae891345101539829a6fcec83373fe
|
||||
9945206e6e26a48a49b9747650d299eb983cc21a3a61c621cd81f0bbc85a74d7
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 ){
|
||||
|
@ -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);
|
||||
|
@ -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 ){
|
||||
|
@ -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**);
|
||||
|
12
src/utf.c
12
src/utf.c
@ -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)
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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 );
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user