SQLite

Check-in [48889530]
Login

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

Overview
Comment:Ensure that the typeof() function always returns SQLITE_FLOAT for floating point values even when the value is stored as an integer to save space.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 48889530a9de22fee536edfd1627be62396ed18d842d5fd6d91e010b4337be95
User & Date: drh 2019-05-02 17:45:52
Context
2019-05-03
02:41
Fix the ".open --hexdb" command in the CLI so that it works even with terminal input. (check-in: 9b5d9434 user: drh tags: trunk)
2019-05-02
21:36
Make MEM_IntReal a completely independent type, meaning a floating point value stored as an integer. This fixes a problem with arithmetic within arguments to string functions on indexes of expressions. But it is a big change and needs lots of new testcase() macros for MC/DC and so it is initially put on this branch. (check-in: dba836e3 user: drh tags: int-real)
17:45
Ensure that the typeof() function always returns SQLITE_FLOAT for floating point values even when the value is stored as an integer to save space. (check-in: 48889530 user: drh tags: trunk)
17:06
Add options to wapptest.tcl similar to those supported by releasetest.tcl. Also add the -noui switch, for running without wapp altogether. (check-in: 005a1694 user: dan tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbeInt.h.

241
242
243
244
245
246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
** flags may coexist with the MEM_Str flag.
*/
#define MEM_Null      0x0001   /* Value is NULL (or a pointer) */
#define MEM_Str       0x0002   /* Value is a string */
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */

#define MEM_AffMask   0x001f   /* Mask of affinity bits */
#define MEM_FromBind  0x0020   /* Value originates from sqlite3_bind() */
#define MEM_IntReal   0x0040   /* MEM_Int that stringifies like MEM_Real */
#define MEM_Undefined 0x0080   /* Value is undefined */
#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
#define MEM_TypeMask  0xc1df   /* Mask of type bits */


/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z.  The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/







>
|
|
<


|







241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
** flags may coexist with the MEM_Str flag.
*/
#define MEM_Null      0x0001   /* Value is NULL (or a pointer) */
#define MEM_Str       0x0002   /* Value is a string */
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */
#define MEM_IntReal   0x0020   /* MEM_Int that stringifies like MEM_Real */
#define MEM_AffMask   0x003f   /* Mask of affinity bits */
#define MEM_FromBind  0x0040   /* Value originates from sqlite3_bind() */

#define MEM_Undefined 0x0080   /* Value is undefined */
#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
#define MEM_TypeMask  0xc1bf   /* Mask of type bits */


/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z.  The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/

Changes to src/vdbeapi.c.

262
263
264
265
266
267
268
































269















270
271
272
273
274
275
276
     SQLITE_NULL,     /* 0x19 */
     SQLITE_FLOAT,    /* 0x1a */
     SQLITE_NULL,     /* 0x1b */
     SQLITE_INTEGER,  /* 0x1c */
     SQLITE_NULL,     /* 0x1d */
     SQLITE_INTEGER,  /* 0x1e */
     SQLITE_NULL,     /* 0x1f */
































  };















  return aType[pVal->flags&MEM_AffMask];
}

/* Return true if a parameter to xUpdate represents an unchanged column */
int sqlite3_value_nochange(sqlite3_value *pVal){
  return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
     SQLITE_NULL,     /* 0x19 */
     SQLITE_FLOAT,    /* 0x1a */
     SQLITE_NULL,     /* 0x1b */
     SQLITE_INTEGER,  /* 0x1c */
     SQLITE_NULL,     /* 0x1d */
     SQLITE_INTEGER,  /* 0x1e */
     SQLITE_NULL,     /* 0x1f */
     SQLITE_BLOB,     /* 0x20 */
     SQLITE_NULL,     /* 0x21 */
     SQLITE_TEXT,     /* 0x22 */
     SQLITE_NULL,     /* 0x23 */
     SQLITE_FLOAT,    /* 0x24 */
     SQLITE_NULL,     /* 0x25 */
     SQLITE_FLOAT,    /* 0x26 */
     SQLITE_NULL,     /* 0x27 */
     SQLITE_FLOAT,    /* 0x28 */
     SQLITE_NULL,     /* 0x29 */
     SQLITE_FLOAT,    /* 0x2a */
     SQLITE_NULL,     /* 0x2b */
     SQLITE_FLOAT,    /* 0x2c */
     SQLITE_NULL,     /* 0x2d */
     SQLITE_FLOAT,    /* 0x2e */
     SQLITE_NULL,     /* 0x2f */
     SQLITE_BLOB,     /* 0x30 */
     SQLITE_NULL,     /* 0x31 */
     SQLITE_TEXT,     /* 0x32 */
     SQLITE_NULL,     /* 0x33 */
     SQLITE_FLOAT,    /* 0x34 */
     SQLITE_NULL,     /* 0x35 */
     SQLITE_FLOAT,    /* 0x36 */
     SQLITE_NULL,     /* 0x37 */
     SQLITE_FLOAT,    /* 0x38 */
     SQLITE_NULL,     /* 0x39 */
     SQLITE_FLOAT,    /* 0x3a */
     SQLITE_NULL,     /* 0x3b */
     SQLITE_FLOAT,    /* 0x3c */
     SQLITE_NULL,     /* 0x3d */
     SQLITE_FLOAT,    /* 0x3e */
     SQLITE_NULL,     /* 0x3f */
  };
#ifdef SQLITE_DEBUG
  {
    int eType = SQLITE_BLOB;
    if( pVal->flags & MEM_Null ){
      eType = SQLITE_NULL;
    }else if( pVal->flags & MEM_Int ){
      eType = (pVal->flags & MEM_IntReal) ? SQLITE_FLOAT : SQLITE_INTEGER;
    }else if( pVal->flags & MEM_Real ){
      eType = SQLITE_FLOAT;
    }else if( pVal->flags & MEM_Str ){
      eType = SQLITE_TEXT;
    }
    assert( eType == aType[pVal->flags&MEM_AffMask] );
  }
#endif
  return aType[pVal->flags&MEM_AffMask];
}

/* Return true if a parameter to xUpdate represents an unchanged column */
int sqlite3_value_nochange(sqlite3_value *pVal){
  return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
}

Changes to test/index.test.

753
754
755
756
757
758
759








760
761
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, b REAL);
  CREATE UNIQUE INDEX t1x1 ON t1(a GLOB b);
  INSERT INTO t1(a,b) VALUES('0.0','1'),('1.0','1');
  SELECT * FROM t1;
  REINDEX;
} {0.0 1.0 1.0 1.0}









finish_test







>
>
>
>
>
>
>
>


753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
  DROP TABLE t1;
  CREATE TABLE t1(a TEXT, b REAL);
  CREATE UNIQUE INDEX t1x1 ON t1(a GLOB b);
  INSERT INTO t1(a,b) VALUES('0.0','1'),('1.0','1');
  SELECT * FROM t1;
  REINDEX;
} {0.0 1.0 1.0 1.0}
do_execsql_test index-23.1 {
  DROP TABLE t1;
  CREATE TABLE t1(a REAL);
  CREATE UNIQUE INDEX index_0 ON t1(TYPEOF(a));
  INSERT OR IGNORE INTO t1(a) VALUES (0.1),(FALSE);
  SELECT * FROM t1;
  REINDEX;
} {0.1}

finish_test