aboutsummaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/session/sessionD.test42
-rw-r--r--ext/session/sqlite3session.c40
-rw-r--r--ext/session/sqlite3session.h5
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