diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/session/sessionD.test | 42 | ||||
-rw-r--r-- | ext/session/sqlite3session.c | 40 | ||||
-rw-r--r-- | ext/session/sqlite3session.h | 5 |
3 files changed, 76 insertions, 11 deletions
diff --git a/ext/session/sessionD.test b/ext/session/sessionD.test index f60fbabc2..74bb101e3 100644 --- a/ext/session/sessionD.test +++ b/ext/session/sessionD.test @@ -202,7 +202,7 @@ do_test 4.3.1 { S attach t4 execsql { CREATE TABLE t4(i PRIMARY KEY, b) } list [catch { S diff ixua t4 } msg] $msg -} {1 {SQLITE_SCHEMA - table schemas do not match}} +} {1 {SQLITE_SCHEMA - no such table: ixua.t4}} S delete do_catchsql_test 4.3.2 { SELECT * FROM ixua.t4; @@ -214,7 +214,7 @@ do_test 4.4.1 { execsql { ANALYZE } execsql { DROP TABLE ixua.sqlite_stat1 } list [catch { S diff ixua sqlite_stat1 } msg] $msg -} {1 {SQLITE_SCHEMA - table schemas do not match}} +} {1 {SQLITE_SCHEMA - no such table: ixua.sqlite_stat1}} S delete do_catchsql_test 4.4.2 { SELECT * FROM ixua.sqlite_stat1; @@ -258,4 +258,42 @@ do_changeset_test 4.2 S { S delete +#------------------------------------------------------------------------- +# Test that sqlite3session_diff() really does return errors if +# +reset_db +forcedelete test.db2 +do_execsql_test 5.0 { + ATTACH 'test.db2' AS two; + CREATE TABLE main.t1(a INTEGER PRIMARY KEY, b); + CREATE TABLE main.t2(a INTEGER PRIMARY KEY, b); + CREATE TABLE two.t1(a, b INTEGER PRIMARY KEY); +} + +proc do_sessions_diff_error {tn db tbl err} { + sqlite3session S db main + set rc [catch {S diff $db $tbl} msg] + + set ::sdgot [list $rc $msg] + do_test $tn [list set sdgot] [list {*}$err] + + S delete +} + +# Test that it is an error if the named db is missing. +breakpoint +do_sessions_diff_error 5.1 nosuchdb t1 { + 1 {SQLITE_SCHEMA - no such table: nosuchdb.t1} +} + +# Test that it is an error if the named db is present, but named table is not. +do_sessions_diff_error 5.2 two t2 { + 1 {SQLITE_SCHEMA - no such table: two.t2} +} + +# Test that it is an error if the tables are present, but schemas do not match. +do_sessions_diff_error 5.3 two t1 { + 1 {SQLITE_SCHEMA - table schemas do not match} +} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 6c386f42e..d049f6986 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2229,17 +2229,43 @@ int sqlite3session_diff( if( rc==SQLITE_OK ){ int bHasPk = 0; int bMismatch = 0; - int nCol; /* Columns in zFrom.zTbl */ + int nCol = 0; /* Columns in zFrom.zTbl */ int bRowid = 0; - u8 *abPK; + u8 *abPK = 0; const char **azCol = 0; - rc = sessionTableInfo(0, db, zFrom, zTbl, - &nCol, 0, 0, &azCol, 0, 0, &abPK, - pSession->bImplicitPK ? &bRowid : 0 - ); + char *zDbExists = 0; + + /* Check that database zFrom is attached. */ + zDbExists = sqlite3_mprintf("SELECT * FROM %Q.sqlite_schema", zFrom); + if( zDbExists==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_stmt *pDbExists = 0; + rc = sqlite3_prepare_v2(db, zDbExists, -1, &pDbExists, 0); + if( rc==SQLITE_ERROR ){ + rc = SQLITE_OK; + nCol = -1; + } + sqlite3_finalize(pDbExists); + sqlite3_free(zDbExists); + } + + if( rc==SQLITE_OK && nCol==0 ){ + rc = sessionTableInfo(0, db, zFrom, zTbl, + &nCol, 0, 0, &azCol, 0, 0, &abPK, + pSession->bImplicitPK ? &bRowid : 0 + ); + } if( rc==SQLITE_OK ){ if( pTo->nCol!=nCol ){ - bMismatch = 1; + if( nCol<=0 ){ + rc = SQLITE_SCHEMA; + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("no such table: %s.%s", zFrom, zTbl); + } + }else{ + bMismatch = 1; + } }else{ int i; for(i=0; i<nCol; i++){ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 919365b14..3405dd064 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -432,8 +432,9 @@ sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession); ** database zFrom the contents of the two compatible tables would be ** identical. ** -** It an error if database zFrom does not exist or does not contain the -** required compatible table. +** Unless the call to this function is a no-op as described above, it is an +** error if database zFrom does not exist or does not contain the required +** compatible table. ** ** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite ** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg |