{INSERT sqlite_stat1 0 XX. {} {t t2 b {} t 6}}
}
+#-------------------------------------------------------------------------
+catch { db2 close }
+reset_db
+forcedelete test.db2
+sqlite3 db2 test.db2
+
+do_test 4.1.0 {
+ do_common_sql {
+ CREATE TABLE t1(a, b);
+ CREATE INDEX i1 ON t1(a);
+ CREATE INDEX i2 ON t1(b);
+ INSERT INTO t1 VALUES(1,1), (2,2);
+ ANALYZE;
+ }
+ execsql { DELETE FROM sqlite_stat1 }
+} {}
+do_test 4.1.1 {
+ execsql { INSERT INTO t1 VALUES(3,3); }
+ set C [changeset_from_sql {ANALYZE}]
+ set ::c [list]
+ proc xConflict {args} {
+ lappend ::c $args
+ return "OMIT"
+ }
+ sqlite3changeset_apply db2 $C xConflict
+ set ::c
+} [list {*}{
+ {INSERT sqlite_stat1 CONFLICT {t t1 t i1 t {3 1}} {t t1 t i1 t {2 1}}}
+ {INSERT sqlite_stat1 CONFLICT {t t1 t i2 t {3 1}} {t t1 t i2 t {2 1}}}
+}]
+
+do_execsql_test -db db2 4.1.2 {
+ SELECT * FROM sqlite_stat1 ORDER BY 1,2;
+} {t1 i1 {2 1} t1 i2 {2 1}}
+
+do_test 4.1.3 {
+ proc xConflict {args} {
+ return "REPLACE"
+ }
+ sqlite3changeset_apply db2 $C xConflict
+ execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2
+} {t1 i1 {3 1} t1 i2 {3 1}}
+
+do_test 4.2.0 {
+ do_common_sql {
+ DROP TABLE t1;
+ CREATE TABLE t3(x,y);
+ INSERT INTO t3 VALUES('a','a');
+ INSERT INTO t3 VALUES('b','b');
+ ANALYZE;
+ }
+ execsql { DELETE FROM sqlite_stat1 }
+} {}
+do_test 4.2.1 {
+ execsql { INSERT INTO t3 VALUES('c','c'); }
+ set C [changeset_from_sql {ANALYZE}]
+ set ::c [list]
+ proc xConflict {args} {
+ lappend ::c $args
+ return "OMIT"
+ }
+ sqlite3changeset_apply db2 $C xConflict
+ set ::c
+} [list {*}{
+ {INSERT sqlite_stat1 CONFLICT {t t3 b {} t 3} {t t3 b {} t 2}}
+}]
+db2 null null
+do_execsql_test -db db2 4.2.2 {
+ SELECT * FROM sqlite_stat1 ORDER BY 1,2;
+} {t3 null 2}
+do_test 4.2.3 {
+ proc xConflict {args} {
+ return "REPLACE"
+ }
+ sqlite3changeset_apply db2 $C xConflict
+ execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2
+} {t3 null 3}
finish_test
int nCol; /* Size of azCol[] and abPK[] arrays */
const char **azCol; /* Array of column names */
u8 *abPK; /* Boolean array - true if column is in PK */
-
+ int bStat1; /* True if table is sqlite_stat1 */
int bDeferConstraints; /* True to defer constraints */
SessionBuffer constraints; /* Deferred constraints are stored here */
};
}else{
assert( op==SQLITE_INSERT );
- rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
- if( rc!=SQLITE_OK ) return rc;
+ if( p->bStat1 ){
+ /* Check if there is a conflicting row. For sqlite_stat1, this needs
+ ** to be done using a SELECT, as there is no PRIMARY KEY in the
+ ** database schema to throw an exception if a duplicate is inserted. */
+ rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
+ if( rc==SQLITE_ROW ){
+ rc = SQLITE_CONSTRAINT;
+ sqlite3_reset(p->pSelect);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
+ if( rc!=SQLITE_OK ) return rc;
+
+ sqlite3_step(p->pInsert);
+ rc = sqlite3_reset(p->pInsert);
+ }
- sqlite3_step(p->pInsert);
- rc = sqlite3_reset(p->pInsert);
if( (rc&0xff)==SQLITE_CONSTRAINT ){
rc = sessionConflictHandler(
SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
if( (rc = sessionStat1Sql(db, &sApply) ) ){
break;
}
- }else
- if((rc = sessionSelectRow(db, zTab, &sApply))
- || (rc = sessionUpdateRow(db, zTab, &sApply))
- || (rc = sessionDeleteRow(db, zTab, &sApply))
- || (rc = sessionInsertRow(db, zTab, &sApply))
- ){
- break;
+ sApply.bStat1 = 1;
+ }else{
+ if((rc = sessionSelectRow(db, zTab, &sApply))
+ || (rc = sessionUpdateRow(db, zTab, &sApply))
+ || (rc = sessionDeleteRow(db, zTab, &sApply))
+ || (rc = sessionInsertRow(db, zTab, &sApply))
+ ){
+ break;
+ }
+ sApply.bStat1 = 0;
}
}
nTab = sqlite3Strlen30(zTab);
-C Simplify\sthe\ssessions\spreupdate-hook\slogic\sfor\stransforming\sNULL\sto\sX''\sfor\ncolumn\ssqlite_stat1.idx.
-D 2018-01-18T15:06:23.750
+C Fix\ssessions\smodule\sconflict\shandling\sfor\sthe\ssqlite_stat1\stable.
+D 2018-01-18T16:42:11.152
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 38f84f301cbef443b2d269f67a74b8cc536469831f70df7c3e912acc04932cc2
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
-F ext/session/sessionstat1.test 16268a9bf62ab19c9bc9e41404bf7a13b5fd37c9cb6cf278a472f0c6c50d7ac1
+F ext/session/sessionstat1.test 41cd97c2e48619a41cdf8ae749e1b25f34719de638689221aa43971be693bf4e
F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc
-F ext/session/sqlite3session.c 55f20fa4a9b6acc338e11867439633c7faa3d18809cdd826fde6abf9a75dd7a0
+F ext/session/sqlite3session.c 989466bba4dff0ede8d4c450b1fc65ca222b87e31193eddbf3931b88bf898a57
F ext/session/sqlite3session.h cb4d860101ba6d3ac810f18684539b766d24d668fa2436cdde90d711af9464fb
F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 25bf734be1b3883fccf12ac4d93d50289aa307fb60a52e0e32df12f7ee4edc7a
-R f7c998dd2622eae2189b630c53aa0780
+P 089d7cecaaa47db58320b216a111a5e56123d022008be6c81bc0746148bbdb58
+R b26168110a43028fdb5773dcda862810
U dan
-Z 3f8bd6ff445f731b364c070e53a9b8ca
+Z 3667003c7f66cdcf6e4cbccaf82894fb
-089d7cecaaa47db58320b216a111a5e56123d022008be6c81bc0746148bbdb58
\ No newline at end of file
+f05ee74e05c401eb075a1ba65179662a08a5c3d5b55fc81f2acc841e841dd055
\ No newline at end of file