mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Modify the sessions module to ignore all operations on tables with no primary keys as documented.
FossilOrigin-Name: bdaf9575cd9ebb33dc5da4062a84bca79e7b0fec
This commit is contained in:
@ -20,16 +20,6 @@ ifcapable !session {finish_test; return}
|
||||
|
||||
set testprefix session1
|
||||
|
||||
proc do_changeset_test {tn session res} {
|
||||
set r [list]
|
||||
foreach x $res {lappend r $x}
|
||||
uplevel do_test $tn [list [subst -nocommands {
|
||||
set x [list]
|
||||
sqlite3session_foreach c [$session changeset] { lappend x [set c] }
|
||||
set x
|
||||
}]] [list $r]
|
||||
}
|
||||
|
||||
proc do_changeset_invert_test {tn session res} {
|
||||
set r [list]
|
||||
foreach x $res {lappend r $x}
|
||||
@ -525,6 +515,47 @@ do_changeset_test 9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {}
|
||||
S delete
|
||||
catch { db2 close }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test a really long table name.
|
||||
#
|
||||
reset_db
|
||||
set tblname [string repeat tblname123 100]
|
||||
do_test 10.1.1 {
|
||||
execsql "
|
||||
CREATE TABLE $tblname (a PRIMARY KEY, b);
|
||||
INSERT INTO $tblname VALUES('xyz', 'def');
|
||||
"
|
||||
sqlite3session S db main
|
||||
S attach $tblname
|
||||
execsql "
|
||||
INSERT INTO $tblname VALUES('uvw', 'abc');
|
||||
DELETE FROM $tblname WHERE a = 'xyz';
|
||||
"
|
||||
} {}
|
||||
breakpoint
|
||||
do_changeset_test 10.1.2 S "
|
||||
{INSERT $tblname 0 X. {} {t uvw t abc}}
|
||||
{DELETE $tblname 0 X. {t xyz t def} {}}
|
||||
"
|
||||
do_test 10.1.4 { S delete } {}
|
||||
|
||||
#---------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 11.1 {
|
||||
CREATE TABLE t1(a, b);
|
||||
}
|
||||
do_test 11.2 {
|
||||
sqlite3session S db main
|
||||
S attach t1
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
}
|
||||
S changeset
|
||||
} {}
|
||||
|
||||
S delete
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test a really long table name.
|
||||
#
|
||||
|
116
ext/session/sessionE.test
Normal file
116
ext/session/sessionE.test
Normal file
@ -0,0 +1,116 @@
|
||||
# 2015 June 02
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file implements regression tests for the sessions module.
|
||||
# Specifically, it tests that operations on tables without primary keys
|
||||
# are ignored.
|
||||
#
|
||||
|
||||
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
set testprefix sessionE
|
||||
|
||||
#
|
||||
# Test plan:
|
||||
#
|
||||
# 1.*: Test that non-PK tables are not auto-attached.
|
||||
# 2.*: Test that explicitly attaching a non-PK table is a no-op.
|
||||
# 3.*: Test that sqlite3session_diff() on a non-PK table is a no-op.
|
||||
#
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE t2(a PRIMARY KEY, b);
|
||||
}
|
||||
do_test 1.1 {
|
||||
sqlite3session S db main
|
||||
S attach *
|
||||
breakpoint
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t2 VALUES(1, 2);
|
||||
}
|
||||
} {}
|
||||
do_changeset_test 1.2 S {
|
||||
{INSERT t2 0 X. {} {i 1 i 2}}
|
||||
}
|
||||
S delete
|
||||
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE t2(a PRIMARY KEY, b);
|
||||
}
|
||||
do_test 2.1 {
|
||||
sqlite3session S db main
|
||||
S attach t1
|
||||
S attach t2
|
||||
breakpoint
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t2 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
INSERT INTO t2 VALUES(5, 6);
|
||||
}
|
||||
} {}
|
||||
do_changeset_test 2.2 S {
|
||||
{INSERT t2 0 X. {} {i 3 i 4}}
|
||||
{INSERT t2 0 X. {} {i 5 i 6}}
|
||||
}
|
||||
S delete
|
||||
|
||||
reset_db
|
||||
forcedelete test.db2
|
||||
do_execsql_test 3.0 {
|
||||
ATTACH 'test.db2' AS aux;
|
||||
CREATE TABLE aux.t1(a, b);
|
||||
CREATE TABLE aux.t2(a PRIMARY KEY, b);
|
||||
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE t2(a PRIMARY KEY, b);
|
||||
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t2 VALUES(3, 4);
|
||||
}
|
||||
do_test 3.1 {
|
||||
sqlite3session S db main
|
||||
S attach t1
|
||||
S diff aux t1
|
||||
|
||||
S attach t2
|
||||
S diff aux t2
|
||||
} {}
|
||||
do_changeset_test 3.2 S {
|
||||
{INSERT t2 0 X. {} {i 3 i 4}}
|
||||
}
|
||||
do_execsql_test 3.3 {
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
INSERT INTO t2 VALUES(7, 8);
|
||||
}
|
||||
do_changeset_test 3.4 S {
|
||||
{INSERT t2 0 X. {} {i 3 i 4}}
|
||||
{INSERT t2 0 X. {} {i 7 i 8}}
|
||||
}
|
||||
|
||||
|
||||
S delete
|
||||
|
||||
|
||||
|
@ -1,4 +1,14 @@
|
||||
|
||||
proc do_changeset_test {tn session res} {
|
||||
set r [list]
|
||||
foreach x $res {lappend r $x}
|
||||
uplevel do_test $tn [list [subst -nocommands {
|
||||
set x [list]
|
||||
sqlite3session_foreach c [$session changeset] { lappend x [set c] }
|
||||
set x
|
||||
}]] [list $r]
|
||||
}
|
||||
|
||||
|
||||
proc do_conflict_test {tn args} {
|
||||
proc xConflict {args} {
|
||||
|
@ -1008,32 +1008,33 @@ static int sessionTableInfo(
|
||||
/*
|
||||
** This function is only called from within a pre-update handler for a
|
||||
** write to table pTab, part of session pSession. If this is the first
|
||||
** write to this table, set the SessionTable.nCol variable to the number
|
||||
** of columns in the table.
|
||||
** write to this table, initalize the SessionTable.nCol, azCol[] and
|
||||
** abPK[] arrays accordingly.
|
||||
**
|
||||
** Otherwise, if this is not the first time this table has been written
|
||||
** to, check that the number of columns in the table has not changed. If
|
||||
** it has not, return zero.
|
||||
**
|
||||
** If the number of columns in the table has changed since the last write
|
||||
** was recorded, set the session error-code to SQLITE_SCHEMA and return
|
||||
** non-zero. Users are not allowed to change the number of columns in a table
|
||||
** for which changes are being recorded by the session module. If they do so,
|
||||
** it is an error.
|
||||
** If an error occurs, an error code is stored in sqlite3_session.rc and
|
||||
** non-zero returned. Or, if no error occurs but the table has no primary
|
||||
** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to
|
||||
** indicate that updates on this table should be ignored. SessionTable.abPK
|
||||
** is set to NULL in this case.
|
||||
*/
|
||||
static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
|
||||
if( pTab->nCol==0 ){
|
||||
u8 *abPK;
|
||||
assert( pTab->azCol==0 || pTab->abPK==0 );
|
||||
pSession->rc = sessionTableInfo(pSession->db, pSession->zDb,
|
||||
pTab->zName, &pTab->nCol, 0, &pTab->azCol, &pTab->abPK
|
||||
pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK
|
||||
);
|
||||
if( pSession->rc==SQLITE_OK ){
|
||||
int i;
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
if( abPK[i] ){
|
||||
pTab->abPK = abPK;
|
||||
break;
|
||||
}
|
||||
if( pSession->rc==SQLITE_OK
|
||||
&& pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx)
|
||||
){
|
||||
pSession->rc = SQLITE_SCHEMA;
|
||||
}
|
||||
return pSession->rc;
|
||||
}
|
||||
}
|
||||
return (pSession->rc || pTab->abPK==0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1058,6 +1059,13 @@ static void sessionPreupdateOneChange(
|
||||
/* Load table details if required */
|
||||
if( sessionInitTable(pSession, pTab) ) return;
|
||||
|
||||
/* Check the number of columns in this xPreUpdate call matches the
|
||||
** number of columns in the table. */
|
||||
if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){
|
||||
pSession->rc = SQLITE_SCHEMA;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Grow the hash table if required */
|
||||
if( sessionGrowHash(0, pTab) ){
|
||||
pSession->rc = SQLITE_NOMEM;
|
||||
@ -1465,10 +1473,9 @@ int sqlite3session_diff(
|
||||
/* Locate and if necessary initialize the target table object */
|
||||
rc = sessionFindTable(pSession, zTbl, &pTo);
|
||||
if( pTo==0 ) goto diff_out;
|
||||
if( pTo->nCol==0 ){
|
||||
rc = pSession->rc = sessionTableInfo(db, zDb,
|
||||
pTo->zName, &pTo->nCol, 0, &pTo->azCol, &pTo->abPK
|
||||
);
|
||||
if( sessionInitTable(pSession, pTo) ){
|
||||
rc = pSession->rc;
|
||||
goto diff_out;
|
||||
}
|
||||
|
||||
/* Check the table schemas match */
|
||||
|
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C Import\srecent\senhancements\sfrom\strunk.
|
||||
D 2015-05-29T19:04:58.908
|
||||
C Modify\sthe\ssessions\smodule\sto\signore\sall\soperations\son\stables\swith\sno\sprimary\skeys\sas\sdocumented.
|
||||
D 2015-06-02T09:19:22.231
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 58c16cc8cd876ed112902e70cf33d33f3270b5aa
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -166,7 +166,7 @@ F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28
|
||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
|
||||
F ext/session/session1.test 4653867f32a98ce4bbb4a181aac6debe51ca4dfb
|
||||
F ext/session/session1.test d4f53b9b5add7eeb358e535d6e18552142092429
|
||||
F ext/session/session2.test a95a2d270b32638c1acba7cb9c81856712d469ac
|
||||
F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01
|
||||
F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84
|
||||
@ -178,9 +178,10 @@ F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f
|
||||
F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c
|
||||
F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4
|
||||
F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2
|
||||
F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d
|
||||
F ext/session/sessionE.test 9ebeae9918f0a07fafc2b5f4a1636fd8bc940804
|
||||
F ext/session/session_common.tcl f4b7b59c617edf0c9b00d94cd93498d225d43837
|
||||
F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc
|
||||
F ext/session/sqlite3session.c 9ccf68d542f4afc5dc14295d984bf37a7db6b936
|
||||
F ext/session/sqlite3session.c d630293057fcf4274451edec24c2745953ca042c
|
||||
F ext/session/sqlite3session.h 8e86f9eec3ed71f1f30eefbe810cbe5bc10b5aa9
|
||||
F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce
|
||||
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
|
||||
@ -1300,7 +1301,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 519054bb72e8f8977b11161c81b0e96ba7bca589 09a38bf665902834936d39341627ded88142e6ae
|
||||
R 8892830f1d56f04b6b2e14d9642ea36b
|
||||
U drh
|
||||
Z 5694d275e23a4dea203ff0f897ed1e57
|
||||
P 54bec164ebeaf62d783352b3c4d0de8845394091
|
||||
R f80d0c3771ea18894e499ba6e9adad71
|
||||
U dan
|
||||
Z e52febd1b018cb0f724ad3d4cfe4ef9d
|
||||
|
@ -1 +1 @@
|
||||
54bec164ebeaf62d783352b3c4d0de8845394091
|
||||
bdaf9575cd9ebb33dc5da4062a84bca79e7b0fec
|
Reference in New Issue
Block a user