From f29123b5725a9b3a385045a4847788be2d88642c Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Apr 2011 15:04:31 +0000 Subject: [PATCH] Have sqlite3changeset_concat() return SQLITE_SCHEMA if an attempt is made to concatenate changesets based on incompatible database schemas. FossilOrigin-Name: 343b64517d244b75097e38342dc273eb5a52915b --- ext/session/session5.test | 56 +++++++++++++++++++++++++++++++++++- ext/session/sqlite3session.c | 15 ++++++++-- manifest | 14 ++++----- manifest.uuid | 2 +- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/ext/session/session5.test b/ext/session/session5.test index 676b2c718f..d2761b3218 100644 --- a/ext/session/session5.test +++ b/ext/session/session5.test @@ -63,6 +63,9 @@ proc do_concat_test {tn args} { catch { s_prev delete } } +#------------------------------------------------------------------------- +# Test cases session5-1.* - simple tests. +# do_execsql_test 1.0 { CREATE TABLE t1(a PRIMARY KEY, b); } @@ -134,12 +137,15 @@ do_concat_test 1.2.7 { DELETE FROM t1 WHERE a = 'I'; } + +#------------------------------------------------------------------------- +# Test cases session5-2.* - more complex tests. +# db function indirect indirect proc indirect {{x -1}} { S indirect $x s_prev indirect $x } - do_concat_test 2.1 { CREATE TABLE abc(a, b, c PRIMARY KEY); INSERT INTO abc VALUES(NULL, NULL, 1); @@ -185,4 +191,52 @@ do_concat_test 2.1 { UPDATE abc SET a='one point six' WHERE c = 'three'; } +#------------------------------------------------------------------------- +# Test that schema incompatibilities are detected correctly. +# +# session5-3.1: Incompatible number of columns. +# session5-3.2: Incompatible PK definition. +# +proc sql_to_changeset {sql} { + sqlite3session S db main + S attach * + execsql $sql + set c [S changeset] + S delete + return $c +} + +do_test 3.1 { + db close + forcedelete test.db + sqlite3 db test.db + + execsql { CREATE TABLE t1(a PRIMARY KEY, b) } + set c1 [sql_to_changeset { INSERT INTO t1 VALUES(1, 2) }] + execsql { + DROP TABLE t1; + CREATE TABLE t1(a PRIMARY KEY, b, c); + } + set c2 [sql_to_changeset { INSERT INTO t1 VALUES(2, 3, 4) }] + + list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg +} {1 SQLITE_SCHEMA} + +do_test 3.2 { + db close + forcedelete test.db + sqlite3 db test.db + + execsql { CREATE TABLE t1(a PRIMARY KEY, b) } + set c1 [sql_to_changeset { INSERT INTO t1 VALUES(1, 2) }] + execsql { + DROP TABLE t1; + CREATE TABLE t1(a, b PRIMARY KEY); + } + set c2 [sql_to_changeset { INSERT INTO t1 VALUES(2, 3) }] + + list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg +} {1 SQLITE_SCHEMA} + + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index f22fafa5dc..b37b1b33f7 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2862,19 +2862,28 @@ int sessionConcatChangeset( if( !pTab || zNew!=pTab->zName ){ /* Search the list for a matching table */ int nNew = strlen(zNew); + u8 *abPK; + + sqlite3changeset_pk(pIter, &abPK, 0); for(pTab = *ppTabList; pTab; pTab=pTab->pNext){ if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; } if( !pTab ){ pTab = sqlite3_malloc(sizeof(SessionTable)); - if( !pTab ) break; + if( !pTab ){ + rc = SQLITE_NOMEM; + break; + } memset(pTab, 0, sizeof(SessionTable)); pTab->pNext = *ppTabList; + pTab->abPK = abPK; + pTab->nCol = nCol; *ppTabList = pTab; + }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){ + rc = SQLITE_SCHEMA; + break; } pTab->zName = (char *)zNew; - pTab->nCol = nCol; - sqlite3changeset_pk(pIter, &pTab->abPK, 0); } if( sessionGrowHash(pTab) ) break; diff --git a/manifest b/manifest index be42cd3f25..8e07b45dbd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sdocumentation\sfor\ssqlite3changeset_concat()\sto\ssqlite3session.h. -D 2011-04-15T12:04:50.155 +C Have\ssqlite3changeset_concat()\sreturn\sSQLITE_SCHEMA\sif\san\sattempt\sis\smade\sto\sconcatenate\schangesets\sbased\son\sincompatible\sdatabase\sschemas. +D 2011-04-15T15:04:31.042 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -103,10 +103,10 @@ F ext/session/session1.test 7a92a2a6f531aef1e9764ffb7f983fb8b315376d F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 -F ext/session/session5.test 9dff891440dc3a424daea914b7e08e9f137272ed +F ext/session/session5.test cbb011a1b2f487d2fe4b014fb6ae3a67e5f7f767 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c -F ext/session/sqlite3session.c abf9846341847c5b81040683b143b511ee828f2e +F ext/session/sqlite3session.c b5293510224e42c50d69a509e6bfaca45defec76 F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 1fc3f15d88c160b45642b46d1d54c591af058ba2 -R 5b10e49a76b6665385d53106c727e888 +P ada9efa53a6ea55f89d237cfd530f1d180343e19 +R bdb9eba45cd97b77f78325d72d96c5f4 U dan -Z 6bd794c4ce6596f42844ff8d0a6b8d50 +Z 570068f4f013ca36918b632f2a36093d diff --git a/manifest.uuid b/manifest.uuid index 7b35dd9932..6943cc86d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ada9efa53a6ea55f89d237cfd530f1d180343e19 \ No newline at end of file +343b64517d244b75097e38342dc273eb5a52915b \ No newline at end of file