/ Check-in [b861328a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:In the sessions module, avoid recording a change if an UPDATE statement overwrites a column with REAL affinity containing an integer value with the same value.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions-fix
Files: files | file ages | folders
SHA1:b861328ab9ceec6926d97658c3606e6ae9ad39bf
User & Date: dan 2016-10-21 21:21:45
Context
2016-10-22
01:22
In the sessions module, avoid recording a change if an UPDATE statement overwrites a column with REAL affinity containing an integer value with the same value. check-in: 5f3e6028 user: drh tags: trunk
2016-10-21
21:21
In the sessions module, avoid recording a change if an UPDATE statement overwrites a column with REAL affinity containing an integer value with the same value. Closed-Leaf check-in: b861328a user: dan tags: sessions-fix
17:39
Add ".mode quote" to the command-line shell. check-in: c4f5fa78 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/session/session1.test.

   565    565   breakpoint
   566    566   do_changeset_test 10.1.2 S "
   567    567     {INSERT $tblname 0 X. {} {t uvw t abc}}
   568    568     {DELETE $tblname 0 X. {t xyz t def} {}}
   569    569   "
   570    570   do_test 10.1.4 { S delete } {}
   571    571   
          572  +#-------------------------------------------------------------------------
          573  +# Test the effect of updating a column from 0.0 to 0.0.
          574  +#
          575  +reset_db
          576  +do_execsql_test 11.1 {
          577  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL);
          578  +  INSERT INTO t1 VALUES(1, 0.0);
          579  +}
          580  +do_iterator_test 11.2 * {
          581  +  UPDATE t1 SET b = 0.0;
          582  +} {
          583  +}
   572    584   
   573    585   finish_test

Changes to src/vdbeInt.h.

   426    426     u8 *aRecord;                    /* old.* database record */
   427    427     KeyInfo keyinfo;
   428    428     UnpackedRecord *pUnpacked;      /* Unpacked version of aRecord[] */
   429    429     UnpackedRecord *pNewUnpacked;   /* Unpacked version of new.* record */
   430    430     int iNewReg;                    /* Register for new.* values */
   431    431     i64 iKey1;                      /* First key value passed to hook */
   432    432     i64 iKey2;                      /* Second key value passed to hook */
   433         -  int iPKey;                      /* If not negative index of IPK column */
   434    433     Mem *aNew;                      /* Array of new.* values */
          434  +  Table *pTab;                    /* Schema object being upated */          
   435    435   };
   436    436   
   437    437   /*
   438    438   ** Function prototypes
   439    439   */
   440    440   void sqlite3VdbeError(Vdbe*, const char *, ...);
   441    441   void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);

Changes to src/vdbeapi.c.

  1706   1706       }
  1707   1707       p->aRecord = aRec;
  1708   1708     }
  1709   1709   
  1710   1710     if( iIdx>=p->pUnpacked->nField ){
  1711   1711       *ppValue = (sqlite3_value *)columnNullValue();
  1712   1712     }else{
         1713  +    Mem *pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
  1713   1714       *ppValue = &p->pUnpacked->aMem[iIdx];
  1714         -    if( iIdx==p->iPKey ){
  1715         -      sqlite3VdbeMemSetInt64(*ppValue, p->iKey1);
         1715  +    if( iIdx==p->pTab->iPKey ){
         1716  +      sqlite3VdbeMemSetInt64(pMem, p->iKey1);
         1717  +    }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
         1718  +      if( pMem->flags & MEM_Int ){
         1719  +        sqlite3VdbeMemRealify(pMem);
         1720  +      }
  1716   1721       }
  1717   1722     }
  1718   1723   
  1719   1724    preupdate_old_out:
  1720   1725     sqlite3Error(db, rc);
  1721   1726     return sqlite3ApiExit(db, rc);
  1722   1727   }
................................................................................
  1785   1790         }
  1786   1791         p->pNewUnpacked = pUnpack;
  1787   1792       }
  1788   1793       if( iIdx>=pUnpack->nField ){
  1789   1794         pMem = (sqlite3_value *)columnNullValue();
  1790   1795       }else{
  1791   1796         pMem = &pUnpack->aMem[iIdx];
  1792         -      if( iIdx==p->iPKey ){
         1797  +      if( iIdx==p->pTab->iPKey ){
  1793   1798           sqlite3VdbeMemSetInt64(pMem, p->iKey2);
  1794   1799         }
  1795   1800       }
  1796   1801     }else{
  1797   1802       /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
  1798   1803       ** value. Make a copy of the cell contents and return a pointer to it.
  1799   1804       ** It is not safe to return a pointer to the memory cell itself as the
................................................................................
  1806   1811           rc = SQLITE_NOMEM;
  1807   1812           goto preupdate_new_out;
  1808   1813         }
  1809   1814       }
  1810   1815       assert( iIdx>=0 && iIdx<p->pCsr->nField );
  1811   1816       pMem = &p->aNew[iIdx];
  1812   1817       if( pMem->flags==0 ){
  1813         -      if( iIdx==p->iPKey ){
         1818  +      if( iIdx==p->pTab->iPKey ){
  1814   1819           sqlite3VdbeMemSetInt64(pMem, p->iKey2);
  1815   1820         }else{
  1816   1821           rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
  1817   1822           if( rc!=SQLITE_OK ) goto preupdate_new_out;
  1818   1823         }
  1819   1824       }
  1820   1825     }

Changes to src/vdbeaux.c.

  4613   4613     preupdate.iNewReg = iReg;
  4614   4614     preupdate.keyinfo.db = db;
  4615   4615     preupdate.keyinfo.enc = ENC(db);
  4616   4616     preupdate.keyinfo.nField = pTab->nCol;
  4617   4617     preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
  4618   4618     preupdate.iKey1 = iKey1;
  4619   4619     preupdate.iKey2 = iKey2;
  4620         -  preupdate.iPKey = pTab->iPKey;
         4620  +  preupdate.pTab = pTab;
  4621   4621   
  4622   4622     db->pPreUpdate = &preupdate;
  4623   4623     db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
  4624   4624     db->pPreUpdate = 0;
  4625   4625     sqlite3DbFree(db, preupdate.aRecord);
  4626   4626     vdbeFreeUnpacked(db, preupdate.pUnpacked);
  4627   4627     vdbeFreeUnpacked(db, preupdate.pNewUnpacked);