/ 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 Unified Diffs Ignore Whitespace Patch

Changes to ext/session/session1.test.

565
566
567
568
569
570
571


572










573
breakpoint
do_changeset_test 10.1.2 S "
  {INSERT $tblname 0 X. {} {t uvw t abc}}
  {DELETE $tblname 0 X. {t xyz t def} {}}
"
do_test 10.1.4 { S delete } {}














finish_test







>
>
|
>
>
>
>
>
>
>
>
>
>

565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
breakpoint
do_changeset_test 10.1.2 S "
  {INSERT $tblname 0 X. {} {t uvw t abc}}
  {DELETE $tblname 0 X. {t xyz t def} {}}
"
do_test 10.1.4 { S delete } {}

#-------------------------------------------------------------------------
# Test the effect of updating a column from 0.0 to 0.0.
#
reset_db
do_execsql_test 11.1 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL);
  INSERT INTO t1 VALUES(1, 0.0);
}
do_iterator_test 11.2 * {
  UPDATE t1 SET b = 0.0;
} {
}

finish_test

Changes to src/vdbeInt.h.

426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
  u8 *aRecord;                    /* old.* database record */
  KeyInfo keyinfo;
  UnpackedRecord *pUnpacked;      /* Unpacked version of aRecord[] */
  UnpackedRecord *pNewUnpacked;   /* Unpacked version of new.* record */
  int iNewReg;                    /* Register for new.* values */
  i64 iKey1;                      /* First key value passed to hook */
  i64 iKey2;                      /* Second key value passed to hook */
  int iPKey;                      /* If not negative index of IPK column */
  Mem *aNew;                      /* Array of new.* values */

};

/*
** Function prototypes
*/
void sqlite3VdbeError(Vdbe*, const char *, ...);
void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);







<

>







426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
  u8 *aRecord;                    /* old.* database record */
  KeyInfo keyinfo;
  UnpackedRecord *pUnpacked;      /* Unpacked version of aRecord[] */
  UnpackedRecord *pNewUnpacked;   /* Unpacked version of new.* record */
  int iNewReg;                    /* Register for new.* values */
  i64 iKey1;                      /* First key value passed to hook */
  i64 iKey2;                      /* Second key value passed to hook */

  Mem *aNew;                      /* Array of new.* values */
  Table *pTab;                    /* Schema object being upated */          
};

/*
** Function prototypes
*/
void sqlite3VdbeError(Vdbe*, const char *, ...);
void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);

Changes to src/vdbeapi.c.

1706
1707
1708
1709
1710
1711
1712

1713
1714
1715




1716
1717
1718
1719
1720
1721
1722
....
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
....
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
    }
    p->aRecord = aRec;
  }

  if( iIdx>=p->pUnpacked->nField ){
    *ppValue = (sqlite3_value *)columnNullValue();
  }else{

    *ppValue = &p->pUnpacked->aMem[iIdx];
    if( iIdx==p->iPKey ){
      sqlite3VdbeMemSetInt64(*ppValue, p->iKey1);




    }
  }

 preupdate_old_out:
  sqlite3Error(db, rc);
  return sqlite3ApiExit(db, rc);
}
................................................................................
      }
      p->pNewUnpacked = pUnpack;
    }
    if( iIdx>=pUnpack->nField ){
      pMem = (sqlite3_value *)columnNullValue();
    }else{
      pMem = &pUnpack->aMem[iIdx];
      if( iIdx==p->iPKey ){
        sqlite3VdbeMemSetInt64(pMem, p->iKey2);
      }
    }
  }else{
    /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
    ** value. Make a copy of the cell contents and return a pointer to it.
    ** It is not safe to return a pointer to the memory cell itself as the
................................................................................
        rc = SQLITE_NOMEM;
        goto preupdate_new_out;
      }
    }
    assert( iIdx>=0 && iIdx<p->pCsr->nField );
    pMem = &p->aNew[iIdx];
    if( pMem->flags==0 ){
      if( iIdx==p->iPKey ){
        sqlite3VdbeMemSetInt64(pMem, p->iKey2);
      }else{
        rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
        if( rc!=SQLITE_OK ) goto preupdate_new_out;
      }
    }
  }







>

|
|
>
>
>
>







 







|







 







|







1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
....
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
....
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
    }
    p->aRecord = aRec;
  }

  if( iIdx>=p->pUnpacked->nField ){
    *ppValue = (sqlite3_value *)columnNullValue();
  }else{
    Mem *pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
    *ppValue = &p->pUnpacked->aMem[iIdx];
    if( iIdx==p->pTab->iPKey ){
      sqlite3VdbeMemSetInt64(pMem, p->iKey1);
    }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
      if( pMem->flags & MEM_Int ){
        sqlite3VdbeMemRealify(pMem);
      }
    }
  }

 preupdate_old_out:
  sqlite3Error(db, rc);
  return sqlite3ApiExit(db, rc);
}
................................................................................
      }
      p->pNewUnpacked = pUnpack;
    }
    if( iIdx>=pUnpack->nField ){
      pMem = (sqlite3_value *)columnNullValue();
    }else{
      pMem = &pUnpack->aMem[iIdx];
      if( iIdx==p->pTab->iPKey ){
        sqlite3VdbeMemSetInt64(pMem, p->iKey2);
      }
    }
  }else{
    /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
    ** value. Make a copy of the cell contents and return a pointer to it.
    ** It is not safe to return a pointer to the memory cell itself as the
................................................................................
        rc = SQLITE_NOMEM;
        goto preupdate_new_out;
      }
    }
    assert( iIdx>=0 && iIdx<p->pCsr->nField );
    pMem = &p->aNew[iIdx];
    if( pMem->flags==0 ){
      if( iIdx==p->pTab->iPKey ){
        sqlite3VdbeMemSetInt64(pMem, p->iKey2);
      }else{
        rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
        if( rc!=SQLITE_OK ) goto preupdate_new_out;
      }
    }
  }

Changes to src/vdbeaux.c.

4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
  preupdate.iNewReg = iReg;
  preupdate.keyinfo.db = db;
  preupdate.keyinfo.enc = ENC(db);
  preupdate.keyinfo.nField = pTab->nCol;
  preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
  preupdate.iKey1 = iKey1;
  preupdate.iKey2 = iKey2;
  preupdate.iPKey = pTab->iPKey;

  db->pPreUpdate = &preupdate;
  db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
  db->pPreUpdate = 0;
  sqlite3DbFree(db, preupdate.aRecord);
  vdbeFreeUnpacked(db, preupdate.pUnpacked);
  vdbeFreeUnpacked(db, preupdate.pNewUnpacked);







|







4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
  preupdate.iNewReg = iReg;
  preupdate.keyinfo.db = db;
  preupdate.keyinfo.enc = ENC(db);
  preupdate.keyinfo.nField = pTab->nCol;
  preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
  preupdate.iKey1 = iKey1;
  preupdate.iKey2 = iKey2;
  preupdate.pTab = pTab;

  db->pPreUpdate = &preupdate;
  db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
  db->pPreUpdate = 0;
  sqlite3DbFree(db, preupdate.aRecord);
  vdbeFreeUnpacked(db, preupdate.pUnpacked);
  vdbeFreeUnpacked(db, preupdate.pNewUnpacked);