/ Check-in [8b8ef445]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:New testcase macros to ensure that MEM_IntReal is fully tested.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | int-real
Files: files | file ages | folders
SHA3-256: 8b8ef445ccccc148af2cda5975986af0d134352fe16283f65d0f8a91c9ffa932
User & Date: drh 2019-05-04 01:29:13
Context
2019-05-04
01:41
In the sqlite3_value or Mem object, make the MEM_IntReal type completely independent from MEM_Int and MEM_Real. This helps avoid problems when inserting non-float values into a "REAL" column. check-in: 5a8a23ee user: drh tags: trunk
01:29
New testcase macros to ensure that MEM_IntReal is fully tested. Closed-Leaf check-in: 8b8ef445 user: drh tags: int-real
2019-05-03
21:17
Add the SQLITE_TESTCTRL_RESULT_INTREAL test-control and use it to create the intreal() SQL function in testfixture. Write a few simple tests to prove this all works. TH3 will hold most of the INTREAL tests, probably. check-in: c9838731 user: drh tags: int-real
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/vdbe.c.

   349    349       /* Only attempt the conversion to TEXT if there is an integer or real
   350    350       ** representation (blob and NULL do not get converted) but no string
   351    351       ** representation.  It would be harmless to repeat the conversion if 
   352    352       ** there is already a string rep, but it is pointless to waste those
   353    353       ** CPU cycles. */
   354    354       if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
   355    355         if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
          356  +        testcase( pRec->flags & MEM_Int );
          357  +        testcase( pRec->flags & MEM_Real );
          358  +        testcase( pRec->flags & MEM_IntReal );
   356    359           sqlite3VdbeMemStringify(pRec, enc, 1);
   357    360         }
   358    361       }
   359    362       pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
   360    363     }
   361    364   }
   362    365   
................................................................................
   412    415   ** none.  
   413    416   **
   414    417   ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
   415    418   ** But it does set pMem->u.r and pMem->u.i appropriately.
   416    419   */
   417    420   static u16 numericType(Mem *pMem){
   418    421     if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){
          422  +    testcase( pMem->flags & MEM_Int );
          423  +    testcase( pMem->flags & MEM_Real );
          424  +    testcase( pMem->flags & MEM_IntReal );
   419    425       return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal);
   420    426     }
   421    427     if( pMem->flags & (MEM_Str|MEM_Blob) ){
          428  +    testcase( pMem->flags & MEM_Str );
          429  +    testcase( pMem->flags & MEM_Blob );
   422    430       return computeNumericType(pMem);
   423    431     }
   424    432     return 0;
   425    433   }
   426    434   
   427    435   #ifdef SQLITE_DEBUG
   428    436   /*
................................................................................
  1798   1806   ** has REAL affinity.  Such column values may still be stored as
  1799   1807   ** integers, for space efficiency, but after extraction we want them
  1800   1808   ** to have only a real value.
  1801   1809   */
  1802   1810   case OP_RealAffinity: {                  /* in1 */
  1803   1811     pIn1 = &aMem[pOp->p1];
  1804   1812     if( pIn1->flags & (MEM_Int|MEM_IntReal) ){
         1813  +    testcase( pIn1->flags & MEM_Int );
         1814  +    testcase( pIn1->flags & MEM_IntReal );
  1805   1815       sqlite3VdbeMemRealify(pIn1);
  1806   1816     }
  1807   1817     break;
  1808   1818   }
  1809   1819   #endif
  1810   1820   
  1811   1821   #ifndef SQLITE_OMIT_CAST
................................................................................
  4378   4388   case OP_SeekRowid: {        /* jump, in3 */
  4379   4389     VdbeCursor *pC;
  4380   4390     BtCursor *pCrsr;
  4381   4391     int res;
  4382   4392     u64 iKey;
  4383   4393   
  4384   4394     pIn3 = &aMem[pOp->p3];
         4395  +  testcase( pIn3->flags & MEM_Int );
         4396  +  testcase( pIn3->flags & MEM_IntReal );
  4385   4397     if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
  4386   4398       /* Make sure pIn3->u.i contains a valid integer representation of
  4387   4399       ** the key value, but do not change the datatype of the register, as
  4388   4400       ** other parts of the perpared statement might be depending on the
  4389   4401       ** current datatype. */
  4390   4402       u16 origFlags = pIn3->flags;
  4391   4403       int isNotInt;

Changes to src/vdbeapi.c.

  1861   1861     pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
  1862   1862     if( iIdx==p->pTab->iPKey ){
  1863   1863       sqlite3VdbeMemSetInt64(pMem, p->iKey1);
  1864   1864     }else if( iIdx>=p->pUnpacked->nField ){
  1865   1865       *ppValue = (sqlite3_value *)columnNullValue();
  1866   1866     }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
  1867   1867       if( pMem->flags & (MEM_Int|MEM_IntReal) ){
         1868  +      testcase( pMem->flags & MEM_Int );
         1869  +      testcase( pMem->flags & MEM_IntReal );
  1868   1870         sqlite3VdbeMemRealify(pMem);
  1869   1871       }
  1870   1872     }
  1871   1873   
  1872   1874    preupdate_old_out:
  1873   1875     sqlite3Error(db, rc);
  1874   1876     return sqlite3ApiExit(db, rc);

Changes to src/vdbeaux.c.

  3433   3433       return 0;
  3434   3434     }
  3435   3435     if( flags&(MEM_Int|MEM_IntReal) ){
  3436   3436       /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
  3437   3437   #   define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
  3438   3438       i64 i = pMem->u.i;
  3439   3439       u64 u;
         3440  +    testcase( flags & MEM_Int );
         3441  +    testcase( flags & MEM_IntReal );
  3440   3442       if( i<0 ){
  3441   3443         u = ~i;
  3442   3444       }else{
  3443   3445         u = i;
  3444   3446       }
  3445   3447       if( u<=127 ){
  3446   3448         if( (i&1)==i && file_format>=4 ){
................................................................................
  4108   4110     if( combined_flags&MEM_Null ){
  4109   4111       return (f2&MEM_Null) - (f1&MEM_Null);
  4110   4112     }
  4111   4113   
  4112   4114     /* At least one of the two values is a number
  4113   4115     */
  4114   4116     if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
         4117  +    testcase( combined_flags & MEM_Int );
         4118  +    testcase( combined_flags & MEM_Real );
         4119  +    testcase( combined_flags & MEM_IntReal );
  4115   4120       if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){
         4121  +      testcase( f1 & f2 & MEM_Int );
         4122  +      testcase( f1 & f2 & MEM_IntReal );
  4116   4123         if( pMem1->u.i < pMem2->u.i ) return -1;
  4117   4124         if( pMem1->u.i > pMem2->u.i ) return +1;
  4118   4125         return 0;
  4119   4126       }
  4120   4127       if( (f1 & f2 & MEM_Real)!=0 ){
  4121   4128         if( pMem1->u.r < pMem2->u.r ) return -1;
  4122   4129         if( pMem1->u.r > pMem2->u.r ) return +1;
  4123   4130         return 0;
  4124   4131       }
  4125   4132       if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
         4133  +      testcase( f1 & MEM_Int );
         4134  +      testcase( f1 & MEM_IntReal );
  4126   4135         if( (f2&MEM_Real)!=0 ){
  4127   4136           return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
  4128   4137         }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
  4129   4138           if( pMem1->u.i < pMem2->u.i ) return -1;
  4130   4139           if( pMem1->u.i > pMem2->u.i ) return +1;
  4131   4140           return 0;
  4132   4141         }else{
  4133   4142           return -1;
  4134   4143         }
  4135   4144       }
  4136   4145       if( (f1&MEM_Real)!=0 ){
  4137   4146         if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
         4147  +        testcase( f2 & MEM_Int );
         4148  +        testcase( f2 & MEM_IntReal );
  4138   4149           return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
  4139   4150         }else{
  4140   4151           return -1;
  4141   4152         }
  4142   4153       }
  4143   4154       return +1;
  4144   4155     }
................................................................................
  4280   4291     assert( pPKey2->pKeyInfo->nKeyField>0 );
  4281   4292     assert( idx1<=szHdr1 || CORRUPT_DB );
  4282   4293     do{
  4283   4294       u32 serial_type;
  4284   4295   
  4285   4296       /* RHS is an integer */
  4286   4297       if( pRhs->flags & (MEM_Int|MEM_IntReal) ){
         4298  +      testcase( pRhs->flags & MEM_Int );
         4299  +      testcase( pRhs->flags & MEM_IntReal );
  4287   4300         serial_type = aKey1[idx1];
  4288   4301         testcase( serial_type==12 );
  4289   4302         if( serial_type>=10 ){
  4290   4303           rc = +1;
  4291   4304         }else if( serial_type==0 ){
  4292   4305           rc = -1;
  4293   4306         }else if( serial_type==7 ){

Changes to src/vdbemem.c.

   560    560   }
   561    561   i64 sqlite3VdbeIntValue(Mem *pMem){
   562    562     int flags;
   563    563     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   564    564     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   565    565     flags = pMem->flags;
   566    566     if( flags & (MEM_Int|MEM_IntReal) ){
          567  +    testcase( flags & MEM_IntReal );
   567    568       return pMem->u.i;
   568    569     }else if( flags & MEM_Real ){
   569    570       return doubleToInt64(pMem->u.r);
   570    571     }else if( flags & (MEM_Str|MEM_Blob) ){
   571    572       assert( pMem->z || pMem->n==0 );
   572    573       return memIntValue(pMem);
   573    574     }else{
................................................................................
   589    590   }
   590    591   double sqlite3VdbeRealValue(Mem *pMem){
   591    592     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   592    593     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   593    594     if( pMem->flags & MEM_Real ){
   594    595       return pMem->u.r;
   595    596     }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
          597  +    testcase( pMem->flags & MEM_IntReal );
   596    598       return (double)pMem->u.i;
   597    599     }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
   598    600       return memRealValue(pMem);
   599    601     }else{
   600    602       /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
   601    603       return (double)0;
   602    604     }
................................................................................
   603    605   }
   604    606   
   605    607   /*
   606    608   ** Return 1 if pMem represents true, and return 0 if pMem represents false.
   607    609   ** Return the value ifNull if pMem is NULL.  
   608    610   */
   609    611   int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
          612  +  testcase( pMem->flags & MEM_IntReal );
   610    613     if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0;
   611    614     if( pMem->flags & MEM_Null ) return ifNull;
   612    615     return sqlite3VdbeRealValue(pMem)!=0.0;
   613    616   }
   614    617   
   615    618   /*
   616    619   ** The MEM structure is already a MEM_Real.  Try to also make it a
................................................................................
   684    687   ** Invalidate any prior representations.
   685    688   **
   686    689   ** Every effort is made to force the conversion, even if the input
   687    690   ** is a string that does not look completely like a number.  Convert
   688    691   ** as much of the string as we can and ignore the rest.
   689    692   */
   690    693   int sqlite3VdbeMemNumerify(Mem *pMem){
          694  +  testcase( pMem->flags & MEM_Int );
          695  +  testcase( pMem->flags & MEM_Real );
          696  +  testcase( pMem->flags & MEM_IntReal );
          697  +  testcase( pMem->flags & MEM_Null );
   691    698     if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
   692    699       int rc;
   693    700       assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
   694    701       assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   695    702       rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
   696    703       if( rc==0 ){
   697    704         MemSetTypeFlag(pMem, MEM_Int);
................................................................................
  1492   1499         sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
  1493   1500       }
  1494   1501       if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){
  1495   1502         sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
  1496   1503       }else{
  1497   1504         sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
  1498   1505       }
  1499         -    if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ) pVal->flags &= ~MEM_Str;
         1506  +    assert( (pVal->flags & MEM_IntReal)==0 );
         1507  +    if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){
         1508  +      testcase( pVal->flags & MEM_Int );
         1509  +      testcase( pVal->flags & MEM_Real );
         1510  +      pVal->flags &= ~MEM_Str;
         1511  +    }
  1500   1512       if( enc!=SQLITE_UTF8 ){
  1501   1513         rc = sqlite3VdbeChangeEncoding(pVal, enc);
  1502   1514       }
  1503   1515     }else if( op==TK_UMINUS ) {
  1504   1516       /* This branch happens for multiple negative signs.  Ex: -(-5) */
  1505   1517       if( SQLITE_OK==valueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal,pCtx) 
  1506   1518        && pVal!=0