diff --git a/ext/session/sessionD.test b/ext/session/sessionD.test index 6fc47075d5..b8572782e2 100644 --- a/ext/session/sessionD.test +++ b/ext/session/sessionD.test @@ -189,7 +189,8 @@ do_empty_diff_test 3.1 # Test some error cases: # # 1) schema mismatches between the two dbs, and -# 2) tables with no primary keys. +# 2) tables with no primary keys. This is not actually an error, but +# should not add any changes to the session object. # reset_db forcedelete test.db2 @@ -197,22 +198,27 @@ do_execsql_test 4.0 { ATTACH 'test.db2' AS ixua; CREATE TABLE ixua.t1(a, b, c); CREATE TABLE main.t1(a, b, c); + INSERT INTO main.t1 VALUES(1, 2, 3); CREATE TABLE ixua.t2(a PRIMARY KEY, b, c); CREATE TABLE main.t2(a PRIMARY KEY, b, x); } -do_test 4.1 { +do_test 4.1.1 { sqlite3session S db main S attach t1 list [catch { S diff ixua t1 } msg] $msg -} {1 {table has no primary key}} +} {0 {}} +do_test 4.1.2 { + string length [S changeset] +} {0} +S delete -do_test 4.2 { +do_test 4.2.2 { + sqlite3session S db main S attach t2 list [catch { S diff ixua t2 } msg] $msg -} {1 {table schemas do not match}} - +} {1 {SQLITE_SCHEMA - table schemas do not match}} S delete finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index f5a6096611..b5a1b9dfa3 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1474,12 +1474,12 @@ int sqlite3session_diff( /* Check the table schemas match */ if( rc==SQLITE_OK ){ int bHasPk = 0; + int bMismatch = 0; int nCol; /* Columns in zFrom.zTbl */ u8 *abPK; const char **azCol = 0; rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); if( rc==SQLITE_OK ){ - int bMismatch = 0; if( pTo->nCol!=nCol ){ bMismatch = 1; }else{ @@ -1491,16 +1491,16 @@ int sqlite3session_diff( } } - if( bMismatch ){ - *pzErrMsg = sqlite3_mprintf("table schemas do not match"); - rc = SQLITE_ERROR; - } - if( bHasPk==0 ){ - *pzErrMsg = sqlite3_mprintf("table has no primary key"); - rc = SQLITE_ERROR; - } } sqlite3_free(azCol); + if( bMismatch ){ + *pzErrMsg = sqlite3_mprintf("table schemas do not match"); + rc = SQLITE_SCHEMA; + } + if( bHasPk==0 ){ + /* Ignore tables with no primary keys */ + goto diff_out; + } } if( rc==SQLITE_OK ){ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index ed1c5d917c..c8ce488ba7 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -293,6 +293,11 @@ int sqlite3session_changeset( **
  • Has the same PRIMARY KEY definition. ** ** +** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables +** are compatible but do not have any PRIMARY KEY columns, it is not an error +** but no changes are added to the session object. As with other session +** APIs, tables without PRIMARY KEYs are simply ignored. +** ** This function adds a set of changes to the session object that could be ** used to update the table in database zFrom (call this the "from-table") ** so that its content is the same as the table attached to the session diff --git a/ext/session/test_session.c b/ext/session/test_session.c index b3f2533ff5..15f7b6f575 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -39,9 +39,13 @@ static int test_tcl_integer(Tcl_Interp *interp, const char *zVar){ return iVal; } -static int test_session_error(Tcl_Interp *interp, int rc){ +static int test_session_error(Tcl_Interp *interp, int rc, char *zErr){ extern const char *sqlite3ErrName(int); Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + if( zErr ){ + Tcl_AppendResult(interp, " - ", zErr, 0); + sqlite3_free(zErr); + } return TCL_ERROR; } @@ -150,7 +154,7 @@ static int test_session_cmd( if( zArg[0]=='*' && zArg[1]=='\0' ) zArg = 0; rc = sqlite3session_attach(pSession, zArg); if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } break; } @@ -177,7 +181,7 @@ static int test_session_cmd( } sqlite3_free(o.p); if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } break; } @@ -226,13 +230,8 @@ static int test_session_cmd( &zErr ); assert( rc!=SQLITE_OK || zErr==0 ); - if( zErr ){ - Tcl_AppendResult(interp, zErr, 0); - sqlite3_free(zErr); - return TCL_ERROR; - } if( rc ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, zErr); } break; } @@ -278,7 +277,7 @@ static int test_sqlite3session( rc = sqlite3session_create(db, Tcl_GetString(objv[3]), &p->pSession); if( rc!=SQLITE_OK ){ ckfree((char*)p); - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } Tcl_CreateObjCommand( @@ -652,7 +651,7 @@ static int test_sqlite3changeset_apply( } if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } Tcl_ResetResult(interp); return TCL_OK; @@ -686,7 +685,7 @@ static int test_sqlite3changeset_apply_replace_all( rc = sqlite3changeset_apply(db, nChangeset, pChangeset, 0, replace_handler,0); if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } Tcl_ResetResult(interp); return TCL_OK; @@ -724,7 +723,7 @@ static int test_sqlite3changeset_invert( rc = sqlite3changeset_invert(sIn.nData, sIn.aData, &sOut.n, &sOut.p); } if( rc!=SQLITE_OK ){ - rc = test_session_error(interp, rc); + rc = test_session_error(interp, rc, 0); }else{ Tcl_SetObjResult(interp,Tcl_NewByteArrayObj((unsigned char*)sOut.p,sOut.n)); } @@ -772,7 +771,7 @@ static int test_sqlite3changeset_concat( } if( rc!=SQLITE_OK ){ - rc = test_session_error(interp, rc); + rc = test_session_error(interp, rc, 0); }else{ Tcl_SetObjResult(interp,Tcl_NewByteArrayObj((unsigned char*)sOut.p,sOut.n)); } @@ -824,7 +823,7 @@ static int test_sqlite3session_foreach( rc = sqlite3changeset_start_strm(&pIter, testStreamInput, (void*)&sStr); } if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ @@ -907,7 +906,7 @@ static int test_sqlite3session_foreach( rc = sqlite3changeset_finalize(pIter); } if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } return TCL_OK; diff --git a/manifest b/manifest index 5b54ca3c2e..cc09519aa2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\serror\smessage\sreturned\sby\ssqlite3session_diff()\sfor\stables\swith\sno\sPRIMARY\sKEY. -D 2015-04-23T15:03:14.997 +C Modify\sthe\ssqlite3session_diff()\sAPI\sso\sthat\stables\swith\sno\sPRIMARY\sKEYs\sare\signored.\sThis\smatches\sthe\sother\ssessions\sAPIs.\sAlso\schange\ssqlite3session_diff()\sso\sthat\sit\sreturns\sSQLITE_SCHEMA,\sinstead\sof\sSQLITE_ERROR,\sif\sthe\stables\sbeing\scompared\sdo\snot\shave\scompatible\sschemas. +D 2015-04-23T17:22:50.000 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7599f0c96df628cd543884b1b2f2a2fbffd00079 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -158,12 +158,12 @@ F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 -F ext/session/sessionD.test bdc20e2384bf92b5719b9e41ad3b18cd9188cf26 +F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 0b26c45c0c3c0b2afaae9bd69ae1e80a6b8e9b5a -F ext/session/sqlite3session.h d9ebd8d4c5791aafdf18165575c7f2223c09279b -F ext/session/test_session.c 67a049635d910c55917f23d067575ab5432d4546 +F ext/session/sqlite3session.c d22a8996f44202a13d0b1ad18757cd509729a23c +F ext/session/sqlite3session.h 8e86f9eec3ed71f1f30eefbe810cbe5bc10b5aa9 +F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1271,7 +1271,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ea400eca314d81761fe5c0e329b906c045f0dfe4 -R 57c462c26b9985ec1f9daf86d6b971a1 +P 4d34a3d40da210bebb2a2e6dff094f9a39c92798 +R 77fdc1b8d856af82047ddfafb467bba9 U dan -Z dd15ced7dcdddbd36a44e0c8439b0673 +Z c001be8d13359c151923937b5aa6a277 diff --git a/manifest.uuid b/manifest.uuid index 9d7404abb8..ef8da808c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d34a3d40da210bebb2a2e6dff094f9a39c92798 \ No newline at end of file +aada0ad08e3baa10d14d1f3393183110289e068e \ No newline at end of file