From: drh Date: Tue, 16 Jun 2015 16:39:01 +0000 (+0000) Subject: Ensure that the CREATE TABLE AS statement correctly undoes partial changes X-Git-Tag: version-3.8.11~161 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0dd5cdaea5594977a58cd4de136c135465b78864;p=thirdparty%2Fsqlite.git Ensure that the CREATE TABLE AS statement correctly undoes partial changes to the sqlite_master table if the SELECT on the right-hand side aborts with an error. Fix for ticket [873cae2b6e25b] FossilOrigin-Name: 400e025e7c61efab71b891743c07a0862e5bb934 --- diff --git a/manifest b/manifest index 739702bb43..aa791daea3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sICU\stests\sto\saccount\sfor\srecent\schanges\sin\sthe\sofficial\s\nUnicode\sdefinition\sof\swhitespace. -D 2015-06-15T16:40:38.658 +C Ensure\sthat\sthe\sCREATE\sTABLE\sAS\sstatement\scorrectly\sundoes\spartial\schanges\nto\sthe\ssqlite_master\stable\sif\sthe\sSELECT\son\sthe\sright-hand\sside\saborts\swith\nan\serror.\s\sFix\sfor\sticket\s[873cae2b6e25b] +D 2015-06-16T16:39:01.822 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -195,7 +195,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c e557af3120ac3e5cea9680ca12688cf26b0222bc F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4 -F src/build.c 6770b74ccb51cb485e81057c625f77455d5ddc06 +F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575 F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b @@ -317,7 +317,7 @@ F src/vdbe.c c9b8985dfc5df9bd512342ea2e56af4be30cb31a F src/vdbe.h 90048aea1910f9df93e6044592bd4a466dc9c5e7 F src/vdbeInt.h 20295e482121d13437f69985f77db211cdc8bac1 F src/vdbeapi.c 6a0d7757987018ff6b1b81bc5293219cd26bb299 -F src/vdbeaux.c 89c85926ce346988d275132e05ddb0c9681807c2 +F src/vdbeaux.c b4a127630ef81d5ea85346262f38aaf482ece4d9 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c 67b302dc6df64b4d6785881c5d22bd4f9b17739d F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b @@ -943,7 +943,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 -F test/table.test bd841e8df69b99172ce9c7d53587463913d711ca +F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054 @@ -1286,7 +1286,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ae6876521819e7a8ce473c8f96617cba35e2156d -R a07fe181e35e9a94a47adc71c8d7ce80 +P 0816525386ac51454b7b09a507e45b6a2cb8bf6e +R aac2c97e6c3d9c60b2cdef77f1695ab5 U drh -Z bb1a4c355eadbeb14b6625f3b7a90f48 +Z 6de6d20f4ab095b721ee46bcbe62906a diff --git a/manifest.uuid b/manifest.uuid index 20cb583453..4307100089 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0816525386ac51454b7b09a507e45b6a2cb8bf6e \ No newline at end of file +400e025e7c61efab71b891743c07a0862e5bb934 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 8c62fd18d5..2936805365 100644 --- a/src/build.c +++ b/src/build.c @@ -976,7 +976,7 @@ void sqlite3StartTable( int j1; int fileFormat; int reg1, reg2, reg3; - sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3BeginWriteOperation(pParse, 1, iDb); #ifndef SQLITE_OMIT_VIRTUALTABLE if( isVirtual ){ @@ -1924,6 +1924,7 @@ void sqlite3EndTable( regRec = ++pParse->nMem; regRowid = ++pParse->nMem; assert(pParse->nTab==1); + sqlite3MayAbort(pParse); sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); pParse->nTab = 2; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index fc667ed47d..53c1d80119 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -414,6 +414,7 @@ static Op *opIterNext(VdbeOpIter *p){ ** * OP_VUpdate ** * OP_VRename ** * OP_FkCounter with P2==0 (immediate foreign key constraint) +** * OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...) ** ** Then check that the value of Parse.mayAbort is true if an ** ABORT may be thrown, or false otherwise. Return true if it does @@ -425,6 +426,8 @@ static Op *opIterNext(VdbeOpIter *p){ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ int hasAbort = 0; int hasFkCounter = 0; + int hasCreateTable = 0; + int hasInitCoroutine = 0; Op *pOp; VdbeOpIter sIter; memset(&sIter, 0, sizeof(sIter)); @@ -439,6 +442,8 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ hasAbort = 1; break; } + if( opcode==OP_CreateTable ) hasCreateTable = 1; + if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1; #ifndef SQLITE_OMIT_FOREIGN_KEY if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){ hasFkCounter = 1; @@ -452,7 +457,8 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ ** through all opcodes and hasAbort may be set incorrectly. Return ** true for this case to prevent the assert() in the callers frame ** from failing. */ - return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter ); + return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter + || (hasCreateTable && hasInitCoroutine) ); } #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */ diff --git a/test/table.test b/test/table.test index faa9712bf7..2aec6473e6 100644 --- a/test/table.test +++ b/test/table.test @@ -808,4 +808,20 @@ do_execsql_test table-17.1 { SELECT p, q, '|' FROM t3 ORDER BY p; } {1 1 | 2 2 |} +# 2015-06-16 +# Ticket [https://www.sqlite.org/src/tktview/873cae2b6e25b1991ce5e9b782f9cd0409b96063] +# Make sure a CREATE TABLE AS statement correctly rolls back partial changes to the +# sqlite_master table when the SELECT on the right-hand side aborts. +# +do_catchsql_test table-18.1 { + DROP TABLE IF EXISTS t1; + BEGIN; + CREATE TABLE t1 AS SELECT zeroblob(2e20); +} {1 {string or blob too big}} +do_execsql_test table-18.2 { + COMMIT; + PRAGMA integrity_check; +} {ok} + + finish_test