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:
@ -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 }
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
14
manifest
14
manifest
@ -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
|
||||
|
@ -1 +1 @@
|
||||
506a0d7a710e1ff2f367821e73f5080fcf63fbc5
|
||||
76d2d2ad3b2a5171393b7894f35f463ff284e53b
|
Reference in New Issue
Block a user