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

Fix handling of schema changes mid-session.

FossilOrigin-Name: 76d2d2ad3b2a5171393b7894f35f463ff284e53b
This commit is contained in:
dan
2011-03-24 16:53:57 +00:00
parent ca62ad57f0
commit a9605b9125
4 changed files with 110 additions and 12 deletions

View File

@ -19,6 +19,7 @@ source $testdir/tester.tcl
set testprefix session3
#-------------------------------------------------------------------------
# These tests - session3-1.* - verify that the session module behaves
# correctly when confronted with a schema mismatch when applying a
# changeset (in function sqlite3changeset_apply()).
@ -27,7 +28,6 @@ set testprefix session3
# session3-1.2.*: Table has wrong number of columns in target db.
# session3-1.3.*: Table has wrong PK columns in target db.
#
db close
sqlite3_shutdown
test_sqlite3_log log
@ -77,6 +77,96 @@ do_test 1.3.1 {
set ::log
} {SQLITE_SCHEMA {sqlite3changeset_apply(): primary key mismatch for table t1}}
#-------------------------------------------------------------------------
# These tests - session3-2.* - verify that the session module behaves
# correctly when the schema of an attached table is modified during the
# session.
#
# session3-2.1.*: Table is dropped midway through the session.
# session3-2.2.*: Table is dropped and recreated with a different # cols.
# session3-2.3.*: Table is dropped and recreated with a different PK.
#
# In all of these scenarios, the call to sqlite3session_changeset() will
# return SQLITE_SCHEMA. Also:
#
# session3-2.4.*: Table is dropped and recreated with an identical schema.
# In this case sqlite3session_changeset() returns SQLITE_OK.
#
do_test 2.1 {
execsql { CREATE TABLE t2(a, b PRIMARY KEY) }
sqlite3session S db main
S attach t2
execsql {
INSERT INTO t2 VALUES(1, 2);
DROP TABLE t2;
}
list [catch { S changeset } msg] $msg
} {1 SQLITE_SCHEMA}
do_test 2.2.1 {
S delete
sqlite3session S db main
execsql { CREATE TABLE t2(a, b PRIMARY KEY, c) }
S attach t2
execsql {
INSERT INTO t2 VALUES(1, 2, 3);
DROP TABLE t2;
CREATE TABLE t2(a, b PRIMARY KEY);
}
list [catch { S changeset } msg] $msg
} {1 SQLITE_SCHEMA}
do_test 2.2.2 {
S delete
sqlite3session S db main
execsql {
DROP TABLE t2;
CREATE TABLE t2(a, b PRIMARY KEY, c);
}
S attach t2
execsql {
INSERT INTO t2 VALUES(1, 2, 3);
DROP TABLE t2;
CREATE TABLE t2(a, b PRIMARY KEY, c, d);
}
list [catch { S changeset } msg] $msg
} {1 SQLITE_SCHEMA}
do_test 2.3 {
S delete
sqlite3session S db main
execsql {
DROP TABLE t2;
CREATE TABLE t2(a, b PRIMARY KEY);
}
S attach t2
execsql {
INSERT INTO t2 VALUES(1, 2);
DROP TABLE t2;
CREATE TABLE t2(a PRIMARY KEY, b, c);
}
list [catch { S changeset } msg] $msg
} {1 SQLITE_SCHEMA}
do_test 2.4 {
S delete
sqlite3session S db main
execsql {
DROP TABLE t2;
CREATE TABLE t2(a, b PRIMARY KEY);
}
S attach t2
execsql {
INSERT INTO t2 VALUES(1, 2);
DROP TABLE t2;
CREATE TABLE t2(a, b PRIMARY KEY);
}
list [catch { S changeset } msg] $msg
} {0 {}}
S delete
catch { db close }
catch { db2 close }

View File

@ -1349,13 +1349,20 @@ int sqlite3session_changeset(
for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
if( pTab->nEntry ){
const char *zName = pTab->zName;
int nCol = pTab->nCol; /* Local copy of member variable */
u8 *abPK = pTab->abPK; /* Local copy of member variable */
int nCol; /* Number of columns in table */
u8 *abPK; /* Primary key array */
const char **azCol = 0; /* Table columns */
int i; /* Used to iterate through hash buckets */
sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */
int nRewind = buf.nBuf; /* Initial size of write buffer */
int nNoop; /* Size of buffer after writing tbl header */
/* Check the table schema is still Ok. */
rc = sessionTableInfo(db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK);
if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){
rc = SQLITE_SCHEMA;
}
/* Write a table header */
sessionAppendByte(&buf, 'T', &rc);
sessionAppendVarint(&buf, nCol, &rc);
@ -1365,7 +1372,7 @@ int sqlite3session_changeset(
/* Build and compile a statement to execute: */
if( rc==SQLITE_OK ){
rc = sessionSelectStmt(
db, pSession->zDb, zName, nCol, pTab->azCol, abPK, &pSel);
db, pSession->zDb, zName, nCol, azCol, abPK, &pSel);
}
if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){
@ -1407,6 +1414,7 @@ int sqlite3session_changeset(
if( buf.nBuf==nNoop ){
buf.nBuf = nRewind;
}
sqlite3_free(azCol);
}
}

View File

@ -1,5 +1,5 @@
C Fix\shandling\sof\sschema\smismatches\sin\ssqlite3session.c\sso\sthat\sit\smatches\sthe\sdocs\sin\ssqlite3session.h.
D 2011-03-24T16:04:55
C Fix\shandling\sof\sschema\schanges\smid-session.
D 2011-03-24T16:53:57
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -101,10 +101,10 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F ext/session/session1.test b2da15b9d727d7f4e5fe95599b32b92d93b5a970
F ext/session/session2.test 8da094318ac88953478c43d0bfb0aa723ee0e379
F ext/session/session3.test b8b9ff7efcb19234892c406dba8bd56792560efe
F ext/session/session3.test c58ebb3273a23da9b5f4eb202d522aa759530a4c
F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28
F ext/session/sessionfault.test d7e6154a30e85622d0733b1a1e3c63e9b8b7004b
F ext/session/sqlite3session.c cf91fe0efb0728c219c8bc2b2174a49758fbd3f8
F ext/session/sqlite3session.c 33a5d4be9c22099aed8e7f6c80b63540953e84c2
F ext/session/sqlite3session.h 900d900bb6a827f84754fc252a05638e0f413a6e
F ext/session/test_session.c e0f500ec5e20478afc2c7998133e8acea7ec5104
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
@ -924,7 +924,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 54298ee5ed183d1f1c49524f25e8ae1407f3d4b5
R 73cd0f1e5ce098769e9cee2c7d1f1ebc
P 506a0d7a710e1ff2f367821e73f5080fcf63fbc5
R 3234ab73592ecae31c60c0a6f501bbfd
U dan
Z 8a40e5171d2567a1ae6ca1b697973f9a
Z 29af2cd6e2d7044fdb214ebc342ad1ba

View File

@ -1 +1 @@
506a0d7a710e1ff2f367821e73f5080fcf63fbc5
76d2d2ad3b2a5171393b7894f35f463ff284e53b