Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Ensure the correct error code is returned if an attempt to parse a database schema made by an ATTACH statement fails. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c272196115ab3926e56b6f4183ec127e |
User & Date: | dan 2010-07-06 07:36:18.000 |
Context
2010-07-06
| ||
09:29 | Reorder variable declarations in the previous check-in to avoid putting code before declarations when not testing. (check-in: d1fe8ab4a1 user: drh tags: trunk) | |
07:36 | Ensure the correct error code is returned if an attempt to parse a database schema made by an ATTACH statement fails. (check-in: c272196115 user: dan tags: trunk) | |
2010-07-05
| ||
21:00 | Modify the VFS xAccess() method on winNT so that it returns false for an exists test of a zero-length file. This makes the windows VFS work the same as the unix VFS. (check-in: ec35f25403 user: drh tags: trunk) | |
Changes
Changes to src/prepare.c.
︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 | corruptSchema(pData, argv[0], 0); }else if( argv[2] && argv[2][0] ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ int rc; sqlite3_stmt *pStmt; assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); db->init.orphanTrigger = 0; | > | > > | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | corruptSchema(pData, argv[0], 0); }else if( argv[2] && argv[2][0] ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ int rc; sqlite3_stmt *pStmt; assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); db->init.orphanTrigger = 0; TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); rc = db->errCode; assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = 0; if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ assert( iDb==1 ); }else{ pData->rc = rc; if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); }else if( argv[0]==0 ){ corruptSchema(pData, 0, 0); |
︙ | ︙ |
Changes to test/notify3.test.
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 | BEGIN EXCLUSIVE; INSERT INTO t2 VALUES('t2 C', 't2 D'); } db2 } {} do_test notify3-1.4 { catchsql { ATTACH 'test.db2' AS aux } } {0 {}} do_test notify3-1.5 { catchsql { SELECT * FROM t2 } } {1 {database schema is locked: aux}} do_test notify3-1.6 { list [sqlite3_errcode db] [sqlite3_extended_errcode db] } {SQLITE_LOCKED SQLITE_LOCKED_SHAREDCACHE} | > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | BEGIN EXCLUSIVE; INSERT INTO t2 VALUES('t2 C', 't2 D'); } db2 } {} do_test notify3-1.4 { catchsql { ATTACH 'test.db2' AS aux } } {0 {}} do_test notify3-1.5 { catchsql { SELECT * FROM t2 } } {1 {database schema is locked: aux}} do_test notify3-1.6 { list [sqlite3_errcode db] [sqlite3_extended_errcode db] } {SQLITE_LOCKED SQLITE_LOCKED_SHAREDCACHE} |
︙ | ︙ | |||
70 71 72 73 74 75 76 77 78 79 80 | set ::when 2 execsql { COMMIT } db2 set ::res } {2} do_test notify3-1.9 { catchsql { SELECT * FROM t2 } } {0 {{t2 A} {t2 B} {t2 C} {t2 D}}} sqlite3_enable_shared_cache $esc finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | set ::when 2 execsql { COMMIT } db2 set ::res } {2} do_test notify3-1.9 { catchsql { SELECT * FROM t2 } } {0 {{t2 A} {t2 B} {t2 C} {t2 D}}} db close set err {{1 {unable to open database: test.db2}}} set noerr {{0 {}}} # When a new database is attached, the connection doing the attaching # tries to load any unloaded schemas for both the new database and any # already attached databases (including the main database). If it is # unable to load any such schemas, then the ATTACH statement fails. # # This block tests that if the loading of schemas as a result of an # ATTACH fails due to locks on the schema table held by other shared-cache # connections the extended error code is SQLITE_LOCKED_SHAREDCACHE and # it is possible to use the unlock-notify mechanism to determine when # the ATTACH might succeed. # foreach { tn db1_loaded db2_loaded enable_extended_errors result error1 error2 } " 0 0 0 0 $err SQLITE_LOCKED SQLITE_LOCKED_SHAREDCACHE 1 0 0 1 $err SQLITE_LOCKED_SHAREDCACHE SQLITE_LOCKED_SHAREDCACHE 2 0 1 0 $err SQLITE_LOCKED SQLITE_LOCKED_SHAREDCACHE 3 0 1 1 $err SQLITE_LOCKED_SHAREDCACHE SQLITE_LOCKED_SHAREDCACHE 4 1 0 0 $err SQLITE_LOCKED SQLITE_LOCKED_SHAREDCACHE 5 1 0 1 $err SQLITE_LOCKED_SHAREDCACHE SQLITE_LOCKED_SHAREDCACHE 6 1 1 0 $noerr SQLITE_OK SQLITE_OK 7 1 1 1 $noerr SQLITE_OK SQLITE_OK " { do_test notify3-2.$tn.1 { catch { db1 close } catch { db2 close } sqlite3 db1 test.db sqlite3 db2 test.db2 sqlite3_extended_result_codes db1 $enable_extended_errors sqlite3_extended_result_codes db2 $enable_extended_errors if { $db1_loaded } { db1 eval "SELECT * FROM sqlite_master" } if { $db2_loaded } { db2 eval "SELECT * FROM sqlite_master" } db2 eval "BEGIN EXCLUSIVE" catchsql "ATTACH 'test.db2' AS two" db1 } $result do_test notify3-2.$tn.2 { list [sqlite3_errcode db1] [sqlite3_extended_errcode db1] } [list $error1 $error2] do_test notify3-2.$tn.3 { db1 unlock_notify {set invoked 1} set invoked 0 db2 eval commit set invoked } [lindex $result 0] } catch { db1 close } catch { db2 close } sqlite3_enable_shared_cache $esc finish_test |