mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Remove some unreachable code in sqlite3session.c. Add test cases.
FossilOrigin-Name: 39cdfa5324ae91bfbbac733b1e3e2d33ca883340
This commit is contained in:
@ -188,7 +188,6 @@ proc do_conflict_test {tn args} {
|
|||||||
sqlite3session S db main
|
sqlite3session S db main
|
||||||
foreach t $O(-tables) { S attach $t }
|
foreach t $O(-tables) { S attach $t }
|
||||||
execsql $O(-sql)
|
execsql $O(-sql)
|
||||||
|
|
||||||
set ::xConflict [list]
|
set ::xConflict [list]
|
||||||
sqlite3changeset_apply db2 [S changeset] xConflict
|
sqlite3changeset_apply db2 [S changeset] xConflict
|
||||||
|
|
||||||
|
@ -150,6 +150,13 @@ set set_of_tests {
|
|||||||
INSERT INTO %T1% SELECT a+8, b+8 FROM %T1%;
|
INSERT INTO %T1% SELECT a+8, b+8 FROM %T1%;
|
||||||
INSERT INTO %T1% SELECT a+256, b+256 FROM %T1%;
|
INSERT INTO %T1% SELECT a+256, b+256 FROM %T1%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16 {
|
||||||
|
INSERT INTO %T4% VALUES('abc', 'def');
|
||||||
|
INSERT INTO %T4% VALUES('def', 'abc');
|
||||||
|
}
|
||||||
|
17 { UPDATE %T4% SET b = 1 }
|
||||||
|
18 { DELETE FROM %T4% WHERE 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
test_reset
|
test_reset
|
||||||
@ -157,9 +164,10 @@ do_common_sql {
|
|||||||
CREATE TABLE t1(a PRIMARY KEY, b);
|
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||||
CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
|
CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
|
||||||
CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
|
CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
|
||||||
|
CREATE TABLE t4(a, b, PRIMARY KEY(b, a));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3} $set_of_tests] {
|
foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3 %T4% t4} $set_of_tests] {
|
||||||
do_then_apply_sql $sql
|
do_then_apply_sql $sql
|
||||||
do_test 2.$tn { compare_db db db2 } {}
|
do_test 2.$tn { compare_db db db2 } {}
|
||||||
}
|
}
|
||||||
@ -182,21 +190,23 @@ do_test 3.0 {
|
|||||||
CREATE TABLE aux.t1(a PRIMARY KEY, b);
|
CREATE TABLE aux.t1(a PRIMARY KEY, b);
|
||||||
CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY);
|
CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY);
|
||||||
CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b));
|
CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b));
|
||||||
|
CREATE TABLE aux.t4(a, b, PRIMARY KEY(b, a));
|
||||||
}
|
}
|
||||||
execsql {
|
execsql {
|
||||||
CREATE TABLE t1(a PRIMARY KEY, b);
|
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||||
CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
|
CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
|
||||||
CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
|
CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
|
||||||
|
CREATE TABLE t4(a, b, PRIMARY KEY(b, a));
|
||||||
} db2
|
} db2
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
proc xTrace {args} { puts $args }
|
proc xTrace {args} { puts $args }
|
||||||
|
|
||||||
foreach {tn sql} [
|
foreach {tn sql} [
|
||||||
string map {%T1% aux.t1 %T2% aux.t2 %T3% aux.t3} $set_of_tests
|
string map {%T1% aux.t1 %T2% aux.t2 %T3% aux.t3 %T4% aux.t4} $set_of_tests
|
||||||
] {
|
] {
|
||||||
do_then_apply_sql $sql aux
|
do_then_apply_sql $sql aux
|
||||||
do_test 3.$tn { compare_db db3 db2 } {}
|
do_test 3.$tn { compare_db db2 db3 } {}
|
||||||
}
|
}
|
||||||
catch {db3 close}
|
catch {db3 close}
|
||||||
|
|
||||||
|
@ -83,7 +83,11 @@ proc compare_db {db1 db2} {
|
|||||||
set lot1 [$db1 eval $sql]
|
set lot1 [$db1 eval $sql]
|
||||||
set lot2 [$db2 eval $sql]
|
set lot2 [$db2 eval $sql]
|
||||||
|
|
||||||
if {$lot1 != $lot2} { error "databases contain different tables" }
|
if {$lot1 != $lot2} {
|
||||||
|
puts $lot1
|
||||||
|
puts $lot2
|
||||||
|
error "databases contain different tables"
|
||||||
|
}
|
||||||
|
|
||||||
foreach tbl $lot1 {
|
foreach tbl $lot1 {
|
||||||
set col1 [list]
|
set col1 [list]
|
||||||
|
@ -82,4 +82,56 @@ do_faultsim_test pagerfault-2 -faults oom-* -prep {
|
|||||||
faultsim_integrity_check
|
faultsim_integrity_check
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch { db close }
|
||||||
|
catch { db2 close }
|
||||||
|
forcedelete test.db2 test.db
|
||||||
|
sqlite3 db2 test.db2
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
proc xConflict {op tbl type args} {
|
||||||
|
if { $type=="CONFLICT" || $type=="DATA" } {
|
||||||
|
return "REPLACE"
|
||||||
|
}
|
||||||
|
return "OMIT"
|
||||||
|
}
|
||||||
|
|
||||||
|
do_test 3.0 {
|
||||||
|
execsql {
|
||||||
|
PRAGMA encoding = 'utf16';
|
||||||
|
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||||
|
INSERT INTO t1 VALUES(5, 32);
|
||||||
|
}
|
||||||
|
execsql {
|
||||||
|
PRAGMA encoding = 'utf16';
|
||||||
|
CREATE TABLE t1(a PRIMARY KEY, b NOT NULL);
|
||||||
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
|
INSERT INTO t1 VALUES(2, 4);
|
||||||
|
INSERT INTO t1 VALUES(4, 16);
|
||||||
|
} db2
|
||||||
|
} {}
|
||||||
|
|
||||||
|
faultsim_save_and_close
|
||||||
|
db2 close
|
||||||
|
|
||||||
|
do_faultsim_test pagerfault-3 -faults oom-transient -prep {
|
||||||
|
catch {db2 close}
|
||||||
|
catch {db close}
|
||||||
|
faultsim_restore_and_reopen
|
||||||
|
sqlite3 db2 test.db2
|
||||||
|
sqlite3session S db main
|
||||||
|
S attach t1
|
||||||
|
execsql {
|
||||||
|
INSERT INTO t1 VALUES(1, 45);
|
||||||
|
INSERT INTO t1 VALUES(2, 55);
|
||||||
|
INSERT INTO t1 VALUES(3, 55);
|
||||||
|
UPDATE t1 SET a = 4 WHERE a = 5;
|
||||||
|
}
|
||||||
|
} -body {
|
||||||
|
sqlite3changeset_apply db2 [S changeset] xConflict
|
||||||
|
} -test {
|
||||||
|
catch { S delete }
|
||||||
|
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
|
||||||
|
if {$testrc==0} { compare_db db db2 }
|
||||||
|
}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -552,11 +552,10 @@ static int sessionTableInfo(
|
|||||||
int nThis;
|
int nThis;
|
||||||
int i;
|
int i;
|
||||||
u8 *pAlloc;
|
u8 *pAlloc;
|
||||||
u8 *pFree = 0;
|
char **azCol = 0;
|
||||||
char **azCol;
|
|
||||||
u8 *abPK;
|
u8 *abPK;
|
||||||
|
|
||||||
assert( pazCol || pabPK );
|
assert( pazCol && pabPK );
|
||||||
|
|
||||||
nThis = strlen(zThis);
|
nThis = strlen(zThis);
|
||||||
zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
|
zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
|
||||||
@ -584,15 +583,10 @@ static int sessionTableInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
pFree = pAlloc;
|
azCol = (char **)pAlloc;
|
||||||
if( pazCol ){
|
pAlloc = (u8 *)&azCol[nCol];
|
||||||
azCol = (char **)pAlloc;
|
abPK = (u8 *)pAlloc;
|
||||||
pAlloc = (u8 *)&azCol[nCol];
|
pAlloc = &abPK[nCol];
|
||||||
}
|
|
||||||
if( pabPK ){
|
|
||||||
abPK = (u8 *)pAlloc;
|
|
||||||
pAlloc = &abPK[nCol];
|
|
||||||
}
|
|
||||||
if( pzTab ){
|
if( pzTab ){
|
||||||
memcpy(pAlloc, zThis, nThis+1);
|
memcpy(pAlloc, zThis, nThis+1);
|
||||||
*pzTab = (char *)pAlloc;
|
*pzTab = (char *)pAlloc;
|
||||||
@ -604,12 +598,10 @@ static int sessionTableInfo(
|
|||||||
int nName = sqlite3_column_bytes(pStmt, 1);
|
int nName = sqlite3_column_bytes(pStmt, 1);
|
||||||
const unsigned char *zName = sqlite3_column_text(pStmt, 1);
|
const unsigned char *zName = sqlite3_column_text(pStmt, 1);
|
||||||
if( zName==0 ) break;
|
if( zName==0 ) break;
|
||||||
if( pazCol ){
|
memcpy(pAlloc, zName, nName+1);
|
||||||
memcpy(pAlloc, zName, nName+1);
|
azCol[i] = (char *)pAlloc;
|
||||||
azCol[i] = (char *)pAlloc;
|
pAlloc += nName+1;
|
||||||
pAlloc += nName+1;
|
abPK[i] = sqlite3_column_int(pStmt, 5);
|
||||||
}
|
|
||||||
if( pabPK ) abPK[i] = sqlite3_column_int(pStmt, 5);
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
rc = sqlite3_reset(pStmt);
|
rc = sqlite3_reset(pStmt);
|
||||||
@ -620,13 +612,13 @@ static int sessionTableInfo(
|
|||||||
** free any allocation made. An error code will be returned in this case.
|
** free any allocation made. An error code will be returned in this case.
|
||||||
*/
|
*/
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
if( pazCol ) *pazCol = (const char **)azCol;
|
*pazCol = (const char **)azCol;
|
||||||
if( pabPK ) *pabPK = abPK;
|
*pabPK = abPK;
|
||||||
}else{
|
}else{
|
||||||
if( pazCol ) *pazCol = 0;
|
*pazCol = 0;
|
||||||
if( pabPK ) *pabPK = 0;
|
*pabPK = 0;
|
||||||
if( pzTab ) *pzTab = 0;
|
if( pzTab ) *pzTab = 0;
|
||||||
sqlite3_free(pFree);
|
sqlite3_free(azCol);
|
||||||
}
|
}
|
||||||
sqlite3_finalize(pStmt);
|
sqlite3_finalize(pStmt);
|
||||||
return rc;
|
return rc;
|
||||||
@ -1785,7 +1777,7 @@ struct SessionApplyCtx {
|
|||||||
**
|
**
|
||||||
** The DELETE statement looks like this:
|
** The DELETE statement looks like this:
|
||||||
**
|
**
|
||||||
** DELETE FROM x WHERE a = :1 AND c = :3 AND :5 OR (b IS :2 AND d IS :4)
|
** DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4)
|
||||||
**
|
**
|
||||||
** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
|
** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
|
||||||
** matching b and d values, or 1 otherwise. The second case comes up if the
|
** matching b and d values, or 1 otherwise. The second case comes up if the
|
||||||
@ -1997,6 +1989,41 @@ static int sessionInsertRow(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Iterator pIter must point to an SQLITE_INSERT entry. This function
|
||||||
|
** transfers new.* values from the current iterator entry to statement
|
||||||
|
** pStmt. The table being inserted into has nCol columns.
|
||||||
|
**
|
||||||
|
** New.* value $i 0 from the iterator is bound to variable ($i+1) of
|
||||||
|
** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1)
|
||||||
|
** are transfered to the statement. Otherwise, if abPK is not NULL, it points
|
||||||
|
** to an array nCol elements in size. In this case only those values for
|
||||||
|
** which abPK[$i] is true are read from the iterator and bound to the
|
||||||
|
** statement.
|
||||||
|
**
|
||||||
|
** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK.
|
||||||
|
*/
|
||||||
|
static int sessionBindValues(
|
||||||
|
sqlite3_changeset_iter *pIter, /* Iterator to read values from */
|
||||||
|
int(*xIterValue)(sqlite3_changeset_iter *, int, sqlite3_value **),
|
||||||
|
int nCol, /* Number of columns */
|
||||||
|
u8 *abPK, /* If not NULL, bind only if true */
|
||||||
|
sqlite3_stmt *pStmt /* Bind values to this statement */
|
||||||
|
){
|
||||||
|
int i;
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
for(i=0; rc==SQLITE_OK && i<nCol; i++){
|
||||||
|
if( !abPK || abPK[i] ){
|
||||||
|
sqlite3_value *pVal;
|
||||||
|
rc = xIterValue(pIter, i, &pVal);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = sqlite3_bind_value(pStmt, i+1, pVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** SQL statement pSelect is as generated by the sessionSelectRow() function.
|
** SQL statement pSelect is as generated by the sessionSelectRow() function.
|
||||||
** This function binds the primary key values from the change that changeset
|
** This function binds the primary key values from the change that changeset
|
||||||
@ -2007,10 +2034,8 @@ static int sessionInsertRow(
|
|||||||
** error occurs, an SQLite error code is returned.
|
** error occurs, an SQLite error code is returned.
|
||||||
**
|
**
|
||||||
** If the iterator currently points to an INSERT record, bind values from the
|
** If the iterator currently points to an INSERT record, bind values from the
|
||||||
** new.* record to the SELECT statement. Or, if it points to a DELETE, bind
|
** new.* record to the SELECT statement. Or, if it points to a DELETE or
|
||||||
** values from the old.* record. If the changeset iterator points to an
|
** UPDATE, bind values from the old.* record.
|
||||||
** UPDATE, bind values from the new.* record, but use old.* values in place
|
|
||||||
** of any undefined new.* values.
|
|
||||||
*/
|
*/
|
||||||
static int sessionSeekToRow(
|
static int sessionSeekToRow(
|
||||||
sqlite3 *db, /* Database handle */
|
sqlite3 *db, /* Database handle */
|
||||||
@ -2019,27 +2044,15 @@ static int sessionSeekToRow(
|
|||||||
sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */
|
sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */
|
||||||
){
|
){
|
||||||
int rc = SQLITE_OK; /* Return code */
|
int rc = SQLITE_OK; /* Return code */
|
||||||
int i; /* Used to iterate through table columns */
|
|
||||||
int nCol; /* Number of columns in table */
|
int nCol; /* Number of columns in table */
|
||||||
int op; /* Changset operation (SQLITE_UPDATE etc.) */
|
int op; /* Changset operation (SQLITE_UPDATE etc.) */
|
||||||
const char *zDummy; /* Unused */
|
const char *zDummy; /* Unused */
|
||||||
|
|
||||||
sqlite3changeset_op(pIter, &zDummy, &nCol, &op);
|
sqlite3changeset_op(pIter, &zDummy, &nCol, &op);
|
||||||
|
rc = sessionBindValues(pIter,
|
||||||
for(i=0; rc==SQLITE_OK && i<nCol; i++){
|
op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old,
|
||||||
if( abPK[i] ){
|
nCol, abPK, pSelect
|
||||||
sqlite3_value *pVal = 0;
|
);
|
||||||
if( op!=SQLITE_DELETE ){
|
|
||||||
rc = sqlite3changeset_new(pIter, i, &pVal);
|
|
||||||
}
|
|
||||||
if( pVal==0 ){
|
|
||||||
rc = sqlite3changeset_old(pIter, i, &pVal);
|
|
||||||
}
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
rc = sqlite3_bind_value(pSelect, i+1, pVal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite3_step(pSelect);
|
rc = sqlite3_step(pSelect);
|
||||||
@ -2108,7 +2121,7 @@ static int sessionConflictHandler(
|
|||||||
if( pbReplace ){
|
if( pbReplace ){
|
||||||
rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
|
rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
|
||||||
}else{
|
}else{
|
||||||
rc = SQLITE_DONE;
|
rc = SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc==SQLITE_ROW ){
|
if( rc==SQLITE_ROW ){
|
||||||
@ -2117,7 +2130,7 @@ static int sessionConflictHandler(
|
|||||||
res = xConflict(pCtx, eType, pIter);
|
res = xConflict(pCtx, eType, pIter);
|
||||||
pIter->pConflict = 0;
|
pIter->pConflict = 0;
|
||||||
rc = sqlite3_reset(p->pSelect);
|
rc = sqlite3_reset(p->pSelect);
|
||||||
}else{
|
}else if( rc==SQLITE_OK ){
|
||||||
/* No other row with the new.* primary key. */
|
/* No other row with the new.* primary key. */
|
||||||
rc = sqlite3_reset(p->pSelect);
|
rc = sqlite3_reset(p->pSelect);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
@ -2192,16 +2205,9 @@ static int sessionApplyOneOp(
|
|||||||
sqlite3changeset_op(pIter, &zDummy, &nCol, &op);
|
sqlite3changeset_op(pIter, &zDummy, &nCol, &op);
|
||||||
|
|
||||||
if( op==SQLITE_DELETE ){
|
if( op==SQLITE_DELETE ){
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Bind values to the DELETE statement. */
|
/* Bind values to the DELETE statement. */
|
||||||
for(i=0; rc==SQLITE_OK && i<nCol; i++){
|
rc = sessionBindValues(pIter, sqlite3changeset_old, nCol, 0, p->pDelete);
|
||||||
sqlite3_value *pVal;
|
|
||||||
rc = sqlite3changeset_old(pIter, i, &pVal);
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
rc = sqlite3_bind_value(p->pDelete, i+1, pVal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){
|
if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){
|
||||||
rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0);
|
rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0);
|
||||||
}
|
}
|
||||||
@ -2254,44 +2260,20 @@ static int sessionApplyOneOp(
|
|||||||
);
|
);
|
||||||
|
|
||||||
}else if( rc==SQLITE_CONSTRAINT ){
|
}else if( rc==SQLITE_CONSTRAINT ){
|
||||||
/* This may be a CONSTRAINT or CONFLICT error. It is a CONFLICT if
|
/* This is always a CONSTRAINT conflict. */
|
||||||
** the only problem is a duplicate PRIMARY KEY, or a CONSTRAINT
|
rc = sessionConflictHandler(
|
||||||
** otherwise. */
|
SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
|
||||||
int bPKChange = 0;
|
|
||||||
|
|
||||||
/* Check if the PK has been modified. */
|
|
||||||
rc = SQLITE_OK;
|
|
||||||
for(i=0; i<nCol && rc==SQLITE_OK; i++){
|
|
||||||
if( p->abPK[i] ){
|
|
||||||
sqlite3_value *pNew;
|
|
||||||
rc = sqlite3changeset_new(pIter, i, &pNew);
|
|
||||||
if( rc==SQLITE_OK && pNew ){
|
|
||||||
bPKChange = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = sessionConflictHandler(SQLITE_CHANGESET_CONFLICT,
|
|
||||||
p, pIter, xConflict, pCtx, (bPKChange ? pbReplace : 0)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
int i;
|
|
||||||
assert( op==SQLITE_INSERT );
|
assert( op==SQLITE_INSERT );
|
||||||
for(i=0; rc==SQLITE_OK && i<nCol; i++){
|
rc = sessionBindValues(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
|
||||||
sqlite3_value *pVal;
|
|
||||||
rc = sqlite3changeset_new(pIter, i, &pVal);
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
rc = sqlite3_bind_value(p->pInsert, i+1, pVal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
sqlite3_step(p->pInsert);
|
sqlite3_step(p->pInsert);
|
||||||
rc = sqlite3_reset(p->pInsert);
|
rc = sqlite3_reset(p->pInsert);
|
||||||
if( rc==SQLITE_CONSTRAINT && xConflict ){
|
if( rc==SQLITE_CONSTRAINT ){
|
||||||
rc = sessionConflictHandler(
|
rc = sessionConflictHandler(
|
||||||
SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
|
SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
|
||||||
);
|
);
|
||||||
@ -2369,21 +2351,11 @@ int sqlite3changeset_apply(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( bReplace ){
|
if( bReplace ){
|
||||||
|
assert( pIter->op==SQLITE_INSERT );
|
||||||
rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
|
rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
int i;
|
rc = sessionBindValues(pIter,
|
||||||
for(i=0; i<sApply.nCol; i++){
|
sqlite3changeset_new, sApply.nCol, sApply.abPK, sApply.pDelete);
|
||||||
if( sApply.abPK[i] ){
|
|
||||||
sqlite3_value *pVal;
|
|
||||||
rc = sqlite3changeset_new(pIter, i, &pVal);
|
|
||||||
if( rc==SQLITE_OK && pVal==0 ){
|
|
||||||
rc = sqlite3changeset_old(pIter, i, &pVal);
|
|
||||||
}
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
rc = sqlite3_bind_value(sApply.pDelete, i+1, pVal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sqlite3_bind_int(sApply.pDelete, sApply.nCol+1, 1);
|
sqlite3_bind_int(sApply.pDelete, sApply.nCol+1, 1);
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
|
32
manifest
32
manifest
@ -1,8 +1,5 @@
|
|||||||
-----BEGIN PGP SIGNED MESSAGE-----
|
C Remove\ssome\sunreachable\scode\sin\ssqlite3session.c.\sAdd\stest\scases.
|
||||||
Hash: SHA1
|
D 2011-03-21T19:41:30
|
||||||
|
|
||||||
C Merge\sin\sthe\ssqlite3_db_config()\senhancements\sfor\senabling\sand\sdisabling\nFKs\sand\striggers\sfrom\strunk.
|
|
||||||
D 2011-03-21T17:17:49.766
|
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
|
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -102,11 +99,11 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
|
|||||||
F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
|
F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
|
||||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||||
F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a
|
F ext/session/session1.test 1e8cda2cc8a60171dabc0fbec4124f9f7c943f23
|
||||||
F ext/session/session2.test 6462c21d3795d9e48ffea2e7550d1b2d6da66dfb
|
F ext/session/session2.test 54c3a5ecdc60548a8ab0a86793b136de6f32a255
|
||||||
F ext/session/session_common.tcl 880b554b0bcadcabe1331afb87d58ad1ed2510c4
|
F ext/session/session_common.tcl d7bb85c3fd76d53bd9b909da808d5c16f5213111
|
||||||
F ext/session/sessionfault.test 4190de237b2c76ca7529ef415778a862d7d0fa30
|
F ext/session/sessionfault.test da234166d5d044c91964863174d7171b0561708b
|
||||||
F ext/session/sqlite3session.c c5a60c2cf21f8892f9ae4850fad2d7859c2c3692
|
F ext/session/sqlite3session.c 1ca39db8a10b8bcb973b35a68c0924b6a64c4a97
|
||||||
F ext/session/sqlite3session.h 2c071ee5925e82c21c7c9c296a0422c039607106
|
F ext/session/sqlite3session.h 2c071ee5925e82c21c7c9c296a0422c039607106
|
||||||
F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535
|
F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||||
@ -926,14 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P 32e95164d1192b87b1ab019549fd2394642cd3fe 09e167f9c14625924b17bbb1f292f89ac9ddc93a
|
P 2b3c8b9d9aa909f64a29ed8167de24c328c50d85
|
||||||
R a0add848dadb7db1c3f35ed60dcfc8d8
|
R c6506b08e053cfdd0bd616ee1b17add6
|
||||||
U drh
|
U dan
|
||||||
Z 2f330aa02552b587cf8d8ca729d4e813
|
Z 4cc9deaf80e50ac14cbc33555ec1ddf1
|
||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
|
||||||
|
|
||||||
iD8DBQFNh4hAoxKgR168RlERAlZKAJ9kBWPV0idzBc6FhOD1zal2v2X27gCfZtYB
|
|
||||||
1RyGCy9Ef7CucSG+WlvrUDU=
|
|
||||||
=TZ5z
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
|
@ -1 +1 @@
|
|||||||
2b3c8b9d9aa909f64a29ed8167de24c328c50d85
|
39cdfa5324ae91bfbbac733b1e3e2d33ca883340
|
Reference in New Issue
Block a user