1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Fix a problem involving session objects and attached databases.

FossilOrigin-Name: ad91d30073a8faa7eb064dd2e1cc4d2297d7b3f8
This commit is contained in:
dan
2011-03-19 19:19:26 +00:00
parent 1f34f8cc71
commit d7fb7d24c6
4 changed files with 109 additions and 16 deletions

View File

@ -34,9 +34,10 @@ proc do_common_sql {sql} {
}
proc xConflict args { return "OMIT" }
proc do_then_apply_sql {sql} {
sqlite3session S db main
db eval {SELECT name FROM sqlite_master WHERE type = 'table'} {
proc do_then_apply_sql {sql {dbname main}} {
sqlite3session S db $dbname
db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" {
S attach $name
}
@ -171,10 +172,96 @@ foreach {tn sql} {
ROLLBACK;
}
} {
if {$tn==9} breakpoint
do_then_apply_sql $sql
do_test $tn { compare_db db db2 } {}
do_test 1.$tn { compare_db db db2 } {}
}
# The following block of tests is similar to the last, except that the
# session object is recording changes made to an attached database. The
# main database contains a table of the same name as the table being
# modified within the attached db.
#
test_reset
forcedelete test.db3
sqlite3 db3 test.db3
do_test 2.0 {
execsql {
ATTACH 'test.db3' AS 'aux';
CREATE TABLE t1(a, b PRIMARY KEY);
CREATE TABLE t2(x, y, z);
CREATE TABLE t3(a);
CREATE TABLE aux.t1(a PRIMARY KEY, b);
CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY);
CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b));
}
execsql {
CREATE TABLE t1(a PRIMARY KEY, b);
CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
} db2
} {}
foreach {tn sql} {
1 { INSERT INTO aux.t1 VALUES(1, 2) }
2 {
INSERT INTO aux.t2 VALUES(1, NULL);
INSERT INTO aux.t2 VALUES(2, NULL);
INSERT INTO aux.t2 VALUES(3, NULL);
DELETE FROM aux.t2 WHERE a = 2;
INSERT INTO aux.t2 VALUES(4, NULL);
UPDATE aux.t2 SET b=0 WHERE b=1;
}
3 { INSERT INTO aux.t3 SELECT *, NULL FROM aux.t2 }
4 {
INSERT INTO aux.t3 SELECT a||a, b||b, NULL FROM aux.t3;
DELETE FROM aux.t3 WHERE rowid%2;
}
5 { UPDATE aux.t3 SET c = a||b }
6 { UPDATE aux.t1 SET a = 32 }
7 {
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
DELETE FROM aux.t1 WHERE (rowid%3)==0;
}
8 {
BEGIN;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
ROLLBACK;
}
9 {
BEGIN;
UPDATE aux.t1 SET b = 'xxx';
ROLLBACK;
}
10 {
BEGIN;
DELETE FROM aux.t1 WHERE 1;
ROLLBACK;
}
} {
do_then_apply_sql $sql aux
do_test 2.$tn { compare_db db3 db2 } {}
}
catch {db3 close}
finish_test

View File

@ -1191,6 +1191,7 @@ static void sessionAppendUpdate(
static int sessionSelectStmt(
sqlite3 *db, /* Database handle */
const char *zDb, /* Database name */
const char *zTab, /* Table name */
int nCol,
const char **azCol,
@ -1203,6 +1204,8 @@ static int sessionSelectStmt(
SessionBuffer buf = {0, 0, 0};
sessionAppendStr(&buf, "SELECT * FROM ", &rc);
sessionAppendIdent(&buf, zDb, &rc);
sessionAppendStr(&buf, ".", &rc);
sessionAppendIdent(&buf, zTab, &rc);
sessionAppendStr(&buf, " WHERE ", &rc);
for(i=0; i<nCol; i++){
@ -1313,6 +1316,7 @@ int sqlite3session_changeset(
for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
if( pTab->nEntry ){
const char *zName = pTab->zName;
int nCol = pTab->nCol; /* Local copy of member variable */
u8 *abPK = pTab->abPK; /* Local copy of member variable */
int i; /* Used to iterate through hash buckets */
@ -1323,11 +1327,12 @@ int sqlite3session_changeset(
/* Write a table header */
sessionAppendByte(&buf, 'T', &rc);
sessionAppendVarint(&buf, nCol, &rc);
sessionAppendBlob(&buf, (u8 *)pTab->zName, strlen(pTab->zName)+1, &rc);
sessionAppendBlob(&buf, (u8 *)zName, strlen(zName)+1, &rc);
/* Build and compile a statement to execute: */
if( rc==SQLITE_OK ){
rc = sessionSelectStmt(db, pTab->zName, nCol, pTab->azCol, abPK, &pSel);
rc = sessionSelectStmt(
db, pSession->zDb, zName, nCol, pTab->azCol, abPK, &pSel);
}
if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){
@ -1942,7 +1947,8 @@ static int sessionSelectRow(
const char *zTab, /* Table name */
SessionApplyCtx *p /* Session changeset-apply context */
){
return sessionSelectStmt(db, zTab, p->nCol, p->azCol, p->abPK, &p->pSelect);
return sessionSelectStmt(
db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect);
}
/*