diff --git a/ext/session/session5.test b/ext/session/session5.test index 440a44c08b..676b2c718f 100644 --- a/ext/session/session5.test +++ b/ext/session/session5.test @@ -21,33 +21,46 @@ ifcapable !session {finish_test; return} set testprefix session5 -proc do_concat_test {tn sql1 sql2} { - sqlite3session S1 db main ; S1 attach * - sqlite3session S2 db main ; S2 attach * +# Organization of tests: +# +# session5-1.*: Simple tests to check the concat() function produces +# correct results. +# +# session5-2.*: More complicated tests. +# +# session5-3.*: Schema mismatch errors. +# - execsql $sql1 - set C1 [S1 changeset] - S1 delete +proc changeset_to_list {c} { + set list [list] + sqlite3session_foreach elem $c { lappend list $elem } + lsort $list +} - sqlite3session S1 db main ; S1 attach * +proc do_concat_test {tn args} { - execsql $sql2 - set C2 [S1 changeset] - S1 delete + set subtest 0 + foreach sql $args { + incr subtest + sqlite3session S db main ; S attach * + execsql $sql - set C3 [S2 changeset] - S2 delete + set c [S changeset] + if {[info commands s_prev] != ""} { + set c_concat [sqlite3changeset_concat $c_prev $c] + set c_two [s_prev changeset] + s_prev delete - set C4 [sqlite3changeset_concat $C1 $C2] + set h_concat [changeset_to_list $c_concat] + set h_two [changeset_to_list $c_two] - set c3 [list] - set c4 [list] - sqlite3session_foreach c $C3 { lappend c3 $c } - sqlite3session_foreach c $C4 { lappend c4 $c } - set c3 [lsort $c3] - set c4 [lsort $c4] + do_test $tn.$subtest [list set {} $h_concat] $h_two + } + set c_prev $c + rename S s_prev + } - do_test $tn [list set {} $c4] $c3 + catch { s_prev delete } } do_execsql_test 1.0 { @@ -121,4 +134,55 @@ do_concat_test 1.2.7 { DELETE FROM t1 WHERE a = 'I'; } +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); + INSERT INTO abc VALUES('abcdefghijkl', NULL, 2); +} { + DELETE FROM abc WHERE c = 1; + UPDATE abc SET c = 1 WHERE c = 2; +} { + INSERT INTO abc VALUES('abcdefghijkl', NULL, 2); + INSERT INTO abc VALUES(1.0, 2.0, 3); +} { + UPDATE abc SET a = a-1; +} { + CREATE TABLE def(d, e, f, PRIMARY KEY(e, f)); + INSERT INTO def VALUES('x', randomblob(11000), 67); + INSERT INTO def SELECT d, e, f+1 FROM def; + INSERT INTO def SELECT d, e, f+2 FROM def; + INSERT INTO def SELECT d, e, f+4 FROM def; +} { + DELETE FROM def WHERE rowid>4; +} { + INSERT INTO def SELECT d, e, f+4 FROM def; +} { + INSERT INTO abc VALUES(22, 44, -1); +} { + UPDATE abc SET c=-2 WHERE c=-1; + UPDATE abc SET c=-3 WHERE c=-2; +} { + UPDATE abc SET c=-4 WHERE c=-3; +} { + UPDATE abc SET a=a+1 WHERE c=-3; + UPDATE abc SET a=a+1 WHERE c=-3; +} { + UPDATE abc SET a=a+1 WHERE c=-3; + UPDATE abc SET a=a+1 WHERE c=-3; +} { + INSERT INTO abc VALUES('one', 'two', 'three'); +} { + SELECT indirect(1); + UPDATE abc SET a='one point five' WHERE c = 'three'; +} { + SELECT indirect(0); + UPDATE abc SET a='one point six' WHERE c = 'three'; +} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 770fc13e30..f22fafa5dc 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -353,6 +353,20 @@ static unsigned int sessionPreupdateHash( return SQLITE_OK; } +/* +** The buffer that the argument points to contains a serialized SQL value. +** Return the number of bytes of space occupied by the value (including +** the type byte). +*/ +static int sessionSerialLen(u8 *a){ + int e = *a; + int n; + if( e==0 ) return 1; + if( e==SQLITE_NULL ) return 1; + if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; + return sessionVarintGet(&a[1], &n) + 1 + n; +} + /* ** Based on the primary key values stored in change aRecord, calculate a ** hash key, assuming the has table has nBucket buckets. The hash keys @@ -369,7 +383,7 @@ static unsigned int sessionChangeHash( u8 *a = aRecord; /* Used to iterate through change record */ for(i=0; inCol; i++){ - int eType = *a++; + int eType = *a; int isPK = pTab->abPK[i]; /* It is not possible for eType to be SQLITE_NULL here. The session @@ -377,31 +391,29 @@ static unsigned int sessionChangeHash( ** primary key columns. */ assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT || eType==SQLITE_TEXT || eType==SQLITE_BLOB + || eType==SQLITE_NULL || eType==0 ); + assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) ); - if( isPK ) h = HASH_APPEND(h, eType); - if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - if( isPK ) h = sessionHashAppendI64(h, sessionGetI64(a)); - a += 8; + if( isPK ){ + a++; + h = HASH_APPEND(h, eType); + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + if( isPK ) h = sessionHashAppendI64(h, sessionGetI64(a)); + a += 8; + }else{ + int n; + a += sessionVarintGet(a, &n); + if( isPK ) h = sessionHashAppendBlob(h, n, a); + a += n; + } }else{ - int n; - a += sessionVarintGet(a, &n); - if( isPK ) h = sessionHashAppendBlob(h, n, a); - a += n; + a += sessionSerialLen(a); } } return (h % nBucket); } -static int sessionSerialLen(u8 *a){ - int e = *a; - int n; - if( e==0 ) return 1; - if( e==SQLITE_NULL ) return 1; - if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; - return sessionVarintGet(&a[1], &n) + 1 + n; -} - static int sessionChangeEqual( SessionTable *pTab, u8 *aLeft, /* Change record */ @@ -419,7 +431,7 @@ static int sessionChangeEqual( return 0; } a1 += n1; - a2 += n1; + a2 += n2; } return 1; diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 10a94b927b..fcde98f842 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -522,10 +522,13 @@ int sqlite3changeset_invert( int *pnOut, void **ppOut /* OUT: Inverse of input */ ); +/* +** CAPI3REF: Combine Two Changeset Objects +*/ int sqlite3changeset_concat( - int nLeft, void *pLeft, /* Input changeset */ - int nRight, void *Right, /* Input changeset */ - int *pnOut, void **ppOut /* OUT: Inverse of input */ + int nLeft, void *pLeft, /* First input changeset */ + int nRight, void *Right, /* Second input changeset */ + int *pnOut, void **ppOut /* OUT: Output changeset */ ); /* diff --git a/manifest b/manifest index 4dcb9b0bb0..7b1c552c55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Start\sadding\sthe\ssqlite3changeset_concat()\sfunction\sto\sthe\ssession\smodule. -D 2011-04-14T11:16:21.630 +C Add\sfurther\stests\sfor\sthe\ssqlite3changeset_concat()\sfunction.\sAlso\sfixes. +D 2011-04-14T18:01:41.789 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -103,11 +103,11 @@ 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 ed5025c96693d406fb13bcf330d1a962dcb68c24 +F ext/session/session5.test 9dff891440dc3a424daea914b7e08e9f137272ed F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c -F ext/session/sqlite3session.c 124ac6d43ac5820add2e736b25432c3f6b5a733a -F ext/session/sqlite3session.h dc7c85fd27fa3a9a17b34e0951ed36cdced1bc67 +F ext/session/sqlite3session.c abf9846341847c5b81040683b143b511ee828f2e +F ext/session/sqlite3session.h e64876b299dcd1f8c9d043d59bfe14a94ee6b2ba F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -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 83705e90a54bad462a5b7fbca70cc129998f871c -R 2d3308935368f3ab85a5bea7204d6f97 +P 8927b2260b8d84f53776cb29e1d2fa41b6b0de0e +R f3f9539d9ce74ceea388d1aad2d1949b U dan -Z 4aed6546b387a7c5d8dbcb80467675b2 +Z 58678ea87adc6f0684f4c0fc5f0a6d31 diff --git a/manifest.uuid b/manifest.uuid index 4733d7436b..d6d4737a85 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8927b2260b8d84f53776cb29e1d2fa41b6b0de0e \ No newline at end of file +1fc3f15d88c160b45642b46d1d54c591af058ba2 \ No newline at end of file