Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix handling of "UPDATE OR REPLACE" statements run on zipfile virtual tables. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | testFixes |
Files: | files | file ages | folders |
SHA3-256: |
9a5ef341de2bd2fc4657a510f48159f7 |
User & Date: | dan 2018-03-20 13:26:01.034 |
Context
2018-03-20
| ||
16:56 | For 'zipfile', detect attempts to cause a duplicate entry via UPDATE. Also, fix handling of 'UPDATE OR REPLACE' statements run on zipfile virtual tables. Win32 portability fixes to the 'fileio' extension. Miscellaneous test fixes. (check-in: b36caeca91 user: mistachkin tags: trunk) | |
13:26 | Fix handling of "UPDATE OR REPLACE" statements run on zipfile virtual tables. (Closed-Leaf check-in: 9a5ef341de user: dan tags: testFixes) | |
12:12 | Add a test case for the fix on this branch. (check-in: 7834cf6c28 user: dan tags: testFixes) | |
Changes
Changes to ext/misc/zipfile.c.
︙ | ︙ | |||
1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 | */ static u32 zipfileGetTime(sqlite3_value *pVal){ if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ return zipfileTime(); } return (u32)sqlite3_value_int64(pVal); } /* ** xUpdate method. */ static int zipfileUpdate( sqlite3_vtab *pVtab, int nVal, | > > > > > > > > > > > > > | 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 | */ static u32 zipfileGetTime(sqlite3_value *pVal){ if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ return zipfileTime(); } return (u32)sqlite3_value_int64(pVal); } /* ** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry ** linked list. Remove it from the list and free the object. */ static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){ if( pOld ){ ZipfileEntry **pp; for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext)); *pp = (*pp)->pNext; zipfileEntryFree(pOld); } } /* ** xUpdate method. */ static int zipfileUpdate( sqlite3_vtab *pVtab, int nVal, |
︙ | ︙ | |||
1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 | int nPath = 0; /* strlen(zPath) */ const u8 *pData = 0; /* Pointer to buffer containing content */ int nData = 0; /* Size of pData buffer in bytes */ int iMethod = 0; /* Compression method for new entry */ u8 *pFree = 0; /* Free this */ char *zFree = 0; /* Also free this */ ZipfileEntry *pOld = 0; int bUpdate = 0; /* True for an update that modifies "name" */ int bIsDir = 0; u32 iCrc32 = 0; if( pTab->pWriteFd==0 ){ rc = zipfileBegin(pVtab); if( rc!=SQLITE_OK ) return rc; | > | 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 | int nPath = 0; /* strlen(zPath) */ const u8 *pData = 0; /* Pointer to buffer containing content */ int nData = 0; /* Size of pData buffer in bytes */ int iMethod = 0; /* Compression method for new entry */ u8 *pFree = 0; /* Free this */ char *zFree = 0; /* Also free this */ ZipfileEntry *pOld = 0; ZipfileEntry *pOld2 = 0; int bUpdate = 0; /* True for an update that modifies "name" */ int bIsDir = 0; u32 iCrc32 = 0; if( pTab->pWriteFd==0 ){ rc = zipfileBegin(pVtab); if( rc!=SQLITE_OK ) return rc; |
︙ | ︙ | |||
1627 1628 1629 1630 1631 1632 1633 | for(p=pTab->pFirstEntry; p; p=p->pNext){ if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){ switch( sqlite3_vtab_on_conflict(pTab->db) ){ case SQLITE_IGNORE: { goto zipfile_update_done; } case SQLITE_REPLACE: { | | | 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 | for(p=pTab->pFirstEntry; p; p=p->pNext){ if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){ switch( sqlite3_vtab_on_conflict(pTab->db) ){ case SQLITE_IGNORE: { goto zipfile_update_done; } case SQLITE_REPLACE: { pOld2 = p; break; } default: { zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath); rc = SQLITE_CONSTRAINT; break; } |
︙ | ︙ | |||
1665 1666 1667 1668 1669 1670 1671 | pNew->mUnixTime = (u32)mTime; rc = zipfileAppendEntry(pTab, pNew, pData, nData); zipfileAddEntry(pTab, pOld, pNew); } } } | | < | | | | | | 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 | pNew->mUnixTime = (u32)mTime; rc = zipfileAppendEntry(pTab, pNew, pData, nData); zipfileAddEntry(pTab, pOld, pNew); } } } if( rc==SQLITE_OK && (pOld || pOld2) ){ ZipfileCsr *pCsr; for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){ pCsr->pCurrent = pCsr->pCurrent->pNext; pCsr->bNoop = 1; } } zipfileRemoveEntryFromList(pTab, pOld); zipfileRemoveEntryFromList(pTab, pOld2); } zipfile_update_done: sqlite3_free(pFree); sqlite3_free(zFree); return rc; } |
︙ | ︙ |
Changes to test/zipfile2.test.
︙ | ︙ | |||
230 231 232 233 234 235 236 237 238 239 | CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip'); INSERT INTO temp.zip (name,data) VALUES ('test','test'); UPDATE temp.zip set name=name||'new' where name='test'; INSERT INTO temp.zip (name,data) VALUES ('test','test'); UPDATE temp.zip set name=name||'new' where name='test'; } {1 {duplicate name: "testnew"}} finish_test | > > > > > > > | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip'); INSERT INTO temp.zip (name,data) VALUES ('test','test'); UPDATE temp.zip set name=name||'new' where name='test'; INSERT INTO temp.zip (name,data) VALUES ('test','test'); UPDATE temp.zip set name=name||'new' where name='test'; } {1 {duplicate name: "testnew"}} forcedelete test.zip do_execsql_test 6.3 { INSERT INTO temp.zip (name,data) VALUES ('test1','test'); INSERT INTO temp.zip (name,data) VALUES ('test2','test'); UPDATE OR REPLACE zip SET name='test2' WHERE name='test1'; SELECT name FROM zip; } {test2} finish_test |